mirror of
				https://github.com/yattee/yattee.git
				synced 2025-10-31 20:52:04 +00:00 
			
		
		
		
	Merge pull request #740 from stonerl/thumbnails
Improved thumbnail handling
This commit is contained in:
		| @@ -20,21 +20,23 @@ final class ThumbnailsModel: ObservableObject { | ||||
|         return unloadable.contains(url) | ||||
|     } | ||||
|  | ||||
|     func best(_ video: Video) -> URL? { | ||||
|     func best(_ video: Video) -> (url: URL?, quality: Thumbnail.Quality?) { | ||||
|         for quality in availableQualitites { | ||||
|             let url = video.thumbnailURL(quality: quality) | ||||
|             if !isUnloadable(url) { | ||||
|                 return url | ||||
|                 return (url, quality) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return nil | ||||
|         return (nil, nil) | ||||
|     } | ||||
|  | ||||
|     private var availableQualitites: [Thumbnail.Quality] { | ||||
|         switch Defaults[.thumbnailsQuality] { | ||||
|         case .highest: | ||||
|             return [.maxresdefault, .medium, .default] | ||||
|             return [.maxres, .high, .medium, .default] | ||||
|         case .high: | ||||
|             return [.high, .medium, .default] | ||||
|         case .medium: | ||||
|             return [.medium, .default] | ||||
|         case .low: | ||||
|   | ||||
| @@ -4,6 +4,8 @@ import SwiftUI | ||||
|  | ||||
| enum Constants { | ||||
|     static let overlayAnimation = Animation.linear(duration: 0.2) | ||||
|     static let aspectRatio16x9 = 16.0 / 9.0 | ||||
|     static let aspectRatio4x3 = 4.0 / 3.0 | ||||
|  | ||||
|     static var isAppleTV: Bool { | ||||
|         #if os(iOS) | ||||
|   | ||||
| @@ -462,12 +462,14 @@ enum ButtonLabelStyle: String, CaseIterable, Defaults.Serializable { | ||||
| } | ||||
|  | ||||
| enum ThumbnailsQuality: String, CaseIterable, Defaults.Serializable { | ||||
|     case highest, medium, low | ||||
|     case highest, high, medium, low | ||||
|  | ||||
|     var description: String { | ||||
|         switch self { | ||||
|         case .highest: | ||||
|             return "Highest quality".localized() | ||||
|             return "Best quality".localized() | ||||
|         case .high: | ||||
|             return "High quality".localized() | ||||
|         case .medium: | ||||
|             return "Medium quality".localized() | ||||
|         case .low: | ||||
|   | ||||
| @@ -265,7 +265,7 @@ struct PlayerControls: View { | ||||
|  | ||||
|     var controlsBackgroundURL: URL? { | ||||
|         if let video = player.videoForDisplay, | ||||
|            let url = thumbnails.best(video) | ||||
|            let url = thumbnails.best(video).url | ||||
|         { | ||||
|             return url | ||||
|         } | ||||
|   | ||||
| @@ -65,7 +65,7 @@ import SwiftUI | ||||
|         } | ||||
|  | ||||
|         static var thumbnailHeight: Double { | ||||
|             thumbnailWidth / (16 / 9) | ||||
|             thumbnailWidth / Constants.aspectRatio16x9 | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -119,7 +119,7 @@ import SwiftUI | ||||
|         } | ||||
|  | ||||
|         static var thumbnailHeight: Double { | ||||
|             thumbnailWidth / 1.7777 | ||||
|             thumbnailWidth / Constants.aspectRatio16x9 | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
|   | ||||
| @@ -19,7 +19,7 @@ struct VideoPlayerView: View { | ||||
|         static let hiddenOffset = 0.0 | ||||
|     #endif | ||||
|  | ||||
|     static let defaultAspectRatio = 16 / 9.0 | ||||
|     static let defaultAspectRatio = Constants.aspectRatio16x9 | ||||
|     static var defaultMinimumHeightLeft: Double { | ||||
|         #if os(macOS) | ||||
|             335 | ||||
|   | ||||
| @@ -219,22 +219,18 @@ struct VideoBanner: View { | ||||
|         return watch!.finished ? 0.5 : 1 | ||||
|     } | ||||
|  | ||||
|     private var thumbnailWidth: Double { | ||||
|         #if os(tvOS) | ||||
|             356 | ||||
|         #else | ||||
|             120 | ||||
|         #endif | ||||
|     } | ||||
|  | ||||
|     private var thumbnailHeight: Double { | ||||
|         #if os(tvOS) | ||||
|             200 | ||||
|         #else | ||||
|             72 | ||||
|             75 | ||||
|         #endif | ||||
|     } | ||||
|  | ||||
|     private var thumbnailWidth: Double { | ||||
|         thumbnailHeight * Constants.aspectRatio16x9 | ||||
|     } | ||||
|  | ||||
|     private var videoDurationLabel: String? { | ||||
|         guard videoDuration != 0 else { return nil } | ||||
|         return (videoDuration ?? video?.length)?.formattedAsPlaybackTime() | ||||
|   | ||||
| @@ -440,7 +440,7 @@ struct VideoCell: View { | ||||
|             #endif | ||||
|         } | ||||
|         .mask(RoundedRectangle(cornerRadius: thumbnailRoundingCornerRadius)) | ||||
|         .modifier(AspectRatioModifier()) | ||||
|         .aspectRatio(Constants.aspectRatio16x9, contentMode: .fill) | ||||
|     } | ||||
|  | ||||
|     private var time: String? { | ||||
| @@ -471,24 +471,6 @@ struct VideoCell: View { | ||||
|             .lineLimit(lineLimit) | ||||
|             .truncationMode(.middle) | ||||
|     } | ||||
|  | ||||
|     struct AspectRatioModifier: ViewModifier { | ||||
|         @Environment(\.horizontalCells) private var horizontalCells | ||||
|  | ||||
|         func body(content: Content) -> some View { | ||||
|             Group { | ||||
|                 if horizontalCells { | ||||
|                     content | ||||
|                 } else { | ||||
|                     content | ||||
|                         .aspectRatio( | ||||
|                             VideoPlayerView.defaultAspectRatio, | ||||
|                             contentMode: .fill | ||||
|                         ) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| struct VideoCellThumbnail: View { | ||||
| @@ -496,7 +478,15 @@ struct VideoCellThumbnail: View { | ||||
|     @ObservedObject private var thumbnails = ThumbnailsModel.shared | ||||
|  | ||||
|     var body: some View { | ||||
|         ThumbnailView(url: thumbnails.best(video)) | ||||
|         GeometryReader { geometry in | ||||
|             let (url, quality) = thumbnails.best(video) | ||||
|             let aspectRatio = (quality == .default || quality == .high) ? Constants.aspectRatio4x3 : Constants.aspectRatio16x9 | ||||
|  | ||||
|             ThumbnailView(url: url) | ||||
|                 .aspectRatio(aspectRatio, contentMode: .fill) | ||||
|                 .frame(width: geometry.size.width, height: geometry.size.height) | ||||
|                 .clipped() | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Arkadiusz Fal
					Arkadiusz Fal