refactor(peer): split local library and operation UI events
Replace the `a9f9845` local-update dedup cache with explicit peer event semantics. Local scans now emit `LocalLibraryChanged` when the library changes, while operation mutations emit `ActiveOperationsChanged` from the mutation path. Tauri keeps joining those facts into the existing `games-list-updated` payload, so the frontend contract stays stable. This removes the cache/invalidation coupling between scan emission and operation state. The remaining forced local snapshot is explicit: accepted game directory changes can refresh the UI for an equivalent new path without sending a peer library delta. Operation guard cleanup and liveness cancellation now publish the same active operation snapshot as normal command-handler transitions. The peer CLI JSONL events follow the same split with `local-library-changed` and `active-operations-changed`. Test Plan: - `just fmt` - `CARGO_BUILD_RUSTC_WRAPPER= just test` - `CARGO_BUILD_RUSTC_WRAPPER= just clippy` - `git diff --check` Refs: CLEAN_CODE_PLAN_1.md
This commit is contained in:
14 files changed
+657
-255
No files matched your search
@@ -1,10 +1,16 @@
|
||||
//! UI event helpers used by peer command and service code.
|
||||
|
||||
use std::{net::SocketAddr, sync::Arc};
|
||||
use std::{collections::HashMap, net::SocketAddr, sync::Arc};
|
||||
|
||||
use tokio::sync::{RwLock, mpsc::UnboundedSender};
|
||||
|
||||
use crate::{PeerEvent, peer_db::PeerGameDB};
|
||||
use crate::{
|
||||
ActiveOperation,
|
||||
ActiveOperationKind,
|
||||
PeerEvent,
|
||||
context::OperationKind,
|
||||
peer_db::PeerGameDB,
|
||||
};
|
||||
|
||||
pub fn send(tx_notify_ui: &UnboundedSender<PeerEvent>, event: PeerEvent) {
|
||||
if let Err(err) = tx_notify_ui.send(event) {
|
||||
@@ -13,6 +19,49 @@ pub fn send(tx_notify_ui: &UnboundedSender<PeerEvent>, event: PeerEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn active_operation_snapshot_from_map(
|
||||
active_operations: &HashMap<String, OperationKind>,
|
||||
) -> Vec<ActiveOperation> {
|
||||
let mut snapshot = active_operations
|
||||
.iter()
|
||||
.map(|(id, operation)| ActiveOperation {
|
||||
id: id.clone(),
|
||||
operation: active_operation_kind(*operation),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
snapshot.sort_by(|left, right| left.id.cmp(&right.id));
|
||||
snapshot
|
||||
}
|
||||
|
||||
pub(crate) fn send_active_operations_snapshot(
|
||||
tx_notify_ui: &UnboundedSender<PeerEvent>,
|
||||
active_operations: &HashMap<String, OperationKind>,
|
||||
) {
|
||||
send(
|
||||
tx_notify_ui,
|
||||
PeerEvent::ActiveOperationsChanged {
|
||||
active_operations: active_operation_snapshot_from_map(active_operations),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) async fn emit_active_operations(
|
||||
active_operations: &Arc<RwLock<HashMap<String, OperationKind>>>,
|
||||
tx_notify_ui: &UnboundedSender<PeerEvent>,
|
||||
) {
|
||||
let active_operations = active_operations.read().await;
|
||||
send_active_operations_snapshot(tx_notify_ui, &active_operations);
|
||||
}
|
||||
|
||||
fn active_operation_kind(operation: OperationKind) -> ActiveOperationKind {
|
||||
match operation {
|
||||
OperationKind::Downloading => ActiveOperationKind::Downloading,
|
||||
OperationKind::Installing => ActiveOperationKind::Installing,
|
||||
OperationKind::Updating => ActiveOperationKind::Updating,
|
||||
OperationKind::Uninstalling => ActiveOperationKind::Uninstalling,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn emit_peer_game_list(
|
||||
peer_game_db: &Arc<RwLock<PeerGameDB>>,
|
||||
tx_notify_ui: &UnboundedSender<PeerEvent>,
|
||||
|
||||
Reference in new issue
Block a user