diff --git a/Yattee/Models/Channel.swift b/Yattee/Models/Channel.swift index 0c4cff9d..3f707501 100644 --- a/Yattee/Models/Channel.swift +++ b/Yattee/Models/Channel.swift @@ -94,6 +94,27 @@ struct ChannelID: Codable, Hashable, Sendable { } } +extension Channel { + /// Returns a copy with `thumbnailURL` filled from cached channel data if currently nil. + @MainActor + func enrichedThumbnail(using dataManager: DataManager) -> Channel { + guard thumbnailURL == nil else { return self } + guard let cached = CachedChannelData.load(for: id.channelID, using: dataManager) else { + return self + } + return Channel( + id: id, + name: name, + description: description, + subscriberCount: subscriberCount ?? cached.subscriberCount, + videoCount: videoCount, + thumbnailURL: cached.thumbnailURL, + bannerURL: bannerURL ?? cached.bannerURL, + isVerified: isVerified + ) + } +} + extension ChannelID: Identifiable { var id: String { switch source { diff --git a/Yattee/Views/Instances/InstanceBrowseView.swift b/Yattee/Views/Instances/InstanceBrowseView.swift index d3ef2697..c5e91380 100644 --- a/Yattee/Views/Instances/InstanceBrowseView.swift +++ b/Yattee/Views/Instances/InstanceBrowseView.swift @@ -67,12 +67,24 @@ struct InstanceBrowseView: View { appEnvironment?.settingsManager.listStyle ?? .inset } - /// Auth header for Yattee Server instances + /// The first enabled Yattee Server instance (for avatar URLs). + private var yatteeServer: Instance? { + appEnvironment?.instancesManager.enabledYatteeServerInstances.first + } + private var yatteeServerURL: URL? { yatteeServer?.url } + + /// Auth header for Yattee Server instances (when browsing a Yattee Server directly) private var yatteeServerAuthHeader: String? { guard instance.type == .yatteeServer else { return nil } return appEnvironment?.yatteeServerCredentialsManager.basicAuthHeader(for: instance) } + /// Auth header for avatar loading (uses Yattee Server for YouTube channel avatars) + private var avatarAuthHeader: String? { + guard let server = yatteeServer else { return nil } + return appEnvironment?.yatteeServerCredentialsManager.basicAuthHeader(for: server) + } + enum BrowseTab: String, CaseIterable, Identifiable { case popular case trending @@ -425,7 +437,7 @@ struct InstanceBrowseView: View { channelID: subscription.id.channelID, name: subscription.name, avatarURL: subscription.thumbnailURL, - serverURL: instance.url, + serverURL: yatteeServerURL, isSelected: selectedFeedChannelID == subscription.id.channelID, avatarSize: 44, onTap: { @@ -441,7 +453,7 @@ struct InstanceBrowseView: View { ) }, onUnsubscribe: nil, - authHeader: yatteeServerAuthHeader + authHeader: avatarAuthHeader ) } } @@ -929,7 +941,7 @@ struct InstanceBrowseView: View { return } - feedSubscriptions = subscriptionChannels + feedSubscriptions = subscriptionChannels.map { $0.enrichedThumbnail(using: appEnvironment.dataManager) } feedVideos = videos prefetchBranding(for: videos) case .playlists: