mirror of
https://github.com/yattee/yattee.git
synced 2026-05-12 10:25:02 +00:00
Add tvOS setting to close video with Menu button
When enabled, the Siri remote Menu button stops playback and clears the queue instead of only collapsing the player, and the explicit top-bar close (X) button is hidden.
This commit is contained in:
@@ -24,6 +24,7 @@ enum SettingsKey: String, CaseIterable {
|
||||
case preferredAudioLanguage
|
||||
case preferredSubtitlesLanguage
|
||||
case resumeAction
|
||||
case tvOSMenuButtonClosesVideo
|
||||
|
||||
// SponsorBlock
|
||||
case sponsorBlockEnabled
|
||||
|
||||
@@ -48,6 +48,20 @@ extension SettingsManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// tvOS only: when enabled, the Siri remote Menu button closes the video
|
||||
/// (clears queue, stops playback) instead of only collapsing the player.
|
||||
/// When enabled, the explicit top-bar close button is hidden.
|
||||
var tvOSMenuButtonClosesVideo: Bool {
|
||||
get {
|
||||
if let cached = _tvOSMenuButtonClosesVideo { return cached }
|
||||
return bool(for: .tvOSMenuButtonClosesVideo, default: false)
|
||||
}
|
||||
set {
|
||||
_tvOSMenuButtonClosesVideo = newValue
|
||||
set(newValue, for: .tvOSMenuButtonClosesVideo)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether DASH streams are enabled (MPV only).
|
||||
/// Disabled by default as DASH can be unreliable with some Invidious instances.
|
||||
var dashEnabled: Bool {
|
||||
|
||||
@@ -39,6 +39,7 @@ final class SettingsManager {
|
||||
var _preferredSubtitlesLanguage: String?
|
||||
var _playerVolume: Float?
|
||||
var _resumeAction: ResumeAction?
|
||||
var _tvOSMenuButtonClosesVideo: Bool?
|
||||
|
||||
// SponsorBlock
|
||||
var _sponsorBlockEnabled: Bool?
|
||||
@@ -410,6 +411,7 @@ final class SettingsManager {
|
||||
_preferredSubtitlesLanguage = nil
|
||||
_playerVolume = nil
|
||||
_resumeAction = nil
|
||||
_tvOSMenuButtonClosesVideo = nil
|
||||
_sponsorBlockEnabled = nil
|
||||
_sponsorBlockCategories = nil
|
||||
_sponsorBlockAPIURL = nil
|
||||
|
||||
@@ -11845,6 +11845,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.playback.tvOSMenuButtonClosesVideo" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Menu Button Closes Video"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.playback.tvOSMenuButtonClosesVideo.footer" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "When enabled, the Siri remote Menu button stops playback and clears the queue. The close (X) button is hidden from the player. When disabled, Menu collapses the player and playback continues in the background."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.playback.behavior.header" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
|
||||
@@ -170,15 +170,19 @@ struct TVPlayerControlsView: View {
|
||||
// Close button — stops playback and dismisses.
|
||||
// Menu button only hides the player (keeps background playback),
|
||||
// so an explicit Close is kept here, icon-only in the top bar.
|
||||
Button {
|
||||
onClose()
|
||||
} label: {
|
||||
Image(systemName: "xmark")
|
||||
.font(.system(size: 26, weight: .semibold))
|
||||
// When `tvOSMenuButtonClosesVideo` is enabled, the Menu button
|
||||
// takes over this role and the explicit button is hidden.
|
||||
if appEnvironment?.settingsManager.tvOSMenuButtonClosesVideo != true {
|
||||
Button {
|
||||
onClose()
|
||||
} label: {
|
||||
Image(systemName: "xmark")
|
||||
.font(.system(size: 26, weight: .semibold))
|
||||
}
|
||||
.buttonStyle(TVCloseButtonStyle())
|
||||
.focused($focusedControl, equals: .closeButton)
|
||||
.accessibilityLabel(Text("player.controls.close"))
|
||||
}
|
||||
.buttonStyle(TVCloseButtonStyle())
|
||||
.focused($focusedControl, equals: .closeButton)
|
||||
.accessibilityLabel(Text("player.controls.close"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -667,6 +667,9 @@ struct TVPlayerView: View {
|
||||
} else if controlsVisible {
|
||||
// Fifth: hide controls
|
||||
hideControls()
|
||||
} else if appEnvironment?.settingsManager.tvOSMenuButtonClosesVideo == true {
|
||||
// Sixth (Menu-closes mode): fully close the video like the xmark button
|
||||
closeVideo()
|
||||
} else {
|
||||
// Sixth: dismiss player (controls already hidden)
|
||||
dismissPlayer()
|
||||
|
||||
@@ -240,7 +240,7 @@ private struct BehaviorSection: View {
|
||||
@Bindable var settings: SettingsManager
|
||||
|
||||
var body: some View {
|
||||
Section(String(localized: "settings.playback.behavior.header")) {
|
||||
Section {
|
||||
PlatformMenuPicker(
|
||||
String(localized: "settings.playback.resumeAction"),
|
||||
selection: $settings.resumeAction
|
||||
@@ -256,6 +256,21 @@ private struct BehaviorSection: View {
|
||||
isOn: $settings.backgroundPlaybackEnabled
|
||||
)
|
||||
#endif
|
||||
|
||||
#if os(tvOS)
|
||||
Toggle(
|
||||
String(localized: "settings.playback.tvOSMenuButtonClosesVideo"),
|
||||
isOn: $settings.tvOSMenuButtonClosesVideo
|
||||
)
|
||||
#endif
|
||||
} header: {
|
||||
Text(String(localized: "settings.playback.behavior.header"))
|
||||
} footer: {
|
||||
#if os(tvOS)
|
||||
Text(String(localized: "settings.playback.tvOSMenuButtonClosesVideo.footer"))
|
||||
#else
|
||||
EmptyView()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user