From 488f79a93dd834975eddc9937632bdf9cb71e55e Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Wed, 18 Mar 2026 18:06:07 -0300 Subject: [PATCH] sidebar: Improve behavior of the "view more" action (#51872) This PR makes sure that threads running, waiting for confirmation, or with a notification remain visible even after you've collapsed the list, in case they would be naturally hidden (if the list was collapsed). Release Notes: - N/A Co-authored-by: Bennet Bo Fenner --- crates/sidebar/src/sidebar.rs | 39 +++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index 5e359175ff96dee9b9885b82af2bc70096ead3f8..fca76c9a58c3beb9487314b4b0c975d4e5c8ad7b 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -242,6 +242,7 @@ pub struct Sidebar { hovered_thread_index: Option, collapsed_groups: HashSet, expanded_groups: HashMap, + promoted_threads: HashSet, view: SidebarView, archive_view: Option>, recent_projects_popover_handle: PopoverMenuHandle, @@ -365,6 +366,7 @@ impl Sidebar { hovered_thread_index: None, collapsed_groups: HashSet::new(), expanded_groups: HashMap::new(), + promoted_threads: HashSet::new(), view: SidebarView::default(), archive_view: None, recent_projects_popover_handle: PopoverMenuHandle::default(), @@ -994,12 +996,34 @@ impl Sidebar { let threads_to_show = DEFAULT_THREADS_SHOWN + (extra_batches * DEFAULT_THREADS_SHOWN); let count = threads_to_show.min(total); - let is_fully_expanded = count >= total; - // Track session IDs and compute active_entry_index as we add - // thread entries. - for thread in threads.into_iter().take(count) { - current_session_ids.insert(thread.session_info.session_id.clone()); + self.promoted_threads.clear(); + + // Build visible entries in a single pass. Threads within + // the cutoff are always shown. Threads beyond it are shown + // only if they should be promoted (running, waiting, or + // focused) + for (index, thread) in threads.into_iter().enumerate() { + let is_hidden = index >= count; + + let session_id = &thread.session_info.session_id; + if is_hidden { + let is_promoted = thread.status == AgentThreadStatus::Running + || thread.status == AgentThreadStatus::WaitingForConfirmation + || notified_threads.contains(session_id) + || self + .focused_thread + .as_ref() + .is_some_and(|id| id == session_id); + if is_promoted { + self.promoted_threads.insert(session_id.clone()); + } + if !self.promoted_threads.contains(session_id) { + continue; + } + } + + current_session_ids.insert(session_id.clone()); if active_entry_index.is_none() { if let Some(focused) = &self.focused_thread { if &thread.session_info.session_id == focused { @@ -1010,10 +1034,13 @@ impl Sidebar { entries.push(thread.into()); } + let visible = count + self.promoted_threads.len(); + let is_fully_expanded = visible >= total; + if total > DEFAULT_THREADS_SHOWN { entries.push(ListEntry::ViewMore { path_list: path_list.clone(), - remaining_count: total.saturating_sub(count), + remaining_count: total.saturating_sub(visible), is_fully_expanded, }); }