Refresh expired thumbnail URLs for downloads and video info

Proxied thumbnail URLs from Invidious/Piped/Yattee server expire over
time. Two paths were left holding stale URLs: the Video Info carousel
kept the original list copy even after fresh details arrived, and
downloaded videos rendered from the remote URL snapshot taken at
download time while the local thumbnail on disk was ignored.

Evict stale URLs from the Nuke cache when fresh video details load,
pass the fresh details through to the videoCard thumbnail, and resolve
downloads' thumbnails from the local file when localThumbnailPath is
set.
This commit is contained in:
Arkadiusz Fal
2026-04-17 06:47:14 +02:00
parent abd432fd0e
commit 2efa0708c8
7 changed files with 67 additions and 17 deletions

View File

@@ -32,7 +32,7 @@ struct DownloadRowView: View {
@State private var hasLoadedWatchData = false
private var video: Video {
download.toVideo()
download.toVideo(downloadsDirectory: appEnvironment?.downloadManager.downloadsDirectory())
}
/// Watch progress for this video (0.0 to 1.0), or nil if not watched.

View File

@@ -161,7 +161,7 @@ struct DownloadsStorageView: View {
@ViewBuilder
private func storageRow(_ download: Download, isLast: Bool) -> some View {
let video = download.toVideo()
let video = download.toVideo(downloadsDirectory: downloadManager?.downloadsDirectory())
let isWatched = dataManager?.watchEntry(for: download.videoID.videoID)?.isFinished ?? false
VideoListRow(

View File

@@ -375,7 +375,8 @@ private struct CompletedDownloadsSectionContentView: View {
private func groupedByChannelContent(_ downloads: [Download]) -> some View {
let grouped = settings.groupedByChannel(downloads)
let allDownloadsInOrder = grouped.flatMap { $0.downloads }
let videoList = allDownloadsInOrder.map { $0.toVideo() }
let downloadsDir = manager.downloadsDirectory()
let videoList = allDownloadsInOrder.map { $0.toVideo(downloadsDirectory: downloadsDir) }
var runningIndex = 0
ForEach(Array(grouped.enumerated()), id: \.element.channelID) { groupIndex, group in
@@ -420,7 +421,8 @@ private struct CompletedDownloadsSectionContentView: View {
let sortedDownloads = settings.sorted(downloads)
let groupedByLetter = groupDownloadsByFirstLetter(sortedDownloads, ascending: settings.sortDirection == .ascending)
let allDownloadsInOrder = groupedByLetter.flatMap { $0.downloads }
let videoList = allDownloadsInOrder.map { $0.toVideo() }
let downloadsDir = manager.downloadsDirectory()
let videoList = allDownloadsInOrder.map { $0.toVideo(downloadsDirectory: downloadsDir) }
var runningIndex = 0
ForEach(Array(groupedByLetter.enumerated()), id: \.element.letter) { groupIndex, group in
@@ -463,7 +465,8 @@ private struct CompletedDownloadsSectionContentView: View {
@ViewBuilder
private func flatListContent(_ downloads: [Download]) -> some View {
let sortedDownloads = settings.sorted(downloads)
let videoList = sortedDownloads.map { $0.toVideo() }
let downloadsDir = manager.downloadsDirectory()
let videoList = sortedDownloads.map { $0.toVideo(downloadsDirectory: downloadsDir) }
// Flat list content wrapped in its own card
VideoListContent(listStyle: listStyle) {
@@ -530,7 +533,7 @@ private struct CompletedDownloadsSectionContentView: View {
)
}
.videoSwipeActions(
video: download.toVideo(),
video: download.toVideo(downloadsDirectory: manager.downloadsDirectory()),
fixedActions: [
SwipeAction(
symbolImage: "trash.fill",