From 9ba6a32ec6c4a231627db1d21c7cd72416b97b4a Mon Sep 17 00:00:00 2001 From: Cameron Mcloughlin Date: Mon, 20 Apr 2026 17:34:23 +0100 Subject: [PATCH] sidebar: Consistently set `interacted_at` (#54320) There were a few places where you could trigger generation without causing the `interacted_at` field to be set. Also renames `message_sent_or_queued` to `interacted`, to be consistent with the field on `ThreadMetadata` Release Notes: - N/A or Added/Fixed/Improved ... --- crates/agent_ui/src/agent_panel.rs | 6 +++--- .../agent_ui/src/conversation_view/thread_view.rs | 13 +++++++++---- crates/agent_ui/src/thread_metadata_store.rs | 4 +++- crates/sidebar/src/sidebar.rs | 10 +++------- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index 48a80ed0fe784ebb9601a32b6561e4aba5f3d455..b873decd220008a8faa1ad14651319f5d26e3f77 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -2454,7 +2454,7 @@ impl AgentPanel { &tv, window, |this, _view, event: &AcpThreadViewEvent, _window, cx| match event { - AcpThreadViewEvent::MessageSentOrQueued => { + AcpThreadViewEvent::Interacted => { let Some(thread_id) = this.active_thread_id(cx) else { return; }; @@ -2466,7 +2466,7 @@ impl AgentPanel { this._draft_editor_observation = None; } this.retained_threads.remove(&thread_id); - cx.emit(AgentPanelEvent::MessageSentOrQueued { thread_id }); + cx.emit(AgentPanelEvent::ThreadInteracted { thread_id }); } }, ) @@ -2762,7 +2762,7 @@ pub enum AgentPanelEvent { ActiveViewChanged, ThreadFocused, RetainedThreadChanged, - MessageSentOrQueued { thread_id: ThreadId }, + ThreadInteracted { thread_id: ThreadId }, } impl EventEmitter for AgentPanel {} diff --git a/crates/agent_ui/src/conversation_view/thread_view.rs b/crates/agent_ui/src/conversation_view/thread_view.rs index a4ff0f31494aa262d852e735bbc3bbfa0a78ad15..ca4b261301f94b5c4299c77ce6ef82af1886bc79 100644 --- a/crates/agent_ui/src/conversation_view/thread_view.rs +++ b/crates/agent_ui/src/conversation_view/thread_view.rs @@ -206,7 +206,7 @@ impl RenderOnce for GeneratingSpinnerElement { } pub enum AcpThreadViewEvent { - MessageSentOrQueued, + Interacted, } impl EventEmitter for ThreadView {} @@ -954,7 +954,6 @@ impl ThreadView { let has_queued = self.has_queued_messages(); if is_editor_empty && self.can_fast_track_queue && has_queued { self.can_fast_track_queue = false; - cx.emit(AcpThreadViewEvent::MessageSentOrQueued); self.send_queued_message_at_index(0, true, window, cx); return; } @@ -964,7 +963,7 @@ impl ThreadView { } if is_generating { - cx.emit(AcpThreadViewEvent::MessageSentOrQueued); + cx.emit(AcpThreadViewEvent::Interacted); self.queue_message(message_editor, window, cx); return; } @@ -1006,7 +1005,7 @@ impl ThreadView { } } - cx.emit(AcpThreadViewEvent::MessageSentOrQueued); + cx.emit(AcpThreadViewEvent::Interacted); self.send_impl(message_editor, window, cx) } @@ -1209,6 +1208,8 @@ impl ThreadView { return; } + cx.emit(AcpThreadViewEvent::Interacted); + let message_editor = self.message_editor.clone(); if thread.read(cx).status() == ThreadStatus::Idle { self.send_impl(message_editor, window, cx); @@ -1371,6 +1372,7 @@ impl ThreadView { } let task = thread.update(cx, |thread, cx| thread.retry(cx)); + cx.emit(AcpThreadViewEvent::Interacted); self.sync_generating_indicator(cx); cx.notify(); cx.spawn(async move |this, cx| { @@ -1430,6 +1432,7 @@ impl ThreadView { .update(cx, |thread, cx| thread.rewind(user_message_id, cx)) .await?; this.update_in(cx, |thread, window, cx| { + cx.emit(AcpThreadViewEvent::Interacted); thread.send_impl(message_editor, window, cx); thread.focus_handle(cx).focus(window, cx); })?; @@ -1522,6 +1525,8 @@ impl ThreadView { return; }; + cx.emit(AcpThreadViewEvent::Interacted); + self.message_editor.focus_handle(cx).focus(window, cx); let content = queued.content; diff --git a/crates/agent_ui/src/thread_metadata_store.rs b/crates/agent_ui/src/thread_metadata_store.rs index c49220f8d44dde1132dd6db5ba520065a299c210..ce1c9ed231f3718561dadb5c09989daf56b63c2e 100644 --- a/crates/agent_ui/src/thread_metadata_store.rs +++ b/crates/agent_ui/src/thread_metadata_store.rs @@ -1176,7 +1176,9 @@ impl ThreadMetadataStore { .and_then(|t| t.created_at) .unwrap_or_else(|| updated_at); - let interacted_at = existing_thread.and_then(|t| t.interacted_at); + let interacted_at = existing_thread + .map(|t| t.interacted_at) + .unwrap_or(Some(updated_at)); let agent_id = thread_ref.connection().agent_id(); diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index a2259a58f1cd2d92dd9132334721a854cc821c23..0b690b5d21f09633168debde1b969741dec615d2 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -736,8 +736,8 @@ impl Sidebar { this.sync_active_entry_from_panel(_agent_panel, cx); this.update_entries(cx); } - AgentPanelEvent::MessageSentOrQueued { thread_id } => { - this.record_thread_message_sent_or_queued(thread_id, cx); + AgentPanelEvent::ThreadInteracted { thread_id } => { + this.record_thread_interacted(thread_id, cx); this.update_entries(cx); } }, @@ -3572,11 +3572,7 @@ impl Sidebar { self.thread_last_accessed.insert(*id, Utc::now()); } - fn record_thread_message_sent_or_queued( - &mut self, - thread_id: &agent_ui::ThreadId, - cx: &mut App, - ) { + fn record_thread_interacted(&mut self, thread_id: &agent_ui::ThreadId, cx: &mut App) { let store = ThreadMetadataStore::global(cx); store.update(cx, |store, cx| { store.update_interacted_at(thread_id, Utc::now(), cx);