mirror of
				https://github.com/yattee/yattee.git
				synced 2025-10-31 04:31:54 +00:00 
			
		
		
		
	Cells view
This commit is contained in:
		| @@ -7,7 +7,7 @@ struct ChannelView: View { | ||||
|     @Binding var tabSelection: TabSelection | ||||
|  | ||||
|     var body: some View { | ||||
|         VideosView(tabSelection: $tabSelection, videos: videos) | ||||
|         VideosListView(tabSelection: $tabSelection, videos: videos) | ||||
|     } | ||||
|  | ||||
|     var listRowInsets: EdgeInsets { | ||||
|   | ||||
| @@ -15,7 +15,7 @@ struct PlayerView: View { | ||||
|                 .edgesIgnoringSafeArea(.all) | ||||
|         } | ||||
|         .task { | ||||
|             async { | ||||
|             Task.init { | ||||
|                 provider.load() | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -2,14 +2,13 @@ import SwiftUI | ||||
|  | ||||
| struct PopularVideosView: View { | ||||
|     @ObservedObject private var provider = PopularVideosProvider() | ||||
|     @EnvironmentObject private var state: AppState | ||||
|  | ||||
|     @Binding var tabSelection: TabSelection | ||||
|  | ||||
|     var body: some View { | ||||
|         VideosView(tabSelection: $tabSelection, videos: videos) | ||||
|             .task { | ||||
|                 async { | ||||
|                 Task.init { | ||||
|                     provider.load() | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -10,6 +10,7 @@ struct SearchView: View { | ||||
|  | ||||
|     var body: some View { | ||||
|         VideosView(tabSelection: $tabSelection, videos: videos) | ||||
|             .environmentObject(state) | ||||
|             .searchable(text: $query) | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,7 @@ struct SubscriptionsView: View { | ||||
|     var body: some View { | ||||
|         VideosView(tabSelection: $tabSelection, videos: videos) | ||||
|             .task { | ||||
|                 async { | ||||
|                 Task.init { | ||||
|                     provider.load() | ||||
|                 } | ||||
|             } | ||||
|   | ||||
							
								
								
									
										72
									
								
								Apple TV/VideoCellView.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								Apple TV/VideoCellView.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| import URLImage | ||||
| import URLImageStore | ||||
|  | ||||
| import SwiftUI | ||||
|  | ||||
| struct VideoCellView: View { | ||||
|     var video: Video | ||||
|     var body: some View { | ||||
|         NavigationLink(destination: PlayerView(id: video.id)) { | ||||
|             VStack(alignment: .leading) { | ||||
|                 ZStack(alignment: .trailing) { | ||||
|                     if let thumbnail = video.thumbnailURL { | ||||
|                         // to replace with AsyncImage when it is fixed with lazy views | ||||
|                         URLImage(thumbnail) { image in | ||||
|                             image | ||||
|                                 .resizable() | ||||
|                                 .aspectRatio(contentMode: .fill) | ||||
|                                 .frame(width: 550, height: 310) | ||||
|                         } | ||||
|                         .mask(RoundedRectangle(cornerRadius: 12)) | ||||
|                     } else { | ||||
|                         Image(systemName: "exclamationmark.square") | ||||
|                             .frame(width: 550, height: 310) | ||||
|                     } | ||||
|  | ||||
|                     Text(video.author) | ||||
|                         .padding(8) | ||||
|                         .background(.thickMaterial) | ||||
|                         .mask(RoundedRectangle(cornerRadius: 12)) | ||||
|                         .offset(x: -10, y: -120) | ||||
|                         .truncationMode(.middle) | ||||
|  | ||||
|                     if let time = video.playTime { | ||||
|                         Text(time) | ||||
|                             .fontWeight(.bold) | ||||
|                             .padding(8) | ||||
|                             .background(.thickMaterial) | ||||
|                             .mask(RoundedRectangle(cornerRadius: 12)) | ||||
|                             .offset(x: -10, y: 115) | ||||
|                     } | ||||
|                 } | ||||
|                 .frame(width: 550, height: 310) | ||||
|  | ||||
|                 VStack(alignment: .leading) { | ||||
|                     Text(video.title) | ||||
|                         .bold() | ||||
|                         .lineLimit(2) | ||||
|                         .multilineTextAlignment(.leading) | ||||
|                         .padding(.horizontal) | ||||
|                         .padding(.bottom, 2) | ||||
|                         .frame(minHeight: 80, alignment: .top) | ||||
|                         .truncationMode(.middle) | ||||
|  | ||||
|                     HStack(spacing: 8) { | ||||
|                         Image(systemName: "calendar") | ||||
|                         Text(video.published) | ||||
|  | ||||
|                         if video.views != 0 { | ||||
|                             Image(systemName: "eye") | ||||
|                             Text(video.viewsCount) | ||||
|                         } | ||||
|                     } | ||||
|                     .padding([.horizontal, .bottom]) | ||||
|                     .foregroundColor(.secondary) | ||||
|                 } | ||||
|             } | ||||
|             .frame(width: 550, alignment: .leading) | ||||
|         } | ||||
|         .buttonStyle(.plain) | ||||
|         .padding(.vertical) | ||||
|     } | ||||
| } | ||||
| @@ -2,7 +2,7 @@ import SwiftUI | ||||
| import URLImage | ||||
| import URLImageStore | ||||
| 
 | ||||
| struct VideoThumbnailView: View { | ||||
| struct VideoListRow: View { | ||||
|     @Environment(\.isFocused) private var focused: Bool | ||||
| 
 | ||||
|     var video: Video | ||||
							
								
								
									
										29
									
								
								Apple TV/VideosCellsView.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								Apple TV/VideosCellsView.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| import SwiftUI | ||||
|  | ||||
| struct VideosCellsView: View { | ||||
|     @EnvironmentObject private var state: AppState | ||||
|  | ||||
|     @State private var columns: Int | ||||
|  | ||||
|     init(videos: [Video], columns: Int = 3) { | ||||
|         self.videos = videos | ||||
|         self.columns = columns | ||||
|     } | ||||
|  | ||||
|     var videos = [Video]() | ||||
|  | ||||
|     var body: some View { | ||||
|         ScrollView(.vertical) { | ||||
|             LazyVGrid(columns: items, spacing: 10) { | ||||
|                 ForEach(videos) { video in | ||||
|                     VideoCellView(video: video) | ||||
|                 } | ||||
|             } | ||||
|             .padding() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     var items: [GridItem] { | ||||
|         Array(repeating: .init(.fixed(600)), count: columns) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										46
									
								
								Apple TV/VideosListView.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								Apple TV/VideosListView.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| import SwiftUI | ||||
|  | ||||
| struct VideosListView: View { | ||||
|     @EnvironmentObject private var state: AppState | ||||
|  | ||||
|     @Binding var tabSelection: TabSelection | ||||
|  | ||||
|     var videos: [Video] | ||||
|  | ||||
|     var body: some View { | ||||
|         Section { | ||||
|             List { | ||||
|                 ForEach(videos) { video in | ||||
|                     VideoListRow(video: video) | ||||
|                         .contextMenu { | ||||
|                             if tabSelection == .channel { | ||||
|                                 closeChannelButton(name: video.author) | ||||
|                             } else { | ||||
|                                 openChannelButton(from: video) | ||||
|                             } | ||||
|                         } | ||||
|                         .listRowInsets(listRowInsets) | ||||
|                 } | ||||
|             } | ||||
|             .listStyle(GroupedListStyle()) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     func openChannelButton(from video: Video) -> some View { | ||||
|         Button("\(video.author) Channel") { | ||||
|             state.openChannel(from: video) | ||||
|             tabSelection = .channel | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     func closeChannelButton(name: String) -> some View { | ||||
|         Button("Close \(name) Channel") { | ||||
|             tabSelection = .popular | ||||
|             state.closeChannel() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     var listRowInsets: EdgeInsets { | ||||
|         EdgeInsets(top: .zero, leading: .zero, bottom: .zero, trailing: 30) | ||||
|     } | ||||
| } | ||||
| @@ -4,43 +4,15 @@ struct VideosView: View { | ||||
|     @EnvironmentObject private var state: AppState | ||||
|  | ||||
|     @Binding var tabSelection: TabSelection | ||||
|  | ||||
|     var videos: [Video] | ||||
|  | ||||
|     var body: some View { | ||||
|         Section { | ||||
|             List { | ||||
|                 ForEach(videos) { video in | ||||
|                     VideoThumbnailView(video: video) | ||||
|                         .contextMenu { | ||||
|                             if tabSelection == .channel { | ||||
|                                 closeChannelButton(name: video.author) | ||||
|                             } else { | ||||
|                                 openChannelButton(from: video) | ||||
|                             } | ||||
|                         } | ||||
|                         .listRowInsets(listRowInsets) | ||||
|                 } | ||||
|         Group { | ||||
|             if state.profile.listing == .list { | ||||
|                 VideosListView(tabSelection: $tabSelection, videos: videos) | ||||
|             } else { | ||||
|                 VideosCellsView(videos: videos, columns: state.profile.cellsColumns) | ||||
|             } | ||||
|             .listStyle(GroupedListStyle()) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     func openChannelButton(from video: Video) -> some View { | ||||
|         Button("\(video.author) Channel") { | ||||
|             state.openChannel(from: video) | ||||
|             tabSelection = .channel | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     func closeChannelButton(name: String) -> some View { | ||||
|         Button("Close \(name) Channel") { | ||||
|             tabSelection = .popular | ||||
|             state.closeChannel() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     var listRowInsets: EdgeInsets { | ||||
|         EdgeInsets(top: .zero, leading: .zero, bottom: .zero, trailing: 30) | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Arkadiusz Fal
					Arkadiusz Fal