iOS client for Grain grain.social
ios photography atproto
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: drop dangling favorites with no hydrated items

Favorites pointing at since-deleted (or empty) galleries came back with
items: nil/[], causing a black void in the favorites grid where the
thumbnail would be. Filter them out of the cache-load, initial fetch,
and pagination paths via a hydratedFavorites helper.

authored by

Hima Aramona and committed by
Chad Miller
afeeed2a b15aa9e5

+13 -4
+13 -4
Grain/ViewModels/ProfileDetailViewModel.swift
··· 50 50 let isOwnProfile = viewer != nil && viewer == did 51 51 if isOwnProfile, favoriteGalleries.isEmpty { 52 52 let cached = FeedCache.shared.load(key: Self.favoritesCacheKey(did: did)) 53 - if !cached.isEmpty { 54 - favoriteGalleries = cached 53 + let hydrated = Self.hydratedFavorites(cached) 54 + if !hydrated.isEmpty { 55 + favoriteGalleries = hydrated 55 56 } 56 57 } 57 58 ··· 129 130 profileLogger.info("loadFavorites start did=\(did, privacy: .public) hasAuth=\(auth != nil, privacy: .public)") 130 131 do { 131 132 let response = try await client.getActorFavorites(actor: did, auth: auth) 132 - favoriteGalleries = response.items ?? [] 133 + favoriteGalleries = Self.hydratedFavorites(response.items ?? []) 133 134 favoritesCursor = response.cursor 134 135 hasMoreFavorites = response.cursor != nil 135 136 profileLogger.info("loadFavorites ok count=\(favoriteGalleries.count, privacy: .public)") ··· 150 151 "favorites_\(did)" 151 152 } 152 153 154 + /// Drops favorites whose underlying gallery has no photos — either an 155 + /// empty/deleted gallery the server couldn't hydrate, or a dangling 156 + /// favorite pointing at a since-deleted record. Without this, the grid 157 + /// shows a black void where the thumbnail would be. 158 + private static func hydratedFavorites(_ galleries: [GrainGallery]) -> [GrainGallery] { 159 + galleries.filter { !($0.items?.isEmpty ?? true) } 160 + } 161 + 153 162 func loadMoreFavorites(did: String, auth: AuthContext? = nil) async { 154 163 guard !isLoading, hasMoreFavorites, let cursor = favoritesCursor else { return } 155 164 isLoading = true 156 165 do { 157 166 let response = try await client.getActorFavorites(actor: did, cursor: cursor, auth: auth) 158 - favoriteGalleries.append(contentsOf: response.items ?? []) 167 + favoriteGalleries.append(contentsOf: Self.hydratedFavorites(response.items ?? [])) 159 168 favoritesCursor = response.cursor 160 169 hasMoreFavorites = response.cursor != nil 161 170 } catch {}