Fix duplicate thread entries in agent navigation menu (#29672)

Closes #ISSUE

Release Notes:

- N/A
This commit is contained in:
Cole Miller 2025-04-30 11:26:04 -04:00 committed by GitHub
parent ff4900c942
commit e4e455ae6b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 34 additions and 12 deletions

View file

@ -401,11 +401,12 @@ impl AssistantPanel {
}
});
let thread_id = thread.read(cx).id().clone();
let history_store = cx.new(|cx| {
HistoryStore::new(
thread_store.clone(),
context_store.clone(),
[RecentEntry::Thread(thread.clone())],
[RecentEntry::Thread(thread_id, thread.clone())],
cx,
)
});
@ -467,7 +468,7 @@ impl AssistantPanel {
.update(cx, {
let entry = entry.clone();
move |this, cx| match entry {
RecentEntry::Thread(thread) => {
RecentEntry::Thread(_, thread) => {
this.open_thread(thread, window, cx)
}
RecentEntry::Context(context) => {
@ -1099,7 +1100,8 @@ impl AssistantPanel {
ActiveView::Thread { thread, .. } => self.history_store.update(cx, |store, cx| {
if let Some(thread) = thread.upgrade() {
if thread.read(cx).is_empty() {
store.remove_recently_opened_entry(&RecentEntry::Thread(thread), cx);
let id = thread.read(cx).id().clone();
store.remove_recently_opened_thread(id, cx);
}
}
}),
@ -1109,7 +1111,8 @@ impl AssistantPanel {
match &new_view {
ActiveView::Thread { thread, .. } => self.history_store.update(cx, |store, cx| {
if let Some(thread) = thread.upgrade() {
store.push_recently_opened_entry(RecentEntry::Thread(thread), cx);
let id = thread.read(cx).id().clone();
store.push_recently_opened_entry(RecentEntry::Thread(id, thread), cx);
}
}),
ActiveView::PromptEditor { context_editor, .. } => {

View file

@ -36,16 +36,28 @@ impl HistoryEntry {
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug)]
pub(crate) enum RecentEntry {
Thread(Entity<Thread>),
Thread(ThreadId, Entity<Thread>),
Context(Entity<AssistantContext>),
}
impl PartialEq for RecentEntry {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Thread(l0, _), Self::Thread(r0, _)) => l0 == r0,
(Self::Context(l0), Self::Context(r0)) => l0 == r0,
_ => false,
}
}
}
impl Eq for RecentEntry {}
impl RecentEntry {
pub(crate) fn summary(&self, cx: &App) -> SharedString {
match self {
RecentEntry::Thread(thread) => thread.read(cx).summary_or_default(),
RecentEntry::Thread(_, thread) => thread.read(cx).summary_or_default(),
RecentEntry::Context(context) => context.read(cx).summary_or_default(),
}
}
@ -93,9 +105,10 @@ impl HistoryStore {
.map(|serialized| match serialized {
SerializedRecentEntry::Thread(id) => thread_store
.update(cx, |thread_store, cx| {
let thread_id = ThreadId::from(id.as_str());
thread_store
.open_thread(&ThreadId::from(id.as_str()), cx)
.map_ok(RecentEntry::Thread)
.open_thread(&thread_id, cx)
.map_ok(|thread| RecentEntry::Thread(thread_id, thread))
.boxed()
})
.unwrap_or_else(|_| async { Err(anyhow!("no thread store")) }.boxed()),
@ -170,9 +183,7 @@ impl HistoryStore {
RecentEntry::Context(context) => Some(SerializedRecentEntry::Context(
context.read(cx).path()?.to_str()?.to_owned(),
)),
RecentEntry::Thread(thread) => Some(SerializedRecentEntry::Thread(
thread.read(cx).id().to_string(),
)),
RecentEntry::Thread(id, _) => Some(SerializedRecentEntry::Thread(id.to_string())),
})
.collect::<Vec<_>>();
@ -200,6 +211,14 @@ impl HistoryStore {
self.save_recently_opened_entries(cx);
}
pub fn remove_recently_opened_thread(&mut self, id: ThreadId, cx: &mut Context<Self>) {
self.recently_opened_entries.retain(|entry| match entry {
RecentEntry::Thread(thread_id, _) if thread_id == &id => false,
_ => true,
});
self.save_recently_opened_entries(cx);
}
pub fn remove_recently_opened_entry(&mut self, entry: &RecentEntry, cx: &mut Context<Self>) {
self.recently_opened_entries
.retain(|old_entry| old_entry != entry);