fix(qconnect): align queue load payload and inbound diagnostics
cx
This commit is contained in:
3 files changed
+91
-8
No files matched your search
@@ -187,8 +187,7 @@ fn map_queue_command(command: &QueueCommand) -> Result<QConnectMessage, Protocol
|
||||
let shuffle_mode = optional_bool(&command.payload, "shuffle_mode", false);
|
||||
let context_uuid = optional_uuid_bytes(&command.payload, &["context_uuid"])?;
|
||||
let autoplay_reset = optional_bool(&command.payload, "autoplay_reset", false);
|
||||
let autoplay_loading =
|
||||
optional_bool(&command.payload, "autoplay_loading", autoplay_reset);
|
||||
let autoplay_loading = optional_bool(&command.payload, "autoplay_loading", false);
|
||||
|
||||
Ok(QConnectMessage {
|
||||
message_type: Some(QConnectMessageType::MessageTypeCtrlSrvrQueueLoadTracks as i32),
|
||||
@@ -1084,7 +1083,7 @@ mod tests {
|
||||
assert_eq!(load.shuffle_seed, Some(3344));
|
||||
assert_eq!(load.shuffle_pivot_index, Some(1));
|
||||
assert_eq!(load.autoplay_reset, Some(true));
|
||||
assert_eq!(load.autoplay_loading, Some(true));
|
||||
assert_eq!(load.autoplay_loading, Some(false));
|
||||
assert_eq!(
|
||||
load.queue_version_ref
|
||||
.as_ref()
|
||||
@@ -1100,6 +1099,37 @@ mod tests {
|
||||
assert_eq!(load.context_uuid.as_ref().map(|uuid| uuid.len()), Some(16));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn defaults_queue_load_tracks_autoplay_loading_to_false_when_omitted() {
|
||||
let command = QueueCommand::new(
|
||||
QueueCommandType::CtrlSrvrQueueLoadTracks,
|
||||
"f997cd72-d2ce-4121-a89b-75bf2be251ec",
|
||||
QueueVersion::new(3, 9),
|
||||
json!({
|
||||
"track_ids": [2001, 2002, 2003],
|
||||
"queue_position": 2,
|
||||
"shuffle_mode": false,
|
||||
"shuffle_pivot_index": 2,
|
||||
"context_uuid": "a3f7be0f-3854-44c6-9194-c93cedec322a",
|
||||
"autoplay_reset": true
|
||||
}),
|
||||
);
|
||||
|
||||
let payload = encode_queue_command_batch(&command).expect("batch payload");
|
||||
let decoded = QConnectMessages::decode(payload.as_slice()).expect("decode batch");
|
||||
let load = decoded.messages[0]
|
||||
.ctrl_srvr_queue_load_tracks
|
||||
.as_ref()
|
||||
.expect("queue load payload");
|
||||
|
||||
assert_eq!(load.queue_position, Some(2));
|
||||
assert_eq!(load.shuffle_mode, Some(false));
|
||||
assert_eq!(load.shuffle_pivot_index, Some(2));
|
||||
assert_eq!(load.autoplay_reset, Some(true));
|
||||
assert_eq!(load.autoplay_loading, Some(false));
|
||||
assert_eq!(load.context_uuid.as_ref().map(|uuid| uuid.len()), Some(16));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encodes_renderer_state_updated_report_with_queue_version() {
|
||||
let report = RendererReport::new(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, OnceLock},
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
@@ -12,7 +13,7 @@ use qconnect_app::{
|
||||
};
|
||||
use qconnect_transport_ws::{NativeWsTransport, WsTransportConfig};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use serde_json::{json, Value};
|
||||
use tauri::async_runtime::JoinHandle;
|
||||
use tauri::{AppHandle, Emitter, State};
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
@@ -308,6 +309,38 @@ struct QconnectRemoteSyncState {
|
||||
session: QconnectSessionState,
|
||||
}
|
||||
|
||||
fn queue_payload_track_preview(payload: &Value, key: &str) -> Vec<i64> {
|
||||
payload
|
||||
.get(key)
|
||||
.and_then(Value::as_array)
|
||||
.map(|tracks| {
|
||||
tracks
|
||||
.iter()
|
||||
.filter_map(|track| track.get("track_id").and_then(Value::as_i64))
|
||||
.take(8)
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn emit_qconnect_diagnostic(app_handle: &AppHandle, channel: &str, level: &str, payload: Value) {
|
||||
let ts = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.map(|duration| duration.as_millis() as u64)
|
||||
.unwrap_or(0);
|
||||
if let Err(err) = app_handle.emit(
|
||||
"qconnect:diagnostic",
|
||||
json!({
|
||||
"ts": ts,
|
||||
"channel": channel,
|
||||
"level": level,
|
||||
"payload": payload,
|
||||
}),
|
||||
) {
|
||||
log::warn!("[QConnect] Failed to emit diagnostic {channel}: {err}");
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct QconnectSessionState {
|
||||
pub session_uuid: Option<String>,
|
||||
@@ -587,6 +620,20 @@ impl QconnectServiceState {
|
||||
}
|
||||
qconnect_transport_ws::TransportEvent::InboundQueueServerEvent(evt) => {
|
||||
log::info!("[QConnect] <-- Inbound queue event: {} payload={}", evt.message_type(), evt.payload);
|
||||
emit_qconnect_diagnostic(
|
||||
&app_for_errors,
|
||||
"qconnect:inbound_queue_event",
|
||||
"info",
|
||||
json!({
|
||||
"message_type": evt.message_type(),
|
||||
"action_uuid": evt.action_uuid.clone(),
|
||||
"queue_version": evt.queue_version,
|
||||
"track_count": evt.payload.get("tracks").and_then(|value| value.as_array()).map(|tracks| tracks.len()).unwrap_or(0),
|
||||
"autoplay_track_count": evt.payload.get("autoplay_tracks").and_then(|value| value.as_array()).map(|tracks| tracks.len()).unwrap_or(0),
|
||||
"preview_track_ids": queue_payload_track_preview(&evt.payload, "tracks"),
|
||||
"preview_autoplay_track_ids": queue_payload_track_preview(&evt.payload, "autoplay_tracks"),
|
||||
}),
|
||||
);
|
||||
}
|
||||
qconnect_transport_ws::TransportEvent::InboundRendererServerCommand(cmd) => {
|
||||
log::info!("[QConnect] <-- Inbound renderer command: {} payload={}", cmd.message_type(), cmd.payload);
|
||||
|
||||
@@ -530,17 +530,23 @@ export async function loadQconnectQueue(
|
||||
}
|
||||
|
||||
try {
|
||||
const normalizedStartIndex = Math.max(0, Math.min(startIndex, Math.max(trackIds.length - 1, 0)));
|
||||
const shuffleSeed = shuffleMode
|
||||
? Math.floor(Math.random() * 0x1_0000_0000)
|
||||
: undefined;
|
||||
const payload = {
|
||||
track_ids: trackIds,
|
||||
queue_position: startIndex,
|
||||
queue_position: shuffleMode ? 0 : normalizedStartIndex,
|
||||
shuffle_seed: shuffleSeed,
|
||||
shuffle_pivot_index: normalizedStartIndex,
|
||||
shuffle_mode: shuffleMode,
|
||||
context_uuid: crypto.randomUUID(),
|
||||
autoplay_reset: true,
|
||||
autoplay_loading: true
|
||||
autoplay_loading: false
|
||||
};
|
||||
await emitQconnectDiagnostic('qconnect:queue_load_tracks', 'info', {
|
||||
track_count: trackIds.length,
|
||||
start_index: startIndex,
|
||||
start_index: normalizedStartIndex,
|
||||
shuffle_mode: shuffleMode,
|
||||
preview_track_ids: trackIds.slice(0, 8),
|
||||
payload
|
||||
@@ -550,7 +556,7 @@ export async function loadQconnectQueue(
|
||||
console.log('[QConnect/LoadQueue] SUCCESS');
|
||||
await emitQconnectDiagnostic('qconnect:queue_load_sent', 'info', {
|
||||
track_count: trackIds.length,
|
||||
start_index: startIndex,
|
||||
start_index: normalizedStartIndex,
|
||||
shuffle_mode: shuffleMode,
|
||||
preview_track_ids: trackIds.slice(0, 8)
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user