Remove Watch Next

This commit is contained in:
Arkadiusz Fal
2023-04-22 13:56:25 +02:00
parent 67690bc435
commit 28f346dee2
14 changed files with 21 additions and 727 deletions

View File

@@ -28,7 +28,6 @@ struct PlayerControls: View {
@Default(.playerControlsLayout) private var regularPlayerControlsLayout
@Default(.fullScreenPlayerControlsLayout) private var fullScreenPlayerControlsLayout
@Default(.openWatchNextOnClose) private var openWatchNextOnClose
@Default(.buttonBackwardSeekDuration) private var buttonBackwardSeekDuration
@Default(.buttonForwardSeekDuration) private var buttonForwardSeekDuration
@@ -40,7 +39,6 @@ struct PlayerControls: View {
@Default(.playerControlsRestartEnabled) private var playerControlsRestartEnabled
@Default(.playerControlsAdvanceToNextEnabled) private var playerControlsAdvanceToNextEnabled
@Default(.playerControlsPlaybackModeEnabled) private var playerControlsPlaybackModeEnabled
@Default(.playerControlsNextEnabled) private var playerControlsNextEnabled
@Default(.playerControlsMusicModeEnabled) private var playerControlsMusicModeEnabled
private let controlsOverlayModel = ControlOverlaysModel.shared
@@ -162,9 +160,6 @@ struct PlayerControls: View {
if playerControlsPlaybackModeEnabled {
playbackModeButton
}
if playerControlsNextEnabled {
watchNextButton
}
#if os(tvOS)
closeVideoButton
#else
@@ -360,12 +355,7 @@ struct PlayerControls: View {
private var closeVideoButton: some View {
button("Close", systemImage: "xmark") {
if openWatchNextOnClose {
player.pause()
WatchNextViewModel.shared.closed(player.currentItem)
} else {
player.closeCurrentItem()
}
player.closeCurrentItem()
}
#if os(tvOS)
.focused($focusedField, equals: .close)
@@ -409,12 +399,6 @@ struct PlayerControls: View {
}
}
var watchNextButton: some View {
button("Watch Next", systemImage: Constants.nextSystemImage) {
WatchNextViewModel.shared.userInteractedOpen(player.currentItem)
}
}
var seekBackwardButton: some View {
var foregroundColor: Color?
var fontSize: Double?

View File

@@ -57,7 +57,7 @@ struct InspectorView: View {
}
var header: some View {
Text("Inspector")
Text("Inspector".localized())
.font(.caption)
.foregroundColor(.secondary)
.frame(maxWidth: .infinity, alignment: .leading)

View File

@@ -7,7 +7,6 @@ struct VideoActions: View {
case addToPlaylist
case subscribe
case settings
case next
case hide
case close
}
@@ -19,17 +18,14 @@ struct VideoActions: View {
var video: Video?
@Default(.openWatchNextOnClose) private var openWatchNextOnClose
@Default(.playerActionsButtonLabelStyle) private var playerActionsButtonLabelStyle
@Default(.actionButtonShareEnabled) private var actionButtonShareEnabled
@Default(.actionButtonAddToPlaylistEnabled) private var actionButtonAddToPlaylistEnabled
@Default(.actionButtonSubscribeEnabled) private var actionButtonSubscribeEnabled
@Default(.actionButtonSettingsEnabled) private var actionButtonSettingsEnabled
@Default(.actionButtonNextEnabled) private var actionButtonNextEnabled
@Default(.actionButtonHideEnabled) private var actionButtonHideEnabled
@Default(.actionButtonCloseEnabled) private var actionButtonCloseEnabled
@Default(.actionButtonNextQueueCountEnabled) private var actionButtonNextQueueCountEnabled
var body: some View {
HStack(spacing: 6) {
@@ -55,8 +51,6 @@ struct VideoActions: View {
return actionButtonSubscribeEnabled
case .settings:
return actionButtonSettingsEnabled
case .next:
return actionButtonNextEnabled
case .hide:
return actionButtonHideEnabled
case .close:
@@ -126,10 +120,6 @@ struct VideoActions: View {
#endif
}
}
case .next:
actionButton(nextLabel, systemImage: Constants.nextSystemImage) {
WatchNextViewModel.shared.userInteractedOpen(player.currentItem)
}
case .hide:
actionButton("Hide", systemImage: "chevron.down") {
player.hide(animate: true)
@@ -137,12 +127,7 @@ struct VideoActions: View {
case .close:
actionButton("Close", systemImage: "xmark") {
if player.presentingPlayer, openWatchNextOnClose {
player.pause()
WatchNextViewModel.shared.closed(player.currentItem)
} else {
player.closeCurrentItem()
}
player.closeCurrentItem()
}
}
}
@@ -150,14 +135,6 @@ struct VideoActions: View {
}
}
var nextLabel: String {
if actionButtonNextQueueCountEnabled, !player.queue.isEmpty {
return "\("Next".localized())\(player.queue.count)"
}
return "Next".localized()
}
func actionButton(
_ name: String,
systemImage: String,

View File

@@ -80,8 +80,6 @@ struct VideoPlayerView: View {
#endif
overlay
WatchNextView()
}
.onAppear {
if player.musicMode {

View File

@@ -1,363 +0,0 @@
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 model.isPresenting {
#if os(iOS)
NavigationView {
watchNext
.toolbar {
ToolbarItem(placement: .principal) {
watchNextMenu
}
}
}
.navigationViewStyle(.stack)
#else
VStack {
HStack {
hideCloseButton
.labelStyle(.iconOnly)
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
watchNextMenu
.frame(maxWidth: .infinity)
Spacer()
HStack {
#if os(macOS)
Text("Mode")
.foregroundColor(.secondary)
#endif
playbackModeControl
HStack {
if model.isRestartable {
reopenButton
}
}
}
.frame(maxWidth: .infinity, alignment: .trailing)
}
#if os(macOS)
.padding()
#endif
watchNext
}
#endif
}
}
.transition(.opacity)
.zIndex(0)
#if os(tvOS)
.background(Color.background(scheme: colorScheme))
#else
.background(Color.background)
#endif
}
var watchNext: some View {
ScrollView {
VStack(alignment: .leading) {
if model.isAutoplaying,
let item = model.nextFromTheQueue
{
HStack {
Text("Playing Next in \(Int(model.countdown.rounded()))...")
.font(.headline.monospacedDigit())
Spacer()
Button {
model.keepFromAutoplaying()
} label: {
Label("Cancel", systemImage: "pause.fill")
#if os(iOS)
.imageScale(.large)
.padding([.vertical, .leading])
.font(.headline.bold())
#endif
}
}
#if os(tvOS)
.padding(.top, 10)
#endif
PlayerQueueRow(item: item)
Divider()
.padding(.vertical, 5)
}
moreVideos
.padding(.top, 15)
}
.padding(.horizontal)
}
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
#if !os(macOS)
.navigationTitle(model.page.title)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
hideCloseButton
}
ToolbarItem(placement: .primaryAction) {
reopenButton
}
}
#endif
}
var watchNextMenu: some View {
#if os(tvOS)
Button {
model.page = model.page.next()
} label: {
menuLabel
}
#elseif os(macOS)
pagePicker
.modifier(SettingsPickerModifier())
#if os(macOS)
.frame(maxWidth: 150)
#endif
#else
Menu {
pagePicker
playbackModePicker
} label: {
HStack(spacing: 12) {
menuLabel
.foregroundColor(.primary)
Image(systemName: "chevron.down.circle.fill")
.foregroundColor(.accentColor)
.imageScale(.small)
}
.transaction { t in t.animation = nil }
}
#endif
}
var menuLabel: some View {
HStack {
Image(systemName: model.page.systemImageName)
.imageScale(.small)
Text(model.page == .queue ? queueTitle : model.page.title)
.font(.headline)
}
}
var pagePicker: some View {
Picker("Page", selection: $model.page) {
ForEach(WatchNextViewModel.Page.allCases, id: \.rawValue) { page in
Label(
page == .queue ? queueTitle : page.title,
systemImage: page.systemImageName
)
.tag(page)
}
}
}
var queueTitle: String {
"\(WatchNextViewModel.Page.queue.title)\(player.queue.count)"
}
@ViewBuilder var hideCloseButton: some View {
Group {
if model.isHideable {
hideButton
} else {
closeButton
}
}
#if !os(tvOS)
.keyboardShortcut(.cancelAction)
#endif
}
var hideButton: some View {
Button {
model.hide()
} label: {
Label("Hide", systemImage: "xmark")
}
}
var closeButton: some View {
Button {
model.close()
} label: {
Label("Close", systemImage: "xmark")
}
}
@ViewBuilder var reopenButton: some View {
if model.isRestartable {
Button {
model.restart()
} label: {
Label(model.reason == .userInteracted ? "Back" : "Reopen", systemImage: "arrow.counterclockwise")
}
}
}
var queueForMoreVideos: [ContentItem] {
guard !player.queue.isEmpty else { return [] }
let suffix = player.playbackMode == .queue && model.isAutoplaying && model.canAutoplay ? 1 : 0
return player.queue.suffix(from: suffix).map(\.contentItem)
}
@ViewBuilder var moreVideos: some View {
VStack(spacing: 12) {
switch model.page {
case .queue:
if player.playbackMode == .related, !(model.isAutoplaying && model.canAutoplay) {
autoplaying
Divider()
}
if (model.isAutoplaying && model.canAutoplay && !queueForMoreVideos.isEmpty) ||
(!model.isAutoplaying && !queueForMoreVideos.isEmpty)
{
HStack {
Text("Next in queue")
.font(.headline)
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
ClearQueueButton()
}
}
if !queueForMoreVideos.isEmpty {
LazyVStack {
ForEach(queueForMoreVideos) { item in
ContentItemView(item: item)
.environment(\.inQueueListing, true)
.environment(\.listingStyle, .list)
}
}
} else {
Label(
model.isAutoplaying ? "Nothing more in the queue" : "Queue is empty",
systemImage: WatchNextViewModel.Page.queue.systemImageName
)
.foregroundColor(.secondary)
}
case .related:
if let item = model.item {
ForEach(item.video.related) { video in
ContentItemView(item: .init(video: video))
.environment(\.listingStyle, .list)
}
} else {
Label("Nothing was played",
systemImage: WatchNextViewModel.Page.related.systemImageName)
.foregroundColor(.secondary)
}
case .history:
if saveHistory {
HistoryView(limit: 15)
}
}
}
}
@ViewBuilder var playbackModeControl: some View {
#if os(tvOS)
Button {
player.playbackMode = player.playbackMode.next()
} label: {
Label(player.playbackMode.description, systemImage: player.playbackMode.systemImage)
.transaction { t in t.animation = nil }
.frame(minWidth: 350)
}
#elseif os(macOS)
playbackModePicker
.modifier(SettingsPickerModifier())
#if os(macOS)
.frame(maxWidth: 150)
#endif
#else
Menu {
playbackModePicker
} label: {
Label(player.playbackMode.description, systemImage: player.playbackMode.systemImage)
}
#endif
}
var playbackModePicker: some View {
Picker("Playback Mode", selection: $model.player.playbackMode) {
ForEach(PlayerModel.PlaybackMode.allCases, id: \.rawValue) { mode in
Label(mode.description, systemImage: mode.systemImage).tag(mode)
}
}
.labelsHidden()
}
@ViewBuilder var autoplaying: some View {
Section(header: autoplayingHeader) {
if let item = player.autoplayItem {
PlayerQueueRow(item: item, autoplay: true)
} else {
Group {
if player.currentItem.isNil {
Text("Not Playing")
} else {
Text("Finding something to play...")
}
}
.foregroundColor(.secondary)
}
}
}
var autoplayingHeader: some View {
HStack {
Text("Autoplaying Next")
.font(.headline)
Spacer()
Button {
player.setRelatedAutoplayItem()
} label: {
Label("Find Other", systemImage: "arrow.triangle.2.circlepath.circle")
.labelStyle(.iconOnly)
.foregroundColor(.accentColor)
}
.disabled(player.currentItem.isNil)
.buttonStyle(.plain)
}
}
}
struct WatchNextView_Previews: PreviewProvider {
static var previews: some View {
WatchNextView()
.onAppear {
WatchNextViewModel.shared.finishedWatching(.init(.fixture))
}
}
}