Persist author cache to disk for instant channel info across restarts

Back the in-memory authorCache with a JSON file in ~/Library/Caches/AuthorCache/.
Disk is lazy-loaded on first lookup and saved asynchronously on each cache update.
Capped at 500 entries to prevent unbounded growth.

- Cache author data from video detail API responses (PlayerService, VideoInfoView)
- Replace ChannelView's private CachedChannelHeader with shared CachedChannelData
- Enrich author with cached avatar/subscriber count in VideoChannelRow, TVDetailsPanel, VideoInfoView
This commit is contained in:
Arkadiusz Fal
2026-02-12 05:47:43 +01:00
parent d1d7edb5ec
commit fd41833532
6 changed files with 185 additions and 37 deletions

View File

@@ -92,6 +92,8 @@ struct VideoStatsRow: View {
/// Displays channel info with avatar, name, subscriber count, and context menu.
struct VideoChannelRow: View {
@Environment(\.appEnvironment) private var appEnvironment
let author: Author
let source: ContentSource
let yatteeServerURL: URL?
@@ -101,6 +103,12 @@ struct VideoChannelRow: View {
var showSubscriberCount: Bool = true
var isLoadingDetails: Bool = false
/// Author enriched with cached channel data (avatar, subscriber count) from local stores.
private var enrichedAuthor: Author {
guard let dataManager = appEnvironment?.dataManager else { return author }
return author.enriched(using: dataManager)
}
var body: some View {
HStack(spacing: 12) {
if let onChannelTap {
@@ -129,21 +137,21 @@ struct VideoChannelRow: View {
private var channelContent: some View {
HStack(spacing: 10) {
ChannelAvatarView(
author: author,
author: enrichedAuthor,
size: 40,
yatteeServerURL: yatteeServerURL,
source: source
)
VStack(alignment: .leading, spacing: 2) {
Text(author.name)
Text(enrichedAuthor.name)
.font(.subheadline)
.fontWeight(.medium)
.lineLimit(1)
if showSubscriberCount {
Group {
if let subscribers = author.formattedSubscriberCount {
if let subscribers = enrichedAuthor.formattedSubscriberCount {
Text(subscribers)
} else if isLoadingDetails && video.supportsAPIStats {
Text("1.2M subscribers")