fix(playback): harden idle queue and gapless transitions
cx
This commit is contained in:
8 files changed
+178
-17
No files matched your search
@@ -70,6 +70,7 @@ Rectangle {
|
||||
readonly property int timeFont: root.compactMode ? 10 : 11
|
||||
|
||||
readonly property bool hasTrack: QbzPlayer.npHasTrack
|
||||
readonly property bool canPlay: root.hasTrack || QbzQueue.hasPlayTarget
|
||||
|
||||
// --- The pending-seek machine (:214-249) -------------------------------
|
||||
// All three constants are load-bearing: the -1.0 SENTINEL (every test is
|
||||
@@ -273,6 +274,7 @@ Rectangle {
|
||||
icSkip: root.icSkip
|
||||
icPlay: root.icPlay
|
||||
btnEnabled: root.hasTrack
|
||||
playEnabled: root.canPlay
|
||||
}
|
||||
|
||||
// The capsule (:322-327): right-aligned, vertically centred
|
||||
@@ -394,6 +396,7 @@ Rectangle {
|
||||
icSkip: 9
|
||||
icPlay: 9
|
||||
btnEnabled: root.hasTrack
|
||||
playEnabled: root.canPlay
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@ Row {
|
||||
property int gap: 18
|
||||
/// Gated on `NowPlayingState.has-track` by the footer (:315).
|
||||
property bool btnEnabled: true
|
||||
/// Play additionally accepts an idle, populated queue. The other four
|
||||
/// controls remain tied to a real current track.
|
||||
property bool playEnabled: root.btnEnabled
|
||||
|
||||
spacing: root.gap
|
||||
|
||||
@@ -50,7 +53,7 @@ Row {
|
||||
name: QbzPlayer.npPlaying ? "pause" : "play-fill"
|
||||
iconSize: root.icPlay
|
||||
btn: root.btn
|
||||
btnEnabled: root.btnEnabled
|
||||
btnEnabled: root.playEnabled
|
||||
onClicked: QbzPlayer.togglePlay()
|
||||
}
|
||||
TBtn {
|
||||
|
||||
@@ -577,7 +577,7 @@ Rectangle {
|
||||
// (kiosk_nav_qt.rs:222-225).
|
||||
if (QbzKioskNav.zone === "player") {
|
||||
QbzKioskNav.markActive()
|
||||
if (QbzPlayer.npHasTrack)
|
||||
if (QbzPlayer.npHasTrack || QbzQueue.hasPlayTarget)
|
||||
QbzPlayer.togglePlay()
|
||||
} else if (QbzKioskNav.zone === "rail") {
|
||||
QbzKioskNav.markActive()
|
||||
|
||||
@@ -73,6 +73,10 @@ Row {
|
||||
// play. Not gated on `npHasTrack`: the first play of a session has no
|
||||
// track yet, and that is exactly the case that felt dead.
|
||||
readonly property bool loading: QbzPlayer.npLoading
|
||||
// Clear-while-paused removes the NPB cursor by design. Rows added
|
||||
// afterwards still make Play actionable: the backend promotes the first
|
||||
// one without resurrecting the cleared paused stream.
|
||||
readonly property bool playEnabled: QbzPlayer.npHasTrack || QbzQueue.hasPlayTarget
|
||||
// Spin phase, advanced on the shared shell pulse (QbzShell.pulseMs).
|
||||
property real spinPhase: 0
|
||||
Connections {
|
||||
@@ -94,10 +98,10 @@ Row {
|
||||
height: tc.playCircle ? 38 : 34
|
||||
radius: tc.playCircle ? width / 2 : theme.radiusSm
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
opacity: QbzPlayer.npHasTrack ? 1.0 : 0.3
|
||||
opacity: tc.playEnabled ? 1.0 : 0.3
|
||||
color: tc.playCircle
|
||||
? (playArea.containsMouse && QbzPlayer.npHasTrack ? theme.accentHover : theme.accent)
|
||||
: ((playArea.containsMouse && QbzPlayer.npHasTrack) ? theme.surfaceHover : "transparent")
|
||||
? (playArea.containsMouse && tc.playEnabled ? theme.accentHover : theme.accent)
|
||||
: ((playArea.containsMouse && tc.playEnabled) ? theme.surfaceHover : "transparent")
|
||||
QbzIcon {
|
||||
// Hidden while loading — the ring below stands in for it, so the
|
||||
// button never shows a play glyph for a track that is still being
|
||||
@@ -145,8 +149,8 @@ Row {
|
||||
id: playArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: QbzPlayer.npHasTrack ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: if (QbzPlayer.npHasTrack) QbzPlayer.togglePlay()
|
||||
cursorShape: tc.playEnabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: if (tc.playEnabled) QbzPlayer.togglePlay()
|
||||
}
|
||||
}
|
||||
QbzIconButton {
|
||||
|
||||
Reference in new issue
Block a user