From 40a2fa618eea08ee6101ed10184d8f6da3f6906c Mon Sep 17 00:00:00 2001 From: vicrodh <103399283+vicrodh@users.noreply.github.com> Date: Sun, 22 Feb 2026 15:18:35 -0600 Subject: [PATCH] fix: omit queue_item_ids from renderer state reports to fix seekbar sync The server rejects renderer state reports with "Current track not found in queue nor autoplay" after QBZ-initiated queue loads, because it assigns non-standard queue_item_ids (first track = track_id, rest = 1..N). Omit current_queue_item_id and next_queue_item_id from all outbound renderer reports. The server already knows the current track from SET_STATE commands and adds the correct queue_item_id when forwarding to controllers. Also add info-level diagnostic logging to both report paths (periodic frontend reports and command-response reports) and the protobuf encoder for verifying wire content. --- crates/qconnect-app/Cargo.toml | 1 + crates/qconnect-app/src/app.rs | 19 +++++++++++++++++-- crates/qconnect-protocol/src/mapper.rs | 19 +++++++++++++------ src-tauri/src/qconnect_service.rs | 19 +++++++++++++++++-- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/crates/qconnect-app/Cargo.toml b/crates/qconnect-app/Cargo.toml index c8e1e6142..39bc96fea 100644 --- a/crates/qconnect-app/Cargo.toml +++ b/crates/qconnect-app/Cargo.toml @@ -15,6 +15,7 @@ serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } uuid = { version = "1", features = ["v4"] } +log = { workspace = true } [dev-dependencies] tokio = { workspace = true, features = ["test-util"] } diff --git a/crates/qconnect-app/src/app.rs b/crates/qconnect-app/src/app.rs index 595291c89..5f6efc7c4 100644 --- a/crates/qconnect-app/src/app.rs +++ b/crates/qconnect-app/src/app.rs @@ -416,10 +416,25 @@ where ) -> Result<(), QconnectAppError> { match command { RendererCommand::SetState { .. } => { + log::info!( + "[QConnect/Report] SetState report: playing={:?} pos={:?} track={:?} next={:?} qv={}.{}", + renderer.playing_state, + renderer.current_position_ms, + renderer.current_track.as_ref().map(|t| (t.track_id, t.queue_item_id)), + renderer.next_track.as_ref().map(|t| (t.track_id, t.queue_item_id)), + queue_version_ref.major, + queue_version_ref.minor + ); let report = RendererReport::new( RendererReportType::RndrSrvrStateUpdated, self.next_action_uuid(), queue_version_ref, + // NOTE: We intentionally OMIT current_queue_item_id and next_queue_item_id. + // The server validates these IDs against its queue state and rejects reports + // when IDs don't match ("Current track not found in queue nor autoplay"). + // This happens after QBZ-initiated queue loads where the server assigns + // non-standard queue_item_ids (first track = track_id, rest = 1..N). + // The server already knows the current track from SET_STATE commands. serde_json::json!({ "playing_state": renderer.playing_state, "buffer_state": infer_buffer_state(renderer.playing_state), @@ -429,8 +444,8 @@ where "major": queue_version_ref.major, "minor": queue_version_ref.minor }, - "current_queue_item_id": renderer.current_track.as_ref().map(|item| item.queue_item_id), - "next_queue_item_id": renderer.next_track.as_ref().map(|item| item.queue_item_id) + "current_queue_item_id": Option::::None, + "next_queue_item_id": Option::::None }), ); self.send_renderer_report(report).await?; diff --git a/crates/qconnect-protocol/src/mapper.rs b/crates/qconnect-protocol/src/mapper.rs index 0422f35ae..1382877ce 100644 --- a/crates/qconnect-protocol/src/mapper.rs +++ b/crates/qconnect-protocol/src/mapper.rs @@ -424,25 +424,32 @@ fn map_renderer_report(report: &RendererReport) -> Result