Files
qbz/crates/qconnect-protocol
vicrodh b4c3bab91b fix(qconnect): WS-authoritative shuffle/repeat gating, button reflection, pause-to-iOS
Shuffle and Repeat now go to the CLOUD whenever connected (renderer OR controller),
gating on transport_connected like Tauri's v2_toggle_shuffle / v2_set_repeat_mode,
instead of the old peer-active gate that fell through to a LOCAL reshuffle when QBZ
was the active renderer — that did nothing visible AND risked a divergent local
order. QBZ sends only the seed + pivot; the cloud owns the order; the toggle reads
the cloud-authoritative queue.shuffle_mode. The local shuffle path is now reachable
only when NOT connected.

- shuffle/repeat button reflects the cloud queue flag (queue.shuffle_mode for the
  controller branch, core queue state via refresh_transport_modes for the renderer
  branch), not the per-renderer field the cloud never populates for a peer — fixes
  the iOS-reflects / WebPlayer-doesn't asymmetry.
- pause/play to a peer renderer: send a BARE SetPlayerState (playing_state only).
  iOS reports current_queue_item_id=null while playing, so resolving the qid landed
  on queue_item_id 0 — the protocol's "unknown" placeholder — and iOS could not
  anchor the pause, auto-resuming. A bare transport toggle is spec-sanctioned: the
  renderer pauses/resumes its own current item in place.
- skip_serializing_if on the SetPlayerState request structs so a None field is
  OMITTED, not serialized as null; and the mapper now treats a null current_queue_item
  as absent. Without this the bare command failed to encode and was never sent.
- log the outbound SetPlayerState payload for controller diagnostics.

cc
2026-06-05 17:44:11 -06:00
..