feat(app): clear all events from the Event Center (red trash icon)

Adds Cmd::ClearEvents + Evt::EventsCleared: the daemon drops the persistent
event log (keeping next_id monotonic), persists, and broadcasts so every
client empties its list. A red trash icon next to 'Mark all read' triggers it;
disabled when the list is empty. Threaded through proto, the daemon handler,
the Tauri bridge, and socketBridge. Includes an EventLog::clear test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-15 13:38:35 +07:00
parent bcc88b6be7
commit f9a565a712
8 changed files with 53 additions and 5 deletions
+2
View File
@@ -124,6 +124,7 @@ pub enum Cmd {
limit: Option<u32>,
},
MarkRead { target: MarkReadTarget },
ClearEvents,
SetZoom {
workspace_id: WorkspaceId,
#[serde(default, skip_serializing_if = "Option::is_none")]
@@ -163,6 +164,7 @@ pub enum Evt {
State { surface_id: SurfaceId, state: SurfaceState },
Event { record: EventRecord },
EventsRead { ids: Vec<u64> },
EventsCleared,
ConfigChanged { config: crate::config_view::ConfigView },
}
+17
View File
@@ -88,6 +88,11 @@ impl EventLog {
changed
}
/// Drop all records. `next_id` stays monotonic so ids are never reused.
pub fn clear(&mut self) {
self.records.clear();
}
pub fn unread_count(&self) -> u32 {
self.records.iter().filter(|r| !r.read).count() as u32
}
@@ -164,6 +169,18 @@ mod tests {
assert!(log.mark_read(&MarkReadTarget::All).is_empty());
}
#[test]
fn clear_drops_records_but_keeps_next_id() {
let mut log = EventLog::new(10);
rec(&mut log, "s_1", EventKind::Done);
rec(&mut log, "s_2", EventKind::Done);
log.clear();
assert_eq!(log.recent(None).len(), 0);
assert_eq!(log.unread_count(), 0);
// ids continue from where they were — no reuse after a clear.
assert_eq!(rec(&mut log, "s_3", EventKind::Done).id, 3);
}
#[test]
fn snapshot_restore_preserves_next_id_and_records() {
let mut log = EventLog::new(10);
+7
View File
@@ -648,6 +648,13 @@ async fn handle_request(
let _ = out.send(ok(id, serde_json::Value::Null)).await;
}
Cmd::ClearEvents => {
event_log.clear();
event_persister.mark_dirty(event_log.snapshot());
broadcast_evt(clients, &Envelope::Evt(Evt::EventsCleared));
let _ = out.send(ok(id, serde_json::Value::Null)).await;
}
Cmd::Shutdown => {
let _ = out.send(ok(id, serde_json::Value::Null)).await;
std::process::exit(0);