mirror of
				https://github.com/yattee/yattee.git
				synced 2025-10-31 12:41:57 +00:00 
			
		
		
		
	Add channels thumbnails to cells and list
This commit is contained in:
		
							
								
								
									
										76
									
								
								Shared/Channels/ChannelLinkView.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								Shared/Channels/ChannelLinkView.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | import Foundation | ||||||
|  | import SwiftUI | ||||||
|  |  | ||||||
|  | struct ChannelLinkView<ChannelLabel: View>: View { | ||||||
|  |     let channel: Channel | ||||||
|  |     let channelLabel: ChannelLabel | ||||||
|  |  | ||||||
|  |     @Environment(\.inChannelView) private var inChannelView | ||||||
|  |     @Environment(\.navigationStyle) private var navigationStyle | ||||||
|  |  | ||||||
|  |     init( | ||||||
|  |         channel: Channel, | ||||||
|  |         @ViewBuilder channelLabel: () -> ChannelLabel | ||||||
|  |     ) { | ||||||
|  |         self.channel = channel | ||||||
|  |         self.channelLabel = channelLabel() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     var body: some View { | ||||||
|  |         channelControl | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @ViewBuilder private var channelControl: some View { | ||||||
|  |         if !channel.name.isEmpty { | ||||||
|  |             #if os(tvOS) | ||||||
|  |                 channelLabel | ||||||
|  |             #else | ||||||
|  |                 if navigationStyle == .tab { | ||||||
|  |                     channelNavigationLink | ||||||
|  |                 } else { | ||||||
|  |                     channelButton | ||||||
|  |                     #if os(macOS) | ||||||
|  |                     .onHover(perform: onHover(_:)) | ||||||
|  |                     #endif | ||||||
|  |                 } | ||||||
|  |             #endif | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @ViewBuilder private var channelNavigationLink: some View { | ||||||
|  |         NavigationLink(destination: ChannelVideosView(channel: channel)) { | ||||||
|  |             channelLabel | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @ViewBuilder private var channelButton: some View { | ||||||
|  |         Button { | ||||||
|  |             guard !inChannelView else { | ||||||
|  |                 return | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             NavigationModel.shared.openChannel( | ||||||
|  |                 channel, | ||||||
|  |                 navigationStyle: navigationStyle | ||||||
|  |             ) | ||||||
|  |         } label: { | ||||||
|  |             channelLabel | ||||||
|  |         } | ||||||
|  |         #if os(tvOS) | ||||||
|  |         .buttonStyle(.card) | ||||||
|  |         #else | ||||||
|  |         .buttonStyle(.plain) | ||||||
|  |         #endif | ||||||
|  |         .help("\(channel.name) Channel") | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #if os(macOS) | ||||||
|  |         private func onHover(_ inside: Bool) { | ||||||
|  |             if inside { | ||||||
|  |                 NSCursor.pointingHand.push() | ||||||
|  |             } else { | ||||||
|  |                 NSCursor.pop() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     #endif | ||||||
|  | } | ||||||
| @@ -11,4 +11,20 @@ struct Constants { | |||||||
|             0.6 |             0.6 | ||||||
|         #endif |         #endif | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     static var channelThumbnailSize: Double { | ||||||
|  |         #if os(tvOS) | ||||||
|  |             50 | ||||||
|  |         #else | ||||||
|  |             30 | ||||||
|  |         #endif | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static var channelDetailsStackSpacing: Double { | ||||||
|  |         #if os(tvOS) | ||||||
|  |             12 | ||||||
|  |         #else | ||||||
|  |             6 | ||||||
|  |         #endif | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -44,7 +44,7 @@ extension Defaults.Keys { | |||||||
|     #if os(iOS) |     #if os(iOS) | ||||||
|         static let lockPortraitWhenBrowsing = Key<Bool>("lockPortraitWhenBrowsing", default: UIDevice.current.userInterfaceIdiom == .phone) |         static let lockPortraitWhenBrowsing = Key<Bool>("lockPortraitWhenBrowsing", default: UIDevice.current.userInterfaceIdiom == .phone) | ||||||
|     #endif |     #endif | ||||||
|     static let channelOnThumbnail = Key<Bool>("channelOnThumbnail", default: true) |     static let channelOnThumbnail = Key<Bool>("channelOnThumbnail", default: false) | ||||||
|     static let timeOnThumbnail = Key<Bool>("timeOnThumbnail", default: true) |     static let timeOnThumbnail = Key<Bool>("timeOnThumbnail", default: true) | ||||||
|     static let roundedThumbnails = Key<Bool>("roundedThumbnails", default: true) |     static let roundedThumbnails = Key<Bool>("roundedThumbnails", default: true) | ||||||
|     static let thumbnailsQuality = Key<ThumbnailsQuality>("thumbnailsQuality", default: .highest) |     static let thumbnailsQuality = Key<ThumbnailsQuality>("thumbnailsQuality", default: .highest) | ||||||
|   | |||||||
| @@ -114,11 +114,11 @@ struct PlayerControls: View { | |||||||
|                                         Text(player.currentVideo?.displayAuthor ?? "") |                                         Text(player.currentVideo?.displayAuthor ?? "") | ||||||
|                                             .fontWeight(.semibold) |                                             .fontWeight(.semibold) | ||||||
|                                             .shadow(radius: 10) |                                             .shadow(radius: 10) | ||||||
|                                             .foregroundColor(.secondary) |                                             .foregroundColor(.init(white: 0.8)) | ||||||
|                                             .font(.system(size: playerControlsLayout.authorLineFontSize)) |                                             .font(.system(size: playerControlsLayout.authorLineFontSize)) | ||||||
|                                             .lineLimit(1) |                                             .lineLimit(1) | ||||||
|                                     } |                                     } | ||||||
|  |                                     .foregroundColor(.white) | ||||||
|                                     .frame(maxWidth: .infinity, alignment: .leading) |                                     .frame(maxWidth: .infinity, alignment: .leading) | ||||||
|                                     .offset(y: -40) |                                     .offset(y: -40) | ||||||
|                                 } |                                 } | ||||||
|   | |||||||
| @@ -74,21 +74,22 @@ struct VideoBanner: View { | |||||||
|  |  | ||||||
|                 HStack { |                 HStack { | ||||||
|                     HStack { |                     HStack { | ||||||
|                         if !inChannelView, |  | ||||||
|                            let video, |  | ||||||
|                            let url = video.channel.thumbnailURLOrCached |  | ||||||
|                         { |  | ||||||
|                             ThumbnailView(url: url) |  | ||||||
|                                 .frame(width: 30, height: 30) |  | ||||||
|                                 .clipShape(Circle()) |  | ||||||
|                         } |  | ||||||
|  |  | ||||||
|                         VStack(alignment: .leading) { |                         VStack(alignment: .leading) { | ||||||
|                             Group { |                             Group { | ||||||
|                                 if let video { |                                 if let video { | ||||||
|                                     if !inChannelView, !video.isLocal || video.localStreamIsRemoteURL { |                                     if !inChannelView, !video.isLocal || video.localStreamIsRemoteURL { | ||||||
|                                         channelControl |                                         ChannelLinkView(channel: video.channel) { | ||||||
|                                             .font(.subheadline) |                                             HStack(spacing: Constants.channelDetailsStackSpacing) { | ||||||
|  |                                                 if let url = video.channel.thumbnailURLOrCached { | ||||||
|  |                                                     ThumbnailView(url: url) | ||||||
|  |                                                         .frame(width: Constants.channelThumbnailSize, height: Constants.channelThumbnailSize) | ||||||
|  |                                                         .clipShape(Circle()) | ||||||
|  |                                                 } | ||||||
|  |  | ||||||
|  |                                                 channelLabel | ||||||
|  |                                                     .font(.subheadline) | ||||||
|  |                                             } | ||||||
|  |                                         } | ||||||
|                                     } else { |                                     } else { | ||||||
|                                         #if os(iOS) |                                         #if os(iOS) | ||||||
|                                             if DocumentsModel.shared.isDocument(video) { |                                             if DocumentsModel.shared.isDocument(video) { | ||||||
| @@ -220,7 +221,7 @@ struct VideoBanner: View { | |||||||
|  |  | ||||||
|     private var thumbnailWidth: Double { |     private var thumbnailWidth: Double { | ||||||
|         #if os(tvOS) |         #if os(tvOS) | ||||||
|             250 |             356 | ||||||
|         #else |         #else | ||||||
|             120 |             120 | ||||||
|         #endif |         #endif | ||||||
| @@ -228,7 +229,7 @@ struct VideoBanner: View { | |||||||
|  |  | ||||||
|     private var thumbnailHeight: Double { |     private var thumbnailHeight: Double { | ||||||
|         #if os(tvOS) |         #if os(tvOS) | ||||||
|             140 |             200 | ||||||
|         #else |         #else | ||||||
|             72 |             72 | ||||||
|         #endif |         #endif | ||||||
| @@ -308,50 +309,7 @@ struct VideoBanner: View { | |||||||
|         (progressViewValue / progressViewTotal) * 100 > Double(Defaults[.watchedThreshold]) |         (progressViewValue / progressViewTotal) * 100 > Double(Defaults[.watchedThreshold]) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @ViewBuilder private var channelControl: some View { |     @ViewBuilder private var channelLabel: some View { | ||||||
|         if let video, !video.displayAuthor.isEmpty { |  | ||||||
|             #if os(tvOS) |  | ||||||
|                 displayAuthor |  | ||||||
|             #else |  | ||||||
|                 if navigationStyle == .tab, inNavigationView { |  | ||||||
|                     channelNavigationLink |  | ||||||
|                 } else { |  | ||||||
|                     channelButton |  | ||||||
|                 } |  | ||||||
|             #endif |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @ViewBuilder private var channelNavigationLink: some View { |  | ||||||
|         if let channel = video?.channel { |  | ||||||
|             NavigationLink(destination: ChannelVideosView(channel: channel)) { |  | ||||||
|                 displayAuthor |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @ViewBuilder private var channelButton: some View { |  | ||||||
|         if let video { |  | ||||||
|             Button { |  | ||||||
|                 guard !inChannelView else { return } |  | ||||||
|  |  | ||||||
|                 NavigationModel.shared.openChannel( |  | ||||||
|                     video.channel, |  | ||||||
|                     navigationStyle: navigationStyle |  | ||||||
|                 ) |  | ||||||
|             } label: { |  | ||||||
|                 displayAuthor |  | ||||||
|             } |  | ||||||
|             #if os(tvOS) |  | ||||||
|             .buttonStyle(.card) |  | ||||||
|             #else |  | ||||||
|             .buttonStyle(.plain) |  | ||||||
|             #endif |  | ||||||
|             .help("\(video.channel.name) Channel") |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @ViewBuilder private var displayAuthor: some View { |  | ||||||
|         if let video, !video.displayAuthor.isEmpty { |         if let video, !video.displayAuthor.isEmpty { | ||||||
|             Text(video.displayAuthor) |             Text(video.displayAuthor) | ||||||
|                 .fontWeight(.semibold) |                 .fontWeight(.semibold) | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ struct VideoCell: View { | |||||||
|         Button(action: playAction) { |         Button(action: playAction) { | ||||||
|             content |             content | ||||||
|             #if os(tvOS) |             #if os(tvOS) | ||||||
|             .frame(width: 580, height: 470) |             .frame(width: 580, height: channelOnThumbnail ? 470 : 500) | ||||||
|             #endif |             #endif | ||||||
|         } |         } | ||||||
|         .opacity(contentOpacity) |         .opacity(contentOpacity) | ||||||
| @@ -166,17 +166,22 @@ struct VideoCell: View { | |||||||
|                     videoDetail(video.displayTitle, lineLimit: 5) |                     videoDetail(video.displayTitle, lineLimit: 5) | ||||||
|                         .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) |                         .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) | ||||||
|  |  | ||||||
|                     HStack(spacing: 12) { |                     HStack(spacing: Constants.channelDetailsStackSpacing) { | ||||||
|                         if !inChannelView, |                         if !inChannelView, | ||||||
|                            let video, |                            let video, | ||||||
|                            let url = video.channel.thumbnailURLOrCached |                            let url = video.channel.thumbnailURLOrCached | ||||||
|                         { |                         { | ||||||
|                             ThumbnailView(url: url) |                             ChannelLinkView(channel: video.channel) { | ||||||
|                                 .frame(width: 30, height: 30) |                                 ThumbnailView(url: url) | ||||||
|                                 .clipShape(Circle()) |                                     .frame(width: Constants.channelThumbnailSize, height: Constants.channelThumbnailSize) | ||||||
|  |                                     .clipShape(Circle()) | ||||||
|  |                             } | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                         if !channelOnThumbnail, !inChannelView { |                         if !channelOnThumbnail, !inChannelView { | ||||||
|                             channelControl(badge: false) |                             ChannelLinkView(channel: video.channel) { | ||||||
|  |                                 channelLabel(badge: false) | ||||||
|  |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
| @@ -259,14 +264,22 @@ struct VideoCell: View { | |||||||
|                         #if os(tvOS) |                         #if os(tvOS) | ||||||
|                             .frame(minHeight: 60, alignment: .top) |                             .frame(minHeight: 60, alignment: .top) | ||||||
|                         #elseif os(macOS) |                         #elseif os(macOS) | ||||||
|                             .frame(minHeight: 32, alignment: .top) |                             .frame(minHeight: 35, alignment: .top) | ||||||
|                         #else |                         #else | ||||||
|                             .frame(minHeight: 40, alignment: .top) |                             .frame(minHeight: 43, alignment: .top) | ||||||
|                         #endif |                         #endif | ||||||
|                         if !channelOnThumbnail, !inChannelView { |                         if !channelOnThumbnail, !inChannelView { | ||||||
|                             channelControl(badge: false) |                             ChannelLinkView(channel: video.channel) { | ||||||
|                                 .padding(.top, 4) |                                 HStack(spacing: Constants.channelDetailsStackSpacing) { | ||||||
|                                 .padding(.bottom, 6) |                                     if let url = video.channel.thumbnailURLOrCached { | ||||||
|  |                                         ThumbnailView(url: url) | ||||||
|  |                                             .frame(width: Constants.channelThumbnailSize, height: Constants.channelThumbnailSize) | ||||||
|  |                                             .clipShape(Circle()) | ||||||
|  |                                     } | ||||||
|  |  | ||||||
|  |                                     channelLabel(badge: false) | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) |                     .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) | ||||||
| @@ -274,20 +287,23 @@ struct VideoCell: View { | |||||||
|                 #if os(tvOS) |                 #if os(tvOS) | ||||||
|                 .frame(minHeight: channelOnThumbnail ? 80 : 120, alignment: .top) |                 .frame(minHeight: channelOnThumbnail ? 80 : 120, alignment: .top) | ||||||
|                 #elseif os(macOS) |                 #elseif os(macOS) | ||||||
|                 .frame(minHeight: 35, alignment: .top) |                 .frame(minHeight: channelOnThumbnail ? 52 : 75, alignment: .top) | ||||||
|                 #else |                 #else | ||||||
|                 .frame(minHeight: 50, alignment: .top) |                 .frame(minHeight: channelOnThumbnail ? 50 : 70, alignment: .top) | ||||||
|                 #endif |                 #endif | ||||||
|                 .padding(.bottom, 4) |                 .padding(.bottom, 4) | ||||||
|  |  | ||||||
|                 HStack(spacing: 8) { |                 HStack(spacing: 8) { | ||||||
|                     if !inChannelView, |                     if channelOnThumbnail, | ||||||
|  |                        !inChannelView, | ||||||
|                        let video, |                        let video, | ||||||
|                        let url = video.channel.thumbnailURLOrCached |                        let url = video.channel.thumbnailURLOrCached | ||||||
|                     { |                     { | ||||||
|                         ThumbnailView(url: url) |                         ChannelLinkView(channel: video.channel) { | ||||||
|                             .frame(width: 30, height: 30) |                             ThumbnailView(url: url) | ||||||
|                             .clipShape(Circle()) |                                 .frame(width: Constants.channelThumbnailSize, height: Constants.channelThumbnailSize) | ||||||
|  |                                 .clipShape(Circle()) | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     if let date = video.publishedDate { |                     if let date = video.publishedDate { | ||||||
| @@ -314,7 +330,7 @@ struct VideoCell: View { | |||||||
|                 } |                 } | ||||||
|                 .lineLimit(1) |                 .lineLimit(1) | ||||||
|                 .foregroundColor(.secondary) |                 .foregroundColor(.secondary) | ||||||
|                 .frame(maxWidth: .infinity, minHeight: 30, alignment: .topLeading) |                 .frame(maxWidth: .infinity, minHeight: 35, alignment: .topLeading) | ||||||
|                 #if os(tvOS) |                 #if os(tvOS) | ||||||
|                     .padding(.bottom, 10) |                     .padding(.bottom, 10) | ||||||
|                 #endif |                 #endif | ||||||
| @@ -327,47 +343,6 @@ struct VideoCell: View { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @ViewBuilder private func channelControl(badge: Bool = true) -> some View { |  | ||||||
|         if !video.channel.name.isEmpty { |  | ||||||
|             #if os(tvOS) |  | ||||||
|                 channelButton(badge: badge) |  | ||||||
|             #else |  | ||||||
|                 if navigationStyle == .tab { |  | ||||||
|                     channelNavigationLink(badge: badge) |  | ||||||
|                 } else { |  | ||||||
|                     channelButton(badge: badge) |  | ||||||
|                 } |  | ||||||
|             #endif |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @ViewBuilder private func channelNavigationLink(badge: Bool = true) -> some View { |  | ||||||
|         NavigationLink(destination: ChannelVideosView(channel: video.channel)) { |  | ||||||
|             channelLabel(badge: badge) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @ViewBuilder private func channelButton(badge: Bool = true) -> some View { |  | ||||||
|         Button { |  | ||||||
|             guard !inChannelView else { |  | ||||||
|                 return |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             NavigationModel.shared.openChannel( |  | ||||||
|                 video.channel, |  | ||||||
|                 navigationStyle: navigationStyle |  | ||||||
|             ) |  | ||||||
|         } label: { |  | ||||||
|             channelLabel(badge: badge) |  | ||||||
|         } |  | ||||||
|         #if os(tvOS) |  | ||||||
|         .buttonStyle(.card) |  | ||||||
|         #else |  | ||||||
|         .buttonStyle(.plain) |  | ||||||
|         #endif |  | ||||||
|         .help("\(video.channel.name) Channel") |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @ViewBuilder private func channelLabel(badge: Bool = true) -> some View { |     @ViewBuilder private func channelLabel(badge: Bool = true) -> some View { | ||||||
|         if badge { |         if badge { | ||||||
|             DetailBadge(text: video.author, style: .prominent) |             DetailBadge(text: video.author, style: .prominent) | ||||||
| @@ -415,7 +390,9 @@ struct VideoCell: View { | |||||||
|                     Spacer() |                     Spacer() | ||||||
|  |  | ||||||
|                     if channelOnThumbnail, !inChannelView { |                     if channelOnThumbnail, !inChannelView { | ||||||
|                         channelControl() |                         ChannelLinkView(channel: video.channel) { | ||||||
|  |                             channelLabel() | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 #if os(tvOS) |                 #if os(tvOS) | ||||||
|   | |||||||
| @@ -171,6 +171,9 @@ | |||||||
| 		37169AA62729E2CC0011DE61 /* AccountsBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37169AA52729E2CC0011DE61 /* AccountsBridge.swift */; }; | 		37169AA62729E2CC0011DE61 /* AccountsBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37169AA52729E2CC0011DE61 /* AccountsBridge.swift */; }; | ||||||
| 		37169AA72729E2CC0011DE61 /* AccountsBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37169AA52729E2CC0011DE61 /* AccountsBridge.swift */; }; | 		37169AA72729E2CC0011DE61 /* AccountsBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37169AA52729E2CC0011DE61 /* AccountsBridge.swift */; }; | ||||||
| 		37169AA82729E2CC0011DE61 /* AccountsBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37169AA52729E2CC0011DE61 /* AccountsBridge.swift */; }; | 		37169AA82729E2CC0011DE61 /* AccountsBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37169AA52729E2CC0011DE61 /* AccountsBridge.swift */; }; | ||||||
|  | 		3717407D2949D40800FDDBC7 /* ChannelLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3717407C2949D40800FDDBC7 /* ChannelLinkView.swift */; }; | ||||||
|  | 		3717407E2949D40800FDDBC7 /* ChannelLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3717407C2949D40800FDDBC7 /* ChannelLinkView.swift */; }; | ||||||
|  | 		3717407F2949D40800FDDBC7 /* ChannelLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3717407C2949D40800FDDBC7 /* ChannelLinkView.swift */; }; | ||||||
| 		3718B9A02921A9620003DB2E /* VideoDetailsOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E80F3B287B107F00561799 /* VideoDetailsOverlay.swift */; }; | 		3718B9A02921A9620003DB2E /* VideoDetailsOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E80F3B287B107F00561799 /* VideoDetailsOverlay.swift */; }; | ||||||
| 		3718B9A12921A9640003DB2E /* VideoDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B81AFE26D2CA3700675966 /* VideoDetails.swift */; }; | 		3718B9A12921A9640003DB2E /* VideoDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B81AFE26D2CA3700675966 /* VideoDetails.swift */; }; | ||||||
| 		3718B9A22921A9670003DB2E /* VideoActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374924EF29216C630017D862 /* VideoActions.swift */; }; | 		3718B9A22921A9670003DB2E /* VideoActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374924EF29216C630017D862 /* VideoActions.swift */; }; | ||||||
| @@ -1144,6 +1147,7 @@ | |||||||
| 		37152EE926EFEB95004FB96D /* LazyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyView.swift; sourceTree = "<group>"; }; | 		37152EE926EFEB95004FB96D /* LazyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyView.swift; sourceTree = "<group>"; }; | ||||||
| 		37169AA12729D98A0011DE61 /* InstancesBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstancesBridge.swift; sourceTree = "<group>"; }; | 		37169AA12729D98A0011DE61 /* InstancesBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstancesBridge.swift; sourceTree = "<group>"; }; | ||||||
| 		37169AA52729E2CC0011DE61 /* AccountsBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsBridge.swift; sourceTree = "<group>"; }; | 		37169AA52729E2CC0011DE61 /* AccountsBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsBridge.swift; sourceTree = "<group>"; }; | ||||||
|  | 		3717407C2949D40800FDDBC7 /* ChannelLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelLinkView.swift; sourceTree = "<group>"; }; | ||||||
| 		37192D5628B179D60012EEDD /* ChaptersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChaptersView.swift; sourceTree = "<group>"; }; | 		37192D5628B179D60012EEDD /* ChaptersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChaptersView.swift; sourceTree = "<group>"; }; | ||||||
| 		371B7E5B27596B8400D21217 /* Comment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Comment.swift; sourceTree = "<group>"; }; | 		371B7E5B27596B8400D21217 /* Comment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Comment.swift; sourceTree = "<group>"; }; | ||||||
| 		371B7E602759706A00D21217 /* CommentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentsView.swift; sourceTree = "<group>"; }; | 		371B7E602759706A00D21217 /* CommentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentsView.swift; sourceTree = "<group>"; }; | ||||||
| @@ -2143,6 +2147,7 @@ | |||||||
| 			children = ( | 			children = ( | ||||||
| 				3776924D294630110055EC18 /* ChannelAvatarView.swift */, | 				3776924D294630110055EC18 /* ChannelAvatarView.swift */, | ||||||
| 				3743B86727216D3600261544 /* ChannelCell.swift */, | 				3743B86727216D3600261544 /* ChannelCell.swift */, | ||||||
|  | 				3717407C2949D40800FDDBC7 /* ChannelLinkView.swift */, | ||||||
| 				37BDFF1A29487C5A000C6404 /* ChannelListItem.swift */, | 				37BDFF1A29487C5A000C6404 /* ChannelListItem.swift */, | ||||||
| 				37C3A24827235FAA0087A57A /* ChannelPlaylistCell.swift */, | 				37C3A24827235FAA0087A57A /* ChannelPlaylistCell.swift */, | ||||||
| 				37BDFF1E29488117000C6404 /* ChannelPlaylistListItem.swift */, | 				37BDFF1E29488117000C6404 /* ChannelPlaylistListItem.swift */, | ||||||
| @@ -3079,6 +3084,7 @@ | |||||||
| 				3722AEBC274DA396005EA4D6 /* Badge+Backport.swift in Sources */, | 				3722AEBC274DA396005EA4D6 /* Badge+Backport.swift in Sources */, | ||||||
| 				3748186626A7627F0084E870 /* Video+Fixtures.swift in Sources */, | 				3748186626A7627F0084E870 /* Video+Fixtures.swift in Sources */, | ||||||
| 				37599F34272B44000087F250 /* FavoritesModel.swift in Sources */, | 				37599F34272B44000087F250 /* FavoritesModel.swift in Sources */, | ||||||
|  | 				3717407D2949D40800FDDBC7 /* ChannelLinkView.swift in Sources */, | ||||||
| 				37030FF727B0347C00ECDDAA /* MPVPlayerView.swift in Sources */, | 				37030FF727B0347C00ECDDAA /* MPVPlayerView.swift in Sources */, | ||||||
| 				37BA794726DC2E56002A0235 /* AppSidebarSubscriptions.swift in Sources */, | 				37BA794726DC2E56002A0235 /* AppSidebarSubscriptions.swift in Sources */, | ||||||
| 				377FC7DC267A081800A6BBAF /* PopularView.swift in Sources */, | 				377FC7DC267A081800A6BBAF /* PopularView.swift in Sources */, | ||||||
| @@ -3484,6 +3490,7 @@ | |||||||
| 				378E9C39294552A700B2D696 /* ThumbnailView.swift in Sources */, | 				378E9C39294552A700B2D696 /* ThumbnailView.swift in Sources */, | ||||||
| 				370F4FAB27CC164D001B35DC /* PlayerControlsModel.swift in Sources */, | 				370F4FAB27CC164D001B35DC /* PlayerControlsModel.swift in Sources */, | ||||||
| 				37E8B0ED27B326C00024006F /* TimelineView.swift in Sources */, | 				37E8B0ED27B326C00024006F /* TimelineView.swift in Sources */, | ||||||
|  | 				3717407E2949D40800FDDBC7 /* ChannelLinkView.swift in Sources */, | ||||||
| 				37FB28422721B22200A57617 /* ContentItem.swift in Sources */, | 				37FB28422721B22200A57617 /* ContentItem.swift in Sources */, | ||||||
| 				376CD21726FBE18D001E1AC1 /* Instance+Fixtures.swift in Sources */, | 				376CD21726FBE18D001E1AC1 /* Instance+Fixtures.swift in Sources */, | ||||||
| 				37B17DA1268A1F89006AEE9B /* VideoContextMenuView.swift in Sources */, | 				37B17DA1268A1F89006AEE9B /* VideoContextMenuView.swift in Sources */, | ||||||
| @@ -3694,6 +3701,7 @@ | |||||||
| 				374C0541272472C0009BDDBE /* PlayerSponsorBlock.swift in Sources */, | 				374C0541272472C0009BDDBE /* PlayerSponsorBlock.swift in Sources */, | ||||||
| 				37130A61277657300033018A /* PersistenceController.swift in Sources */, | 				37130A61277657300033018A /* PersistenceController.swift in Sources */, | ||||||
| 				37E70929271CDDAE00D34DDE /* OpenSettingsButton.swift in Sources */, | 				37E70929271CDDAE00D34DDE /* OpenSettingsButton.swift in Sources */, | ||||||
|  | 				3717407F2949D40800FDDBC7 /* ChannelLinkView.swift in Sources */, | ||||||
| 				370F4FAA27CC163B001B35DC /* PlayerBackend.swift in Sources */, | 				370F4FAA27CC163B001B35DC /* PlayerBackend.swift in Sources */, | ||||||
| 				376A33E62720CB35000C1D6B /* Account.swift in Sources */, | 				376A33E62720CB35000C1D6B /* Account.swift in Sources */, | ||||||
| 				3763C98B290C7A50004D3B5F /* OpenVideosView.swift in Sources */, | 				3763C98B290C7A50004D3B5F /* OpenVideosView.swift in Sources */, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Arkadiusz Fal
					Arkadiusz Fal