Cells view

This commit is contained in:
Arkadiusz Fal
2021-06-24 00:19:58 +02:00
parent cbcf58d5c7
commit 0e02a6e25a
13 changed files with 208 additions and 55 deletions

View File

@@ -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 {

View File

@@ -15,7 +15,7 @@ struct PlayerView: View {
.edgesIgnoringSafeArea(.all)
}
.task {
async {
Task.init {
provider.load()
}
}

View File

@@ -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()
}
}

View File

@@ -10,6 +10,7 @@ struct SearchView: View {
var body: some View {
VideosView(tabSelection: $tabSelection, videos: videos)
.environmentObject(state)
.searchable(text: $query)
}

View File

@@ -9,7 +9,7 @@ struct SubscriptionsView: View {
var body: some View {
VideosView(tabSelection: $tabSelection, videos: videos)
.task {
async {
Task.init {
provider.load()
}
}

View 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)
}
}

View File

@@ -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

View 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)
}
}

View 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)
}
}

View File

@@ -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)
}
}