···130130131131// RepoCardData contains all data needed to render a repository card
132132type RepoCardData struct {
133133- OwnerHandle string
134134- Repository string
135135- Title string
136136- Description string
137137- IconURL string
138138- StarCount int
139139- PullCount int
140140- IsStarred bool // Whether the current user has starred this repository
141141- ArtifactType string // container-image, helm-chart, unknown
142142- Tag string // Latest tag name (e.g., "latest", "v1.0.0")
143143- Digest string // Latest manifest digest (sha256:...)
144144- LastUpdated time.Time // When the repository was last pushed to
133133+ OwnerHandle string
134134+ OwnerAvatarURL string // Owner's profile avatar URL (fallback when no repo icon)
135135+ Repository string
136136+ Title string
137137+ Description string
138138+ IconURL string
139139+ StarCount int
140140+ PullCount int
141141+ IsStarred bool // Whether the current user has starred this repository
142142+ ArtifactType string // container-image, helm-chart, unknown
143143+ Tag string // Latest tag name (e.g., "latest", "v1.0.0")
144144+ Digest string // Latest manifest digest (sha256:...)
145145+ LastUpdated time.Time // When the repository was last pushed to
146146+ RegistryURL string // Registry URL for docker commands (e.g., "atcr.io" or "127.0.0.1:5000")
147147+}
148148+149149+// SetRegistryURL sets the RegistryURL field on all cards in the slice
150150+func SetRegistryURL(cards []RepoCardData, registryURL string) {
151151+ for i := range cards {
152152+ cards[i].RegistryURL = registryURL
153153+ }
145154}
146155147156// PlatformInfo represents platform information (OS/Architecture)
+13-2
pkg/appview/db/queries.go
···446446 return err
447447}
448448449449+// UpdateUserAvatar updates a user's avatar URL when a profile change is detected
450450+// This is called when Jetstream receives an app.bsky.actor.profile update
451451+func UpdateUserAvatar(db *sql.DB, did string, avatarURL string) error {
452452+ _, err := db.Exec(`
453453+ UPDATE users SET avatar = ?, last_seen = ? WHERE did = ?
454454+ `, avatarURL, time.Now(), did)
455455+ return err
456456+}
457457+449458// GetManifestDigestsForDID returns all manifest digests for a DID
450459func GetManifestDigestsForDID(db *sql.DB, did string) ([]string, error) {
451460 rows, err := db.Query(`
···17761785 SELECT
17771786 m.did,
17781787 u.handle,
17881788+ COALESCE(u.avatar, ''),
17791789 m.repository,
17801790 COALESCE((SELECT value FROM repository_annotations WHERE did = m.did AND repository = m.repository AND key = 'org.opencontainers.image.title'), ''),
17811791 COALESCE((SELECT value FROM repository_annotations WHERE did = m.did AND repository = m.repository AND key = 'org.opencontainers.image.description'), ''),
···18121822 var avatarCID string
18131823 var lastUpdatedStr sql.NullString
1814182418151815- if err := rows.Scan(&ownerDID, &c.OwnerHandle, &c.Repository, &c.Title, &c.Description, &c.IconURL,
18251825+ if err := rows.Scan(&ownerDID, &c.OwnerHandle, &c.OwnerAvatarURL, &c.Repository, &c.Title, &c.Description, &c.IconURL,
18161826 &c.StarCount, &c.PullCount, &isStarredInt, &c.ArtifactType, &c.Tag, &c.Digest, &lastUpdatedStr, &avatarCID); err != nil {
18171827 return nil, err
18181828 }
···18581868 SELECT
18591869 m.did,
18601870 u.handle,
18711871+ COALESCE(u.avatar, ''),
18611872 m.repository,
18621873 COALESCE((SELECT value FROM repository_annotations WHERE did = m.did AND repository = m.repository AND key = 'org.opencontainers.image.title'), ''),
18631874 COALESCE((SELECT value FROM repository_annotations WHERE did = m.did AND repository = m.repository AND key = 'org.opencontainers.image.description'), ''),
···18931904 var avatarCID string
18941905 var lastUpdatedStr sql.NullString
1895190618961896- if err := rows.Scan(&ownerDID, &c.OwnerHandle, &c.Repository, &c.Title, &c.Description, &c.IconURL,
19071907+ if err := rows.Scan(&ownerDID, &c.OwnerHandle, &c.OwnerAvatarURL, &c.Repository, &c.Title, &c.Description, &c.IconURL,
18971908 &c.StarCount, &c.PullCount, &isStarredInt, &c.ArtifactType, &c.Tag, &c.Digest, &lastUpdatedStr, &avatarCID); err != nil {
18981909 return nil, err
18991910 }