fix: skip CoreBridge actions for echo SET_STATE commands
The server echoes every state report as a SET_STATE with only next_track (playing_state=null, current_track=null). These echoes were triggering align_corebridge_queue_cursor which uses the accumulated renderer state current_track (from a different context, e.g. iOS). When the track wasn't found in the local queue, it replaced the entire queue with a single track, destroying the user's loaded queue. Now echo SET_STATE commands are detected early and only update the internal renderer state (for next_track tracking). CoreBridge actions (align cursor, load track, play/pause) and state reports are skipped entirely for these echoes.
This commit is contained in:
1 file changed
+22
@@ -313,16 +313,38 @@ where
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
// Detect echo SET_STATE commands: the server echoes every state report
|
||||
// as a SET_STATE with only next_track (playing_state=None, current_track=None).
|
||||
// These echoes must NOT trigger CoreBridge actions (align cursor, load track,
|
||||
// resume/pause) or state reports, otherwise they destroy the local queue
|
||||
// and cause feedback loops.
|
||||
let is_echo = matches!(
|
||||
&renderer_command,
|
||||
RendererCommand::SetState {
|
||||
playing_state,
|
||||
current_track,
|
||||
..
|
||||
} if playing_state.is_none() && current_track.is_none()
|
||||
);
|
||||
|
||||
let (snapshot, queue_version) = {
|
||||
let mut state = self.state.lock().await;
|
||||
apply_renderer_command(&mut state.renderer, &renderer_command, now_ms());
|
||||
(state.renderer.clone(), state.queue.version)
|
||||
};
|
||||
|
||||
// Always update renderer state (for tracking next_track etc.)
|
||||
self.sink
|
||||
.on_event(QconnectAppEvent::RendererUpdated(snapshot.clone()))
|
||||
.await;
|
||||
|
||||
if is_echo {
|
||||
log::debug!(
|
||||
"[QConnect] Skipping echo SET_STATE (no playing_state or current_track)"
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.sink
|
||||
.on_event(QconnectAppEvent::RendererCommandApplied {
|
||||
command: renderer_command.clone(),
|
||||
|
||||
Reference in new issue
Block a user