Add queue refreshing indicator to UI

- Introduce `QueueRefreshing` event type for dedicated queue refresh state
- Add reactive tracking of refreshing queues via new `queueRefreshingIds` Set in useRenderers composable
- Display visual indicator (spinning icon + text) when queue is refreshing in QueueViewer component
- Update `picomatch` dependency to v4.0.4 (patch)
- Minor cleanup in package-lock.json files
This commit is contained in:
2026-04-03 20:45:35 +02:00
parent 494cc3b8e1
commit 2fd4c84e1a
9 changed files with 88 additions and 9 deletions

View File

@@ -1585,10 +1585,9 @@ fn refresh_attached_queue_for(
return Ok(());
}
// Step 3: Notify UI that the renderer is loading (Transitioning state)
event_bus.broadcast(RendererEvent::StateChanged {
// Step 3: Notify UI that the queue is being refreshed (dedicated event, no state change)
event_bus.broadcast(RendererEvent::QueueRefreshing {
id: renderer_id.clone(),
state: PlaybackState::Transitioning,
});
// Step 4: Browse container (renamed from Step 3 for clarity)

View File

@@ -434,6 +434,9 @@ pub enum RendererEvent {
id: DeviceId,
queue_length: usize,
},
QueueRefreshing {
id: DeviceId,
},
BindingChanged {
id: DeviceId,
binding: Option<PlaylistBinding>,

View File

@@ -647,6 +647,17 @@ impl OpenHomeQueue {
let snapshot = self.queue_snapshot()?;
let current_track_ids = self.track_ids()?;
debug!(
renderer = self.renderer_id.0.as_str(),
current_count = snapshot.items.len(),
desired_count = items.len(),
current_uris = ?snapshot.items.iter().map(|i| i.uri.as_str()).collect::<Vec<_>>(),
current_didl_ids = ?snapshot.items.iter().map(|i| i.didl_id.as_str()).collect::<Vec<_>>(),
desired_uris = ?items.iter().map(|i| i.uri.as_str()).collect::<Vec<_>>(),
desired_didl_ids = ?items.iter().map(|i| i.didl_id.as_str()).collect::<Vec<_>>(),
"LCS input: current vs desired items"
);
let (keep_current, keep_desired) = lcs_flags(&snapshot.items, &items);
let items_to_keep = keep_current.iter().filter(|&&k| k).count();

View File

@@ -79,6 +79,10 @@ pub enum RendererEventPayload {
queue_length: usize,
timestamp: chrono::DateTime<chrono::Utc>,
},
QueueRefreshing {
renderer_id: String,
timestamp: chrono::DateTime<chrono::Utc>,
},
BindingChanged {
renderer_id: String,
server_id: Option<String>,
@@ -214,6 +218,10 @@ fn renderer_event_to_payload(
queue_length,
timestamp,
},
RendererEvent::QueueRefreshing { id } => RendererEventPayload::QueueRefreshing {
renderer_id: id.0,
timestamp,
},
RendererEvent::BindingChanged { id, binding } => RendererEventPayload::BindingChanged {
renderer_id: id.0,
server_id: binding.as_ref().map(|b| b.server_id.0.clone()),