yattee/Shared/Player/WatchNextView.swift
2023-02-05 14:24:14 +01:00

175 lines
5.0 KiB
Swift

import Defaults
import SwiftUI
struct WatchNextView: View {
@ObservedObject private var model = WatchNextViewModel.shared
@ObservedObject private var player = PlayerModel.shared
@Default(.saveHistory) private var saveHistory
@Environment(\.colorScheme) private var colorScheme
var body: some View {
Group {
#if os(iOS)
NavigationView {
watchNext
}
#else
VStack {
HStack {
closeButton
Spacer()
reopenButton
}
.padding()
watchNext
}
#endif
}
#if os(tvOS)
.background(Color.background(scheme: colorScheme))
#else
.background(Color.background)
#endif
.opacity(model.presentingOutro ? 1 : 0)
}
var watchNext: some View {
ScrollView {
VStack(alignment: .leading) {
if model.isAutoplaying,
let item = nextFromTheQueue
{
HStack {
Text("Playing Next in 5...")
.font(.headline)
Spacer()
Button {
model.cancelAutoplay()
} label: {
Label("Cancel", systemImage: "xmark")
}
}
PlayerQueueRow(item: item)
.padding(.bottom, 10)
}
moreVideos
}
.padding(.horizontal)
}
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
.navigationTitle("Watch Next")
#if !os(macOS)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
closeButton
}
ToolbarItem(placement: .primaryAction) {
reopenButton
}
}
#endif
}
var closeButton: some View {
Button {
player.closeCurrentItem()
player.hide()
Delay.by(0.8) {
model.presentingOutro = false
}
} label: {
Label("Close", systemImage: "xmark")
}
}
@ViewBuilder var reopenButton: some View {
if player.currentItem != nil, model.item != nil {
Button {
model.close()
} label: {
Label("Back to last video", systemImage: "arrow.counterclockwise")
}
}
}
@ViewBuilder var moreVideos: some View {
VStack(spacing: 12) {
let queueForMoreVideos = player.queue.isEmpty ? [] : player.queue.suffix(from: model.isAutoplaying ? 1 : 0)
if !queueForMoreVideos.isEmpty {
VStack(spacing: 12) {
Text("Next in Queue")
.frame(maxWidth: .infinity, alignment: .leading)
.font(.headline)
ForEach(queueForMoreVideos) { item in
ContentItemView(item: .init(video: item.video))
.environment(\.listingStyle, .list)
}
}
}
if let item = model.item {
VStack(spacing: 12) {
Text("Related videos")
.frame(maxWidth: .infinity, alignment: .leading)
.font(.headline)
ForEach(item.video.related) { video in
ContentItemView(item: .init(video: video))
.environment(\.listingStyle, .list)
}
.padding(.bottom, 4)
}
}
if saveHistory {
VStack(spacing: 12) {
Text("History")
.frame(maxWidth: .infinity, alignment: .leading)
.font(.headline)
HStack {
Text("Playing Next in 5...")
.font(.headline)
Spacer()
Button {
model.cancelAutoplay()
} label: {
Label("Cancel", systemImage: "pause.fill")
}
}
HistoryView(limit: 15)
}
}
}
}
var nextFromTheQueue: PlayerQueueItem? {
if player.playbackMode == .related {
return player.autoplayItem
} else if player.playbackMode == .queue {
return player.queue.first
}
return nil
}
}
struct OutroView_Previews: PreviewProvider {
static var previews: some View {
WatchNextView()
.onAppear {
WatchNextViewModel.shared.prepareForNextItem(.init(.fixture))
}
}
}