fix: keep seek target visible until acknowledged and make volume thumb opaque
This commit is contained in:
@@ -28,6 +28,7 @@ final class PlayerModel: ObservableObject {
|
||||
private var windowActive = true
|
||||
private var lastAudibleVolume = 1.0
|
||||
private var needsVideoFit = false
|
||||
private var seekPending = false
|
||||
|
||||
private init() {
|
||||
let player = player_create()
|
||||
@@ -100,6 +101,7 @@ final class PlayerModel: ObservableObject {
|
||||
needsVideoFit = true
|
||||
commandError = nil
|
||||
isSeeking = false
|
||||
seekPending = false
|
||||
seekPosition = 0
|
||||
window?.representedURL = url
|
||||
window?.title = url.lastPathComponent
|
||||
@@ -117,7 +119,9 @@ final class PlayerModel: ObservableObject {
|
||||
isSeeking = false
|
||||
guard let handle, canSeek else { return }
|
||||
let position = min(max(0, seekPosition), duration)
|
||||
commandError = player_seek(handle, position) ? nil : "Could not queue the seek. Please try again."
|
||||
let accepted = player_seek(handle, position)
|
||||
if accepted { seekPending = true }
|
||||
commandError = accepted ? nil : "Could not queue the seek. Please try again."
|
||||
revealControls()
|
||||
}
|
||||
|
||||
@@ -133,6 +137,7 @@ final class PlayerModel: ObservableObject {
|
||||
window?.aspectRatio = .zero
|
||||
commandError = nil
|
||||
isSeeking = false
|
||||
seekPending = false
|
||||
window?.representedURL = nil
|
||||
window?.title = "Player"
|
||||
revealControls()
|
||||
@@ -140,9 +145,13 @@ final class PlayerModel: ObservableObject {
|
||||
|
||||
func seekRelative(_ seconds: Double) {
|
||||
guard canSeek, let handle else { return }
|
||||
let target = min(max(0, state.position + seconds), duration)
|
||||
commandError = player_seek(handle, target) ? nil : "Could not queue the seek. Please try again."
|
||||
seekPosition = target
|
||||
let target = min(max(0, (seekPending ? seekPosition : state.position) + seconds), duration)
|
||||
let accepted = player_seek(handle, target)
|
||||
if accepted {
|
||||
seekPosition = target
|
||||
seekPending = true
|
||||
}
|
||||
commandError = accepted ? nil : "Could not queue the seek. Please try again."
|
||||
revealControls()
|
||||
}
|
||||
|
||||
@@ -234,7 +243,7 @@ final class PlayerModel: ObservableObject {
|
||||
|
||||
private var shouldHideControls: Bool {
|
||||
canTogglePlayback && state.has_video && fileName != nil &&
|
||||
!isSeeking && !controlsHovered && !titleHovered && !controlsDragging &&
|
||||
!isSeeking && !seekPending && !controlsHovered && !titleHovered && !controlsDragging &&
|
||||
windowActive && errorText == nil &&
|
||||
!NSWorkspace.shared.isVoiceOverEnabled
|
||||
}
|
||||
@@ -265,14 +274,18 @@ final class PlayerModel: ObservableObject {
|
||||
|
||||
private func poll() {
|
||||
guard let handle else { return }
|
||||
let next = player_get_state(handle)
|
||||
applyState(player_get_state(handle))
|
||||
}
|
||||
|
||||
func applyState(_ next: PlayerState) {
|
||||
if let revision = pendingRevision {
|
||||
guard next.revision != revision, next.status != PLAYER_OPENING else { return }
|
||||
pendingRevision = nil
|
||||
}
|
||||
let statusChanged = state.status != next.status
|
||||
state = next
|
||||
if !isSeeking {
|
||||
if !next.seek_pending || next.status == PLAYER_ERROR { seekPending = false }
|
||||
if !isSeeking && !seekPending {
|
||||
seekPosition = min(max(0, next.position.isFinite ? next.position : 0), duration)
|
||||
}
|
||||
fitVideoWindow()
|
||||
@@ -379,7 +392,9 @@ private struct PlaybackSlider: NSViewRepresentable {
|
||||
let width: CGFloat = volume ? 16 : 3
|
||||
let height: CGFloat = volume ? 12 : 15
|
||||
let knob = NSRect(x: rect.midX - width / 2, y: rect.midY - height / 2, width: width, height: height)
|
||||
NSColor.white.withAlphaComponent(isEnabled ? 0.65 : 0.25).setFill()
|
||||
let color = volume ? NSColor(white: isEnabled ? 0.85 : 0.45, alpha: 1)
|
||||
: NSColor.white.withAlphaComponent(isEnabled ? 0.65 : 0.25)
|
||||
color.setFill()
|
||||
NSBezierPath(roundedRect: knob, xRadius: volume ? 6 : 1, yRadius: volume ? 6 : 1).fill()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user