package components import ( "tangled.org/oolong.social/oolong/internal/atproto" "tangled.org/oolong.social/oolong/internal/web/bff" "tangled.org/pdewey.com/atp" ) templ AuthorByline(profile *atproto.Profile, fallbackDID string) { if profile != nil { @Avatar(AvatarProps{ AvatarURL: authorAvatar(profile), DisplayName: authorDisplay(profile, fallbackDID), Size: "sm", }) { authorDisplay(profile, fallbackDID) } { "@" + atp.DisplayHandle(authorProfileID(profile, fallbackDID)) } } else if fallbackDID != "" { @Avatar(AvatarProps{DisplayName: fallbackDID, Size: "sm"}) { fallbackDID } } } func authorProfileID(profile *atproto.Profile, fallbackDID string) string { if profile != nil && profile.Handle != "" { return profile.Handle } if profile != nil && profile.DID != "" { return profile.DID } return fallbackDID } func authorDisplay(profile *atproto.Profile, fallbackDID string) string { if profile != nil && profile.DisplayName != nil && *profile.DisplayName != "" { return *profile.DisplayName } if profile != nil && profile.Handle != "" { return atp.DisplayHandle(profile.Handle) } if profile != nil && profile.DID != "" { return profile.DID } return fallbackDID } func authorAvatar(profile *atproto.Profile) string { if profile != nil && profile.Avatar != nil { return *profile.Avatar } return "" } // TypeBadge renders a colored pill with an icon and type label for record type identification. templ TypeBadge(recordType string) { switch recordType { case "oolong-tea", "tea": @IconTea() Tea case "oolong-brew", "brew": @IconTeapot() Brew case "oolong-vendor", "vendor": @IconStore() Vendor case "oolong-infuser", "infuser": @IconGear() Infuser case "oolong-vessel", "vessel": @IconVessel() Vessel } } // RecordViewHeaderProps defines properties for the shared record view header. type RecordViewHeaderProps struct { RecordType string // "brew", "tea", "vendor", "infuser", "vessel", "brew" Title string Timestamp string // formatted date string TimestampISO string // ISO 8601 for