mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 21:43:41 +00:00
New actions buttons
This commit is contained in:
parent
a7763c5802
commit
8f9fb7ba82
@ -664,6 +664,46 @@ final class PlayerModel: ObservableObject {
|
||||
backend.closePiP()
|
||||
}
|
||||
|
||||
var pipImage: String {
|
||||
transitioningToPiP ? "pip.fill" : pipController?.isPictureInPictureActive ?? false ? "pip.exit" : "pip.enter"
|
||||
}
|
||||
|
||||
var fullscreenImage: String {
|
||||
playingFullScreen ? "arrow.down.right.and.arrow.up.left" : "arrow.up.left.and.arrow.down.right"
|
||||
}
|
||||
|
||||
func toggleFullScreenAction() {
|
||||
toggleFullscreen(playingFullScreen, showControls: false)
|
||||
}
|
||||
|
||||
func togglePiPAction() {
|
||||
(pipController?.isPictureInPictureActive ?? false) ? closePiP() : startPiP()
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
var lockOrientationImage: String {
|
||||
lockedOrientation.isNil ? "lock.rotation.open" : "lock.rotation"
|
||||
}
|
||||
|
||||
func lockOrientationAction() {
|
||||
if lockedOrientation.isNil {
|
||||
let orientationMask = OrientationTracker.shared.currentInterfaceOrientationMask
|
||||
lockedOrientation = orientationMask
|
||||
let orientation = OrientationTracker.shared.currentInterfaceOrientation
|
||||
Orientation.lockOrientation(orientationMask, andRotateTo: .landscapeLeft)
|
||||
// iOS 16 workaround
|
||||
Orientation.lockOrientation(orientationMask, andRotateTo: orientation)
|
||||
} else {
|
||||
lockedOrientation = nil
|
||||
Orientation.lockOrientation(.allButUpsideDown, andRotateTo: OrientationTracker.shared.currentInterfaceOrientation)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
func replayAction() {
|
||||
backend.seek(to: 0.0, seekType: .userInteracted)
|
||||
}
|
||||
|
||||
func handleQueueChange() {
|
||||
Defaults[.queue] = queue
|
||||
|
||||
|
@ -201,6 +201,12 @@ extension Defaults.Keys {
|
||||
static let actionButtonSettingsEnabled = Key<Bool>("actionButtonSettingsEnabled", default: true)
|
||||
static let actionButtonHideEnabled = Key<Bool>("actionButtonHideEnabled", default: false)
|
||||
static let actionButtonCloseEnabled = Key<Bool>("actionButtonCloseEnabled", default: true)
|
||||
static let actionButtonFullScreenEnabled = Key<Bool>("actionButtonFullScreenEnabled", default: false)
|
||||
static let actionButtonPipEnabled = Key<Bool>("actionButtonPipEnabled", default: false)
|
||||
static let actionButtonLockOrientationEnabled = Key<Bool>("actionButtonLockOrientationEnabled", default: false)
|
||||
static let actionButtonRestartEnabled = Key<Bool>("actionButtonRestartEnabled", default: false)
|
||||
static let actionButtonAdvanceToNextItemEnabled = Key<Bool>("actionButtonAdvanceToNextItemEnabled", default: false)
|
||||
static let actionButtonMusicModeEnabled = Key<Bool>("actionButtonMusicModeEnabled", default: true)
|
||||
|
||||
#if os(iOS)
|
||||
static let playerControlsLockOrientationEnabled = Key<Bool>("playerControlsLockOrientationEnabled", default: true)
|
||||
@ -215,7 +221,7 @@ extension Defaults.Keys {
|
||||
static let playerControlsRestartEnabled = Key<Bool>("playerControlsRestartEnabled", default: false)
|
||||
static let playerControlsAdvanceToNextEnabled = Key<Bool>("playerControlsAdvanceToNextEnabled", default: false)
|
||||
static let playerControlsPlaybackModeEnabled = Key<Bool>("playerControlsPlaybackModeEnabled", default: false)
|
||||
static let playerControlsMusicModeEnabled = Key<Bool>("playerControlsMusicModeEnabled", default: true)
|
||||
static let playerControlsMusicModeEnabled = Key<Bool>("playerControlsMusicModeEnabled", default: false)
|
||||
|
||||
static let mpvCacheSecs = Key<String>("mpvCacheSecs", default: "120")
|
||||
static let mpvCachePauseWait = Key<String>("mpvCachePauseWait", default: "3")
|
||||
|
@ -329,7 +329,7 @@ struct PlayerControls: View {
|
||||
var fullscreenButton: some View {
|
||||
button(
|
||||
"Fullscreen",
|
||||
systemImage: player.playingFullScreen ? "arrow.down.right.and.arrow.up.left" : "arrow.up.left.and.arrow.down.right"
|
||||
systemImage: player.fullscreenImage
|
||||
) {
|
||||
player.toggleFullscreen(player.playingFullScreen, showControls: false)
|
||||
}
|
||||
@ -367,28 +367,13 @@ struct PlayerControls: View {
|
||||
}
|
||||
|
||||
private var pipButton: some View {
|
||||
let image = player.transitioningToPiP ? "pip.fill" : player.pipController?.isPictureInPictureActive ?? false ? "pip.exit" : "pip.enter"
|
||||
return button("PiP", systemImage: image) {
|
||||
(player.pipController?.isPictureInPictureActive ?? false) ? player.closePiP() : player.startPiP()
|
||||
}
|
||||
button("PiP", systemImage: player.pipImage, action: player.togglePiPAction)
|
||||
.disabled(!player.pipPossible)
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
private var lockOrientationButton: some View {
|
||||
button("Lock Rotation", systemImage: player.lockedOrientation.isNil ? "lock.rotation.open" : "lock.rotation", active: !player.lockedOrientation.isNil) {
|
||||
if player.lockedOrientation.isNil {
|
||||
let orientationMask = OrientationTracker.shared.currentInterfaceOrientationMask
|
||||
player.lockedOrientation = orientationMask
|
||||
let orientation = OrientationTracker.shared.currentInterfaceOrientation
|
||||
Orientation.lockOrientation(orientationMask, andRotateTo: .landscapeLeft)
|
||||
// iOS 16 workaround
|
||||
Orientation.lockOrientation(orientationMask, andRotateTo: orientation)
|
||||
} else {
|
||||
player.lockedOrientation = nil
|
||||
Orientation.lockOrientation(.allButUpsideDown, andRotateTo: OrientationTracker.shared.currentInterfaceOrientation)
|
||||
}
|
||||
}
|
||||
button("Lock Rotation", systemImage: player.lockOrientationImage, active: !player.lockedOrientation.isNil, action: player.lockOrientationAction)
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -456,9 +441,7 @@ struct PlayerControls: View {
|
||||
}
|
||||
|
||||
private var restartVideoButton: some View {
|
||||
button("Restart video", systemImage: "backward.end.fill", cornerRadius: 5) {
|
||||
player.backend.seek(to: 0.0, seekType: .userInteracted)
|
||||
}
|
||||
button("Restart video", systemImage: "backward.end.fill", cornerRadius: 5, action: player.replayAction)
|
||||
}
|
||||
|
||||
private var togglePlayButton: some View {
|
||||
|
@ -6,6 +6,14 @@ struct VideoActions: View {
|
||||
case share
|
||||
case addToPlaylist
|
||||
case subscribe
|
||||
case fullScreen
|
||||
case pip
|
||||
#if os(iOS)
|
||||
case lockOrientation
|
||||
#endif
|
||||
case restart
|
||||
case advanceToNextItem
|
||||
case musicMode
|
||||
case settings
|
||||
case hide
|
||||
case close
|
||||
@ -24,6 +32,12 @@ struct VideoActions: View {
|
||||
@Default(.actionButtonAddToPlaylistEnabled) private var actionButtonAddToPlaylistEnabled
|
||||
@Default(.actionButtonSubscribeEnabled) private var actionButtonSubscribeEnabled
|
||||
@Default(.actionButtonSettingsEnabled) private var actionButtonSettingsEnabled
|
||||
@Default(.actionButtonFullScreenEnabled) private var actionButtonFullScreenEnabled
|
||||
@Default(.actionButtonPipEnabled) private var actionButtonPipEnabled
|
||||
@Default(.actionButtonLockOrientationEnabled) private var actionButtonLockOrientationEnabled
|
||||
@Default(.actionButtonRestartEnabled) private var actionButtonRestartEnabled
|
||||
@Default(.actionButtonAdvanceToNextItemEnabled) private var actionButtonAdvanceToNextItemEnabled
|
||||
@Default(.actionButtonMusicModeEnabled) private var actionButtonMusicModeEnabled
|
||||
@Default(.actionButtonHideEnabled) private var actionButtonHideEnabled
|
||||
@Default(.actionButtonCloseEnabled) private var actionButtonCloseEnabled
|
||||
|
||||
@ -51,6 +65,20 @@ struct VideoActions: View {
|
||||
return actionButtonSubscribeEnabled
|
||||
case .settings:
|
||||
return actionButtonSettingsEnabled
|
||||
case .fullScreen:
|
||||
return actionButtonFullScreenEnabled
|
||||
case .pip:
|
||||
return actionButtonPipEnabled
|
||||
#if os(iOS)
|
||||
case .lockOrientation:
|
||||
return actionButtonLockOrientationEnabled
|
||||
#endif
|
||||
case .restart:
|
||||
return actionButtonRestartEnabled
|
||||
case .advanceToNextItem:
|
||||
return actionButtonAdvanceToNextItemEnabled
|
||||
case .musicMode:
|
||||
return actionButtonMusicModeEnabled
|
||||
case .hide:
|
||||
return actionButtonHideEnabled
|
||||
case .close:
|
||||
@ -68,6 +96,8 @@ struct VideoActions: View {
|
||||
return !(video?.isLocal ?? true) && accounts.signedIn && accounts.app.supportsSubscriptions
|
||||
case .settings:
|
||||
return video != nil
|
||||
case .advanceToNextItem:
|
||||
return player.isAdvanceToNextItemAvailable
|
||||
default:
|
||||
return true
|
||||
}
|
||||
@ -110,6 +140,23 @@ struct VideoActions: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
case .fullScreen:
|
||||
actionButton("Fullscreen", systemImage: player.fullscreenImage, action: player.toggleFullScreenAction)
|
||||
case .pip:
|
||||
actionButton("PiP", systemImage: player.pipImage, action: player.togglePiPAction)
|
||||
#if os(iOS)
|
||||
case .lockOrientation:
|
||||
actionButton("Lock", systemImage: player.lockOrientationImage, active: player.lockedOrientation != nil, action: player.lockOrientationAction)
|
||||
#endif
|
||||
case .restart:
|
||||
actionButton("Replay", systemImage: "backward.end.fill", action: player.replayAction)
|
||||
case .advanceToNextItem:
|
||||
actionButton("Next", systemImage: "forward.fill") {
|
||||
player.advanceToNextItem()
|
||||
}
|
||||
case .musicMode:
|
||||
actionButton("Music", systemImage: "music.note", active: player.musicMode, action: player.toggleMusicMode)
|
||||
|
||||
case .settings:
|
||||
actionButton("Settings", systemImage: "gear") {
|
||||
withAnimation(ControlOverlaysModel.animation) {
|
||||
@ -138,15 +185,17 @@ struct VideoActions: View {
|
||||
func actionButton(
|
||||
_ name: String,
|
||||
systemImage: String,
|
||||
active: Bool = false,
|
||||
action: @escaping () -> Void = {}
|
||||
) -> some View {
|
||||
Button(action: action) {
|
||||
VStack(spacing: 3) {
|
||||
Image(systemName: systemImage)
|
||||
.frame(width: 20, height: 20)
|
||||
.foregroundColor(active ? Color("AppRedColor") : .accentColor)
|
||||
if playerActionsButtonLabelStyle.text {
|
||||
Text(name.localized())
|
||||
.foregroundColor(.secondary)
|
||||
.foregroundColor(active ? Color("AppRedColor") : .secondary)
|
||||
.font(.caption2)
|
||||
.allowsTightening(true)
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ struct VideoDetails: View {
|
||||
|
||||
switch page {
|
||||
case .queue:
|
||||
return !player.queue.isEmpty
|
||||
return !sidebarQueue && player.isAdvanceToNextItemAvailable
|
||||
default:
|
||||
return !video.isLocal
|
||||
}
|
||||
|
@ -18,6 +18,12 @@ struct PlayerControlsSettings: View {
|
||||
@Default(.actionButtonCloseEnabled) private var actionButtonCloseEnabled
|
||||
@Default(.actionButtonAddToPlaylistEnabled) private var actionButtonAddToPlaylistEnabled
|
||||
@Default(.actionButtonSettingsEnabled) private var actionButtonSettingsEnabled
|
||||
@Default(.actionButtonFullScreenEnabled) private var actionButtonFullScreenEnabled
|
||||
@Default(.actionButtonPipEnabled) private var actionButtonPipEnabled
|
||||
@Default(.actionButtonLockOrientationEnabled) private var actionButtonLockOrientationEnabled
|
||||
@Default(.actionButtonRestartEnabled) private var actionButtonRestartEnabled
|
||||
@Default(.actionButtonAdvanceToNextItemEnabled) private var actionButtonAdvanceToNextItemEnabled
|
||||
@Default(.actionButtonMusicModeEnabled) private var actionButtonMusicModeEnabled
|
||||
@Default(.actionButtonHideEnabled) private var actionButtonHideEnabled
|
||||
|
||||
#if os(iOS)
|
||||
@ -211,6 +217,7 @@ struct PlayerControlsSettings: View {
|
||||
.labelStyle(.iconOnly)
|
||||
.padding(7)
|
||||
.foregroundColor(.accentColor)
|
||||
.accessibilityAddTraits(.isButton)
|
||||
#if os(iOS)
|
||||
.background(RoundedRectangle(cornerRadius: 4).strokeBorder(lineWidth: 1).foregroundColor(.accentColor))
|
||||
#endif
|
||||
@ -246,6 +253,7 @@ struct PlayerControlsSettings: View {
|
||||
.labelStyle(.iconOnly)
|
||||
.padding(7)
|
||||
.foregroundColor(.accentColor)
|
||||
.accessibilityAddTraits(.isButton)
|
||||
#if os(iOS)
|
||||
.frame(minHeight: 35)
|
||||
.background(RoundedRectangle(cornerRadius: 4).strokeBorder(lineWidth: 1).foregroundColor(.accentColor))
|
||||
@ -265,13 +273,25 @@ struct PlayerControlsSettings: View {
|
||||
}
|
||||
|
||||
@ViewBuilder private var actionButtonToggles: some View {
|
||||
Group {
|
||||
Toggle("Share", isOn: $actionButtonShareEnabled)
|
||||
Toggle("Add to Playlist", isOn: $actionButtonAddToPlaylistEnabled)
|
||||
Toggle("Subscribe/Unsubscribe", isOn: $actionButtonSubscribeEnabled)
|
||||
Toggle("Settings", isOn: $actionButtonSettingsEnabled)
|
||||
Toggle("Fullscreen", isOn: $actionButtonFullScreenEnabled)
|
||||
Toggle("Picture in Picture", isOn: $actionButtonPipEnabled)
|
||||
}
|
||||
Group {
|
||||
#if os(iOS)
|
||||
Toggle("Lock orientation", isOn: $actionButtonLockOrientationEnabled)
|
||||
#endif
|
||||
Toggle("Restart", isOn: $actionButtonRestartEnabled)
|
||||
Toggle("Play next item", isOn: $actionButtonAdvanceToNextItemEnabled)
|
||||
Toggle("Music Mode", isOn: $actionButtonMusicModeEnabled)
|
||||
Toggle("Hide player", isOn: $actionButtonHideEnabled)
|
||||
Toggle("Close video", isOn: $actionButtonCloseEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private var controlButtonToggles: some View {
|
||||
#if os(iOS)
|
||||
@ -283,9 +303,9 @@ struct PlayerControlsSettings: View {
|
||||
#endif
|
||||
Toggle("Restart", isOn: $playerControlsRestartEnabled)
|
||||
Toggle("Play next item", isOn: $playerControlsAdvanceToNextEnabled)
|
||||
Toggle("Playback mode", isOn: $playerControlsPlaybackModeEnabled)
|
||||
Toggle("Playback Mode", isOn: $playerControlsPlaybackModeEnabled)
|
||||
#if !os(tvOS)
|
||||
Toggle("Music mode", isOn: $playerControlsMusicModeEnabled)
|
||||
Toggle("Music Mode", isOn: $playerControlsMusicModeEnabled)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ struct SettingsView: View {
|
||||
case .player:
|
||||
return 450
|
||||
case .controls:
|
||||
return 850
|
||||
return 900
|
||||
case .quality:
|
||||
return 420
|
||||
case .history:
|
||||
|
Loading…
Reference in New Issue
Block a user