Skip to content

Commit 28fa947

Browse files
authored
agent_ui: Enable deleting a thread from the sidebar (zed-industries#51532)
Currently only available for native threads. Release Notes: - N/A
1 parent b7266ba commit 28fa947

2 files changed

Lines changed: 60 additions & 6 deletions

File tree

crates/agent_ui/src/sidebar.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ pub struct Sidebar {
243243
selection: Option<usize>,
244244
focused_thread: Option<acp::SessionId>,
245245
active_entry_index: Option<usize>,
246+
hovered_thread_index: Option<usize>,
246247
collapsed_groups: HashSet<PathList>,
247248
expanded_groups: HashMap<PathList, usize>,
248249
view: SidebarView,
@@ -345,6 +346,7 @@ impl Sidebar {
345346
selection: None,
346347
focused_thread: None,
347348
active_entry_index: None,
349+
hovered_thread_index: None,
348350
collapsed_groups: HashSet::new(),
349351
expanded_groups: HashMap::new(),
350352
view: SidebarView::default(),
@@ -1582,11 +1584,23 @@ impl Sidebar {
15821584
}
15831585
}
15841586

1587+
fn delete_thread(&mut self, session_id: &acp::SessionId, cx: &mut Context<Self>) {
1588+
let Some(thread_store) = ThreadStore::try_global(cx) else {
1589+
return;
1590+
};
1591+
self.hovered_thread_index = None;
1592+
thread_store.update(cx, |store, cx| {
1593+
store
1594+
.delete_thread(session_id.clone(), cx)
1595+
.detach_and_log_err(cx);
1596+
});
1597+
}
1598+
15851599
fn render_thread(
15861600
&self,
15871601
ix: usize,
15881602
thread: &ThreadEntry,
1589-
is_selected: bool,
1603+
is_focused: bool,
15901604
docked_right: bool,
15911605
cx: &mut Context<Self>,
15921606
) -> AnyElement {
@@ -1602,6 +1616,11 @@ impl Sidebar {
16021616
let session_info = thread.session_info.clone();
16031617
let thread_workspace = thread.workspace.clone();
16041618

1619+
let is_hovered = self.hovered_thread_index == Some(ix);
1620+
let is_selected = self.focused_thread.as_ref() == Some(&session_info.session_id);
1621+
let can_delete = thread.agent == Agent::NativeAgent;
1622+
let session_id_for_delete = thread.session_info.session_id.clone();
1623+
16051624
let id = SharedString::from(format!("thread-entry-{}", ix));
16061625

16071626
let timestamp = thread
@@ -1648,9 +1667,32 @@ impl Sidebar {
16481667
.when(thread.diff_stats.lines_removed > 0, |this| {
16491668
this.removed(thread.diff_stats.lines_removed as usize)
16501669
})
1651-
.selected(self.focused_thread.as_ref() == Some(&session_info.session_id))
1652-
.focused(is_selected)
1670+
.selected(is_selected)
1671+
.focused(is_focused)
16531672
.docked_right(docked_right)
1673+
.hovered(is_hovered)
1674+
.on_hover(cx.listener(move |this, is_hovered: &bool, _window, cx| {
1675+
if *is_hovered {
1676+
this.hovered_thread_index = Some(ix);
1677+
} else if this.hovered_thread_index == Some(ix) {
1678+
this.hovered_thread_index = None;
1679+
}
1680+
cx.notify();
1681+
}))
1682+
.when((is_hovered || is_selected) && can_delete, |this| {
1683+
this.action_slot(
1684+
IconButton::new("delete-thread", IconName::Trash)
1685+
.icon_size(IconSize::Small)
1686+
.icon_color(Color::Muted)
1687+
.tooltip(Tooltip::text("Delete Thread"))
1688+
.on_click({
1689+
let session_id = session_id_for_delete.clone();
1690+
cx.listener(move |this, _, _window, cx| {
1691+
this.delete_thread(&session_id, cx);
1692+
})
1693+
}),
1694+
)
1695+
})
16541696
.on_click({
16551697
let agent = thread.agent.clone();
16561698
cx.listener(move |this, _, window, cx| {

crates/ui/src/components/ai/thread_item.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,20 @@ impl RenderOnce for ThreadItem {
283283
.when_some(self.tooltip, |this, tooltip| this.tooltip(tooltip)),
284284
)
285285
.child(gradient_overlay)
286-
.when(self.hovered, |this| {
287-
this.when_some(self.action_slot, |this, slot| this.child(slot))
286+
.when(self.hovered || self.selected, |this| {
287+
this.when_some(self.action_slot, |this, slot| {
288+
let overlay = GradientFade::new(
289+
base_bg,
290+
color.element_hover,
291+
color.element_active,
292+
)
293+
.width(px(64.0))
294+
.right(px(6.))
295+
.gradient_stop(0.75)
296+
.group_name("thread-item");
297+
298+
this.child(h_flex().relative().child(overlay).child(slot))
299+
})
288300
}),
289301
)
290302
.when_some(self.worktree, |this, worktree| {
@@ -337,7 +349,7 @@ impl RenderOnce for ThreadItem {
337349
.when(has_diff_stats, |this| {
338350
this.child(
339351
DiffStat::new(diff_stat_id, added_count, removed_count)
340-
.tooltip("Unreviewed changes"),
352+
.tooltip("Unreviewed Changes"),
341353
)
342354
})
343355
.when(has_diff_stats && has_timestamp, |this| {

0 commit comments

Comments
 (0)