mirror of
https://github.com/yattee/yattee.git
synced 2026-08-05 23:01:28 +00:00
Apply thumbnail fallback everywhere a single URL was rendered
The previous fix rebuilt the quality chain when converting persisted models back to videos, but many consumers discarded it again by rendering bestThumbnail (usually a maxresdefault.jpg that 404s for older videos) as a single URL with no fallback. Extract the retry logic from VideoThumbnailView into FallbackLazyImage and use it at every in-app site that can iterate: player thumbnails (mini bar, expanded sheet loaders, autoplay previews, tvOS audio-mode artwork - previously a silent black screen), video info card and tvOS header, and the tvOS playlist cover. Sites that fetch or send exactly one URL are rewritten to the always-available hqdefault variant via Thumbnail.reliableURL (exposed as Video.reliableThumbnailURL): Now Playing artwork, Top Shelf snapshots, remote control state, the frozen transition thumbnail, blurred info background, navigation covers, and playlist covers derived from a video's first thumbnail in Invidious/Yattee Server responses. Also invert RecentPlaylist's upgrade helper, which rewrote covers *to* maxresdefault, walk the quality chain when caching download thumbnails for offline artwork instead of giving up after one 404, and expand the remaining single-thumbnail Piped conversions into full chains.
This commit is contained in:
@@ -652,9 +652,9 @@ struct VideoInfoView: View {
|
||||
@ViewBuilder
|
||||
private func tvOSThumbnail(for video: Video) -> some View {
|
||||
let deArrowURL = appEnvironment?.deArrowBrandingProvider.thumbnailURL(for: video)
|
||||
let thumbnailURL = deArrowURL ?? video.bestThumbnail?.url
|
||||
let thumbnailURLs = [deArrowURL].compactMap { $0 } + video.thumbnailURLsByQuality
|
||||
|
||||
LazyImage(url: thumbnailURL) { state in
|
||||
FallbackLazyImage(urls: thumbnailURLs) { state in
|
||||
if let image = state.image {
|
||||
image
|
||||
.resizable()
|
||||
@@ -816,7 +816,7 @@ struct VideoInfoView: View {
|
||||
@ViewBuilder
|
||||
private var blurredThumbnailBackground: some View {
|
||||
BlurredImageBackground(
|
||||
url: displayedVideo.flatMap { appEnvironment?.deArrowBrandingProvider.thumbnailURL(for: $0) } ?? displayedVideo?.bestThumbnail?.url,
|
||||
url: displayedVideo.flatMap { appEnvironment?.deArrowBrandingProvider.thumbnailURL(for: $0) } ?? displayedVideo?.reliableThumbnailURL,
|
||||
videoID: displayedVideo?.id.videoID,
|
||||
blurRadius: BlurredImageBackground.platformBlurRadius,
|
||||
scale: 1.8,
|
||||
@@ -949,12 +949,11 @@ struct VideoInfoView: View {
|
||||
private func videoCard(for video: Video, thumbnailFrom: Video? = nil, authorFrom: Video? = nil, isLoadingMore: Bool, showTitle: Bool, isCurrent: Bool) -> some View {
|
||||
let thumbnailSource = thumbnailFrom ?? video
|
||||
let deArrowURL = appEnvironment?.deArrowBrandingProvider.thumbnailURL(for: thumbnailSource)
|
||||
let bestThumb = thumbnailSource.bestThumbnail
|
||||
let thumbnailURL = deArrowURL ?? bestThumb?.url
|
||||
let thumbnailURLs = [deArrowURL].compactMap { $0 } + thumbnailSource.thumbnailURLsByQuality
|
||||
return VStack(spacing: 12) {
|
||||
// Thumbnail with loading overlay
|
||||
ZStack {
|
||||
LazyImage(url: thumbnailURL) { state in
|
||||
FallbackLazyImage(urls: thumbnailURLs) { state in
|
||||
if let image = state.image {
|
||||
image
|
||||
.resizable()
|
||||
|
||||
Reference in New Issue
Block a user