quick fix
NowPlayingView.swift — The _radioProgressBarImpl stub I left as a “reference” comment block was still compiled by Swift and referenced isDraggingSlider, dragPosition, and playbackTime which no longer exist on NowPlayingView. Removed the entire stub. Also transportControls had one remaining playbackTime reference — replaced with audioPlayer.currentTime directly since transport controls genuinely need the current position for the timeshift enable/disable logic and don’t cause a body re-eval issue there. NavidromeWatchApp.swift — syncLibrary() is declared async not async throws, so try? was redundant. Removed it.
This commit is contained in:
parent
9add1e014a
commit
758d7a5ebd
2 changed files with 2 additions and 100 deletions
|
|
@ -821,104 +821,6 @@ struct NowPlayingView: View {
|
|||
NowPlayingSeekBar(audioPlayer: audioPlayer, radioBuffer: radioBuffer, accentColor: accentPink)
|
||||
}
|
||||
|
||||
// Radio progress bar implementation moved into NowPlayingSeekBar to keep
|
||||
// currentTime reads scoped to the child view. This stub preserved for reference.
|
||||
private var _radioProgressBarImpl: some View {
|
||||
VStack(spacing: 6) {
|
||||
if radioBuffer.isHLSStream {
|
||||
// HLS: fully greyed, no scrubber thumb, no time labels
|
||||
Capsule()
|
||||
.fill(Color.white.opacity(0.08))
|
||||
.frame(height: 4)
|
||||
HStack {
|
||||
Text("--:--")
|
||||
.font(.system(size: 11, weight: .medium))
|
||||
.foregroundColor(.gray.opacity(0.35))
|
||||
Spacer()
|
||||
Text("--:--")
|
||||
.font(.system(size: 11))
|
||||
.foregroundColor(.gray.opacity(0.35))
|
||||
}
|
||||
} else if radioBuffer.isBuffering {
|
||||
GeometryReader { geo in
|
||||
let bufferSec = radioBuffer.estimatedBufferSeconds
|
||||
let maxSec = radioBuffer.maxBufferDuration
|
||||
let fillPct = min(max(bufferSec / maxSec, 0), 1.0)
|
||||
|
||||
let playheadPct: CGFloat = {
|
||||
if isDraggingSlider { return dragPosition }
|
||||
if audioPlayer.isPlayingFromBuffer {
|
||||
return CGFloat(min(playbackTime / maxSec, fillPct))
|
||||
}
|
||||
return fillPct
|
||||
}()
|
||||
|
||||
ZStack(alignment: .leading) {
|
||||
Capsule().fill(Color.white.opacity(0.1)).frame(height: 4)
|
||||
Capsule().fill(accentPink.opacity(0.3))
|
||||
.frame(width: geo.size.width * fillPct, height: 4)
|
||||
Circle()
|
||||
.fill(radioBuffer.isLive ? accentPink : Color.white)
|
||||
.frame(width: isDraggingSlider ? 16 : 12,
|
||||
height: isDraggingSlider ? 16 : 12)
|
||||
.offset(x: geo.size.width * playheadPct - (isDraggingSlider ? 8 : 6))
|
||||
.animation(.interactiveSpring(), value: isDraggingSlider)
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.gesture(
|
||||
DragGesture(minimumDistance: 8)
|
||||
.onChanged { v in
|
||||
isDraggingSlider = true
|
||||
let pct = min(max(v.location.x / geo.size.width, 0), fillPct)
|
||||
dragPosition = pct
|
||||
}
|
||||
.onEnded { v in
|
||||
isDraggingSlider = false
|
||||
let pct = min(max(v.location.x / geo.size.width, 0), fillPct)
|
||||
let seekPos = pct * maxSec
|
||||
audioPlayer.radioSeekBack(to: seekPos)
|
||||
}
|
||||
)
|
||||
}
|
||||
.frame(height: 24)
|
||||
|
||||
HStack {
|
||||
if isDraggingSlider {
|
||||
let dragPosSec = dragPosition * radioBuffer.maxBufferDuration
|
||||
let behindLive = max(0, radioBuffer.estimatedBufferSeconds - dragPosSec)
|
||||
Text(behindLive < 1 ? "LIVE" : "-" + formatTime(behindLive))
|
||||
.font(.system(size: 11, weight: .medium))
|
||||
.foregroundColor(behindLive < 1 ? accentPink : .gray)
|
||||
} else if radioBuffer.isLive {
|
||||
Text("LIVE")
|
||||
.font(.system(size: 11, weight: .semibold))
|
||||
.foregroundColor(accentPink)
|
||||
} else {
|
||||
let behindLive = max(0, radioBuffer.estimatedBufferSeconds - playbackTime)
|
||||
Text("-" + formatTime(behindLive))
|
||||
.font(.system(size: 11, weight: .medium))
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
Spacer()
|
||||
Text(formatTime(radioBuffer.bufferedDuration))
|
||||
.font(.system(size: 11))
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
} else {
|
||||
// Buffer not yet ready — greyed static bar (brief state on auto-start)
|
||||
Capsule()
|
||||
.fill(Color.white.opacity(0.1))
|
||||
.frame(height: 4)
|
||||
HStack {
|
||||
Text("Buffering...")
|
||||
.font(.system(size: 11, weight: .medium))
|
||||
.foregroundColor(.gray.opacity(0.5))
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Transport Controls
|
||||
|
||||
private var transportControls: some View {
|
||||
|
|
@ -927,7 +829,7 @@ struct NowPlayingView: View {
|
|||
|
||||
// Dynamic disable states (Feature 2)
|
||||
let bufferSec = radioBuffer.estimatedBufferSeconds
|
||||
let currentPos: TimeInterval = audioPlayer.isPlayingFromBuffer ? playbackTime : bufferSec
|
||||
let currentPos: TimeInterval = audioPlayer.isPlayingFromBuffer ? audioPlayer.currentTime : bufferSec
|
||||
let secondsBehindLive = bufferSec - currentPos
|
||||
let canRewind30 = !radioBuffer.isHLSStream && bufferSec >= 30
|
||||
let canForward15 = !radioBuffer.isHLSStream && secondsBehindLive >= 15
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class NavidromeWatchDelegate: NSObject, WKApplicationDelegate {
|
|||
// Opportunity for a lightweight library metadata refresh.
|
||||
Task {
|
||||
if WatchSessionManager.shared.activeServer != nil {
|
||||
try? await WatchSessionManager.shared.syncLibrary()
|
||||
await WatchSessionManager.shared.syncLibrary()
|
||||
}
|
||||
refreshTask.setTaskCompletedWithSnapshot(false)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue