mirror of
https://github.com/yattee/yattee.git
synced 2026-07-20 14:22:02 +00:00
Make seek durations configurable in Playback menu and add secondary seek
Playback menu seek items now follow the durations from the active player controls preset instead of hardcoded 10s/30s labels. AppEnvironment caches the active preset's center settings (refreshed on preset change notifications) so menu commands can read them synchronously. Add secondary seek durations (default 30s) to CenterSectionSettings, configurable on macOS in Seek Durations settings, used by Shift+arrows in the player and Cmd+Shift+arrows in the Playback menu. Also let Cmd-based key equivalents pass through the player keyboard monitor so menu shortcuts (e.g. Cmd+Option+arrow previous/next video) work while the player window has focus, and unify macOS built-in preset primary seek at 10s to match iOS/tvOS (built-in presets version 8).
This commit is contained in:
@@ -56,6 +56,13 @@ final class AppEnvironment {
|
||||
let legacyMigrationService: LegacyDataMigrationService
|
||||
let sourcesSettings: SourcesSettings
|
||||
|
||||
/// Center-section settings of the active player controls preset, cached for
|
||||
/// synchronous access. Menu bar commands read seek durations from here since
|
||||
/// they cannot await the layout service actor.
|
||||
private(set) var activeControlsCenterSettings: CenterSectionSettings = .default
|
||||
|
||||
@ObservationIgnored private var controlsSettingsObservers: [NSObjectProtocol] = []
|
||||
|
||||
// MARK: - Shared Instance
|
||||
|
||||
/// The single, process-wide app environment.
|
||||
@@ -311,6 +318,18 @@ final class AppEnvironment {
|
||||
// Wire up player controls layout service to player service (for preset-based settings)
|
||||
player.setPlayerControlsLayoutService(layoutService)
|
||||
|
||||
// Cache active preset's center settings and keep them in sync
|
||||
Task { await self.refreshActiveControlsSettings() }
|
||||
for name: Notification.Name in [.playerControlsActivePresetDidChange, .playerControlsPresetsDidChange] {
|
||||
controlsSettingsObservers.append(
|
||||
NotificationCenter.default.addObserver(forName: name, object: nil, queue: .main) { [weak self] _ in
|
||||
Task { @MainActor in
|
||||
await self?.refreshActiveControlsSettings()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Set up circular dependencies after all properties are initialized
|
||||
bgRefreshManager.setAppEnvironment(self)
|
||||
|
||||
@@ -350,6 +369,12 @@ final class AppEnvironment {
|
||||
|
||||
// MARK: - Configuration
|
||||
|
||||
/// Refreshes the cached center-section settings from the active player controls preset.
|
||||
func refreshActiveControlsSettings() async {
|
||||
let layout = await playerControlsLayoutService.activeLayout()
|
||||
activeControlsCenterSettings = layout.centerSettings
|
||||
}
|
||||
|
||||
/// Updates the HTTP client's User-Agent configuration from current settings.
|
||||
/// Call this after changing User-Agent related settings.
|
||||
func updateUserAgent() {
|
||||
|
||||
@@ -50,10 +50,10 @@ struct PlaybackCommands: Commands {
|
||||
Divider()
|
||||
|
||||
// Seeking
|
||||
seekBackward10Button
|
||||
seekForward10Button
|
||||
seekBackward30Button
|
||||
seekForward30Button
|
||||
seekBackwardButton
|
||||
seekForwardButton
|
||||
secondarySeekBackwardButton
|
||||
secondarySeekForwardButton
|
||||
|
||||
Divider()
|
||||
|
||||
@@ -121,41 +121,59 @@ struct PlaybackCommands: Commands {
|
||||
|
||||
// MARK: - Seeking
|
||||
|
||||
private var seekBackward10Button: some View {
|
||||
/// Seek durations follow the active player controls preset, matching the
|
||||
/// in-player arrow key shortcuts.
|
||||
private var seekBackwardSeconds: Int {
|
||||
appEnvironment.activeControlsCenterSettings.seekBackwardSeconds
|
||||
}
|
||||
|
||||
private var seekForwardSeconds: Int {
|
||||
appEnvironment.activeControlsCenterSettings.seekForwardSeconds
|
||||
}
|
||||
|
||||
private var seekBackwardButton: some View {
|
||||
Button {
|
||||
playerService.seekBackward(by: 10)
|
||||
playerService.seekBackward(by: TimeInterval(seekBackwardSeconds))
|
||||
} label: {
|
||||
Text(String(localized: "menu.playback.seekBackward10"))
|
||||
Text(String(localized: "menu.playback.seekBackward \(seekBackwardSeconds)"))
|
||||
}
|
||||
.keyboardShortcut(.leftArrow, modifiers: [.command])
|
||||
.disabled(!hasActiveVideo)
|
||||
}
|
||||
|
||||
private var seekForward10Button: some View {
|
||||
private var seekForwardButton: some View {
|
||||
Button {
|
||||
playerService.seekForward(by: 10)
|
||||
playerService.seekForward(by: TimeInterval(seekForwardSeconds))
|
||||
} label: {
|
||||
Text(String(localized: "menu.playback.seekForward10"))
|
||||
Text(String(localized: "menu.playback.seekForward \(seekForwardSeconds)"))
|
||||
}
|
||||
.keyboardShortcut(.rightArrow, modifiers: [.command])
|
||||
.disabled(!hasActiveVideo)
|
||||
}
|
||||
|
||||
private var seekBackward30Button: some View {
|
||||
private var secondarySeekBackwardSeconds: Int {
|
||||
appEnvironment.activeControlsCenterSettings.secondarySeekBackwardSeconds
|
||||
}
|
||||
|
||||
private var secondarySeekForwardSeconds: Int {
|
||||
appEnvironment.activeControlsCenterSettings.secondarySeekForwardSeconds
|
||||
}
|
||||
|
||||
private var secondarySeekBackwardButton: some View {
|
||||
Button {
|
||||
playerService.seekBackward(by: 30)
|
||||
playerService.seekBackward(by: TimeInterval(secondarySeekBackwardSeconds))
|
||||
} label: {
|
||||
Text(String(localized: "menu.playback.seekBackward30"))
|
||||
Text(String(localized: "menu.playback.seekBackward \(secondarySeekBackwardSeconds)"))
|
||||
}
|
||||
.keyboardShortcut(.leftArrow, modifiers: [.command, .shift])
|
||||
.disabled(!hasActiveVideo)
|
||||
}
|
||||
|
||||
private var seekForward30Button: some View {
|
||||
private var secondarySeekForwardButton: some View {
|
||||
Button {
|
||||
playerService.seekForward(by: 30)
|
||||
playerService.seekForward(by: TimeInterval(secondarySeekForwardSeconds))
|
||||
} label: {
|
||||
Text(String(localized: "menu.playback.seekForward30"))
|
||||
Text(String(localized: "menu.playback.seekForward \(secondarySeekForwardSeconds)"))
|
||||
}
|
||||
.keyboardShortcut(.rightArrow, modifiers: [.command, .shift])
|
||||
.disabled(!hasActiveVideo)
|
||||
|
||||
Reference in New Issue
Block a user