mirror of
https://github.com/yattee/yattee.git
synced 2025-08-05 02:04:07 +00:00
Remove Watch Next
This commit is contained in:
@@ -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?
|
||||
|
@@ -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)
|
||||
|
@@ -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,
|
||||
|
@@ -80,8 +80,6 @@ struct VideoPlayerView: View {
|
||||
#endif
|
||||
|
||||
overlay
|
||||
|
||||
WatchNextView()
|
||||
}
|
||||
.onAppear {
|
||||
if player.musicMode {
|
||||
|
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user