sidebar: Remove View More batched thread expansion (#53956)

Remove the `DEFAULT_THREADS_SHOWN` limit and the View More / Collapse
row from the sidebar thread list. When a project group is expanded, all
of its threads are now shown. Fold/unfold of project group headers is
preserved.

### Changes

- Remove `ListEntry::ViewMore` variant and `render_view_more`
- Remove `DEFAULT_THREADS_SHOWN`, `group_extra_batches`,
`set_group_visible_thread_count`, `expand/collapse_thread_group`
- Remove `visible_thread_count` from `ProjectGroupState`,
`SerializedProjectGroupState`, `ProjectGroup`, and persistence
- Remove `ShowMoreThreads` / `ShowFewerThreads` actions and vim
keybindings

cc @danilo-leal

Release Notes:

- N/A
This commit is contained in:
Nathan Sobo 2026-04-15 08:41:54 -06:00 committed by GitHub
parent 3f2baed6a0
commit 3b2c12a111
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 15 additions and 468 deletions

View file

@ -48,8 +48,8 @@ use util::path_list::PathList;
use workspace::{
CloseWindow, FocusWorkspaceSidebar, MultiWorkspace, MultiWorkspaceEvent, NextProject,
NextThread, Open, OpenMode, PreviousProject, PreviousThread, ProjectGroupKey, SaveIntent,
ShowFewerThreads, ShowMoreThreads, Sidebar as WorkspaceSidebar, SidebarSide, Toast,
ToggleWorkspaceSidebar, Workspace, notifications::NotificationId, sidebar_side_context_menu,
Sidebar as WorkspaceSidebar, SidebarSide, Toast, ToggleWorkspaceSidebar, Workspace,
notifications::NotificationId, sidebar_side_context_menu,
};
use zed_actions::OpenRecent;
@ -83,7 +83,6 @@ gpui::actions!(
const DEFAULT_WIDTH: Pixels = px(300.0);
const MIN_WIDTH: Pixels = px(200.0);
const MAX_WIDTH: Pixels = px(800.0);
const DEFAULT_THREADS_SHOWN: usize = 5;
#[derive(Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
enum SerializedSidebarView {
@ -227,10 +226,6 @@ enum ListEntry {
has_threads: bool,
},
Thread(ThreadEntry),
ViewMore {
key: ProjectGroupKey,
is_fully_expanded: bool,
},
}
#[cfg(test)]
@ -255,7 +250,6 @@ impl ListEntry {
ListEntry::ProjectHeader { key, .. } => multi_workspace
.workspaces_for_project_group(key, cx)
.unwrap_or_default(),
ListEntry::ViewMore { .. } => Vec::new(),
}
}
}
@ -482,17 +476,6 @@ impl Sidebar {
.unwrap_or(false)
}
fn group_extra_batches(&self, key: &ProjectGroupKey, cx: &App) -> usize {
self.multi_workspace
.upgrade()
.and_then(|mw| {
mw.read(cx)
.group_state_by_key(key)
.and_then(|state| state.visible_thread_count)
})
.unwrap_or(0)
}
fn set_group_expanded(&self, key: &ProjectGroupKey, expanded: bool, cx: &mut Context<Self>) {
if let Some(mw) = self.multi_workspace.upgrade() {
mw.update(cx, |mw, cx| {
@ -504,22 +487,6 @@ impl Sidebar {
}
}
fn set_group_visible_thread_count(
&self,
key: &ProjectGroupKey,
count: Option<usize>,
cx: &mut Context<Self>,
) {
if let Some(mw) = self.multi_workspace.upgrade() {
mw.update(cx, |mw, cx| {
if let Some(state) = mw.group_state_by_key_mut(key) {
state.visible_thread_count = count;
}
mw.serialize(cx);
});
}
}
fn is_active_workspace(&self, workspace: &Entity<Workspace>, cx: &App) -> bool {
self.multi_workspace
.upgrade()
@ -1250,55 +1217,13 @@ impl Sidebar {
continue;
}
let total = threads.len();
let extra_batches = self.group_extra_batches(&group_key, cx);
let threads_to_show =
DEFAULT_THREADS_SHOWN + (extra_batches * DEFAULT_THREADS_SHOWN);
let count = threads_to_show.min(total);
let mut promoted_threads: HashSet<agent_ui::ThreadId> = HashSet::new();
// 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;
if is_hidden {
let is_notified = notified_threads.contains(&thread.metadata.thread_id);
let is_promoted = thread.status == AgentThreadStatus::Running
|| thread.status == AgentThreadStatus::WaitingForConfirmation
|| is_notified
|| self.active_entry.as_ref().is_some_and(|active| {
active.matches_entry(&ListEntry::Thread(thread.clone()))
});
if is_promoted {
promoted_threads.insert(thread.metadata.thread_id);
}
let is_in_promoted = promoted_threads.contains(&thread.metadata.thread_id);
if !is_in_promoted {
continue;
}
}
for thread in threads {
if let Some(sid) = &thread.metadata.session_id {
current_session_ids.insert(sid.clone());
}
current_thread_ids.insert(thread.metadata.thread_id);
entries.push(thread.into());
}
let visible = count + promoted_threads.len();
let is_fully_expanded = visible >= total;
if total > DEFAULT_THREADS_SHOWN {
entries.push(ListEntry::ViewMore {
key: group_key.clone(),
is_fully_expanded,
});
}
}
}
@ -1414,10 +1339,6 @@ impl Sidebar {
)
}
ListEntry::Thread(thread) => self.render_thread(ix, thread, is_active, is_selected, cx),
ListEntry::ViewMore {
key,
is_fully_expanded,
} => self.render_view_more(ix, key, *is_fully_expanded, is_selected, cx),
};
if is_group_header_after_first {
@ -1485,8 +1406,6 @@ impl Sidebar {
};
let key_for_toggle = key.clone();
let key_for_collapse = key.clone();
let view_more_expanded = self.group_extra_batches(key, cx) > 0;
let label = if highlight_positions.is_empty() {
Label::new(label.clone())
@ -1632,30 +1551,6 @@ impl Sidebar {
},
))
})
.when(has_threads && view_more_expanded && !is_collapsed, |this| {
this.child(
IconButton::new(
SharedString::from(format!(
"{id_prefix}project-header-collapse-{ix}",
)),
IconName::ListCollapse,
)
.icon_size(IconSize::Small)
.tooltip(Tooltip::text("Show Fewer Threads"))
.on_click(cx.listener({
let key_for_collapse = key_for_collapse.clone();
move |this, _, _window, cx| {
this.selection = None;
this.set_group_visible_thread_count(
&key_for_collapse,
None,
cx,
);
this.update_entries(cx);
}
})),
)
})
.child(self.render_project_header_ellipsis_menu(ix, id_prefix, key, cx)),
)
.tooltip(Tooltip::element({
@ -2146,18 +2041,6 @@ impl Sidebar {
}
}
}
ListEntry::ViewMore {
key,
is_fully_expanded,
..
} => {
let key = key.clone();
if *is_fully_expanded {
self.reset_thread_group_expansion(&key, cx);
} else {
self.expand_thread_group(&key, cx);
}
}
}
}
@ -2718,7 +2601,7 @@ impl Sidebar {
self.update_entries(cx);
}
}
Some(ListEntry::Thread(_) | ListEntry::ViewMore { .. }) => {
Some(ListEntry::Thread(_)) => {
for i in (0..ix).rev() {
if let Some(ListEntry::ProjectHeader { key, .. }) = self.contents.entries.get(i)
{
@ -2745,7 +2628,7 @@ impl Sidebar {
// Find the group header for the current selection.
let header_ix = match self.contents.entries.get(ix) {
Some(ListEntry::ProjectHeader { .. }) => Some(ix),
Some(ListEntry::Thread(_) | ListEntry::ViewMore { .. }) => (0..ix).rev().find(|&i| {
Some(ListEntry::Thread(_)) => (0..ix).rev().find(|&i| {
matches!(
self.contents.entries.get(i),
Some(ListEntry::ProjectHeader { .. })
@ -3448,7 +3331,6 @@ impl Sidebar {
timestamp,
})
}
_ => None,
})
.collect();
@ -3855,38 +3737,6 @@ impl Sidebar {
.anchor(gpui::Corner::BottomRight)
}
fn render_view_more(
&self,
ix: usize,
key: &ProjectGroupKey,
is_fully_expanded: bool,
is_selected: bool,
cx: &mut Context<Self>,
) -> AnyElement {
let key = key.clone();
let id = SharedString::from(format!("view-more-{}", ix));
let label: SharedString = if is_fully_expanded {
"Collapse".into()
} else {
"View More".into()
};
ThreadItem::new(id, label)
.focused(is_selected)
.icon_visible(false)
.title_label_color(Color::Muted)
.on_click(cx.listener(move |this, _, _window, cx| {
this.selection = None;
if is_fully_expanded {
this.reset_thread_group_expansion(&key, cx);
} else {
this.expand_thread_group(&key, cx);
}
}))
.into_any_element()
}
fn new_thread_in_group(
&mut self,
_: &NewThreadInGroup,
@ -3943,7 +3793,7 @@ impl Sidebar {
let ix = self.selection?;
match self.contents.entries.get(ix) {
Some(ListEntry::ProjectHeader { key, .. }) => Some(key.clone()),
Some(ListEntry::Thread(_) | ListEntry::ViewMore { .. }) => {
Some(ListEntry::Thread(_)) => {
(0..ix)
.rev()
.find_map(|i| match self.contents.entries.get(i) {
@ -4120,59 +3970,6 @@ impl Sidebar {
self.cycle_thread_impl(false, window, cx);
}
fn expand_thread_group(&mut self, project_group_key: &ProjectGroupKey, cx: &mut Context<Self>) {
let current = self.group_extra_batches(project_group_key, cx);
self.set_group_visible_thread_count(project_group_key, Some(current + 1), cx);
self.update_entries(cx);
}
fn reset_thread_group_expansion(
&mut self,
project_group_key: &ProjectGroupKey,
cx: &mut Context<Self>,
) {
self.set_group_visible_thread_count(project_group_key, None, cx);
self.update_entries(cx);
}
fn collapse_thread_group(
&mut self,
project_group_key: &ProjectGroupKey,
cx: &mut Context<Self>,
) {
let batches = self.group_extra_batches(project_group_key, cx);
match batches {
0 => return,
1 => self.set_group_visible_thread_count(project_group_key, None, cx),
_ => self.set_group_visible_thread_count(project_group_key, Some(batches - 1), cx),
}
self.update_entries(cx);
}
fn on_show_more_threads(
&mut self,
_: &ShowMoreThreads,
_window: &mut Window,
cx: &mut Context<Self>,
) {
let Some(active_key) = self.active_project_group_key(cx) else {
return;
};
self.expand_thread_group(&active_key, cx);
}
fn on_show_fewer_threads(
&mut self,
_: &ShowFewerThreads,
_window: &mut Window,
cx: &mut Context<Self>,
) {
let Some(active_key) = self.active_project_group_key(cx) else {
return;
};
self.collapse_thread_group(&active_key, cx);
}
fn render_no_results(&self, cx: &mut Context<Self>) -> impl IntoElement {
let has_query = self.has_filter_query(cx);
let message = if has_query {
@ -4729,8 +4526,6 @@ impl Render for Sidebar {
.on_action(cx.listener(Self::on_previous_project))
.on_action(cx.listener(Self::on_next_thread))
.on_action(cx.listener(Self::on_previous_thread))
.on_action(cx.listener(Self::on_show_more_threads))
.on_action(cx.listener(Self::on_show_fewer_threads))
.on_action(cx.listener(|this, _: &OpenRecent, window, cx| {
this.recent_projects_popover_handle.toggle(window, cx);
}))

View file

@ -145,11 +145,6 @@ fn assert_remote_project_integration_sidebar_state(
title
);
}
ListEntry::ViewMore { .. } => {
panic!(
"unexpected `View More` entry while simulating remote project integration flicker"
);
}
}
}
@ -427,15 +422,6 @@ fn visible_entries_as_strings(
format!(" {title}{worktree}{live}{status_str}{notified}{selected}")
}
}
ListEntry::ViewMore {
is_fully_expanded, ..
} => {
if *is_fully_expanded {
format!(" - Collapse{}", selected)
} else {
format!(" + View More{}", selected)
}
}
}
})
.collect()
@ -453,7 +439,7 @@ async fn test_serialization_round_trip(cx: &mut TestAppContext) {
let project_group_key = project.read_with(cx, |project, cx| project.project_group_key(cx));
// Set a custom width, collapse the group, and expand "View More".
// Set a custom width and collapse the group.
sidebar.update_in(cx, |sidebar, window, cx| {
sidebar.set_width(Some(px(420.0)), cx);
sidebar.toggle_collapse(&project_group_key, window, cx);
@ -635,101 +621,6 @@ async fn test_workspace_lifecycle(cx: &mut TestAppContext) {
);
}
#[gpui::test]
async fn test_view_more_pagination(cx: &mut TestAppContext) {
let project = init_test_project("/my-project", cx).await;
let (multi_workspace, cx) =
cx.add_window_view(|window, cx| MultiWorkspace::test_new(project.clone(), window, cx));
let sidebar = setup_sidebar(&multi_workspace, cx);
save_n_test_threads(12, &project, cx).await;
multi_workspace.update_in(cx, |_, _window, cx| cx.notify());
cx.run_until_parked();
assert_eq!(
visible_entries_as_strings(&sidebar, cx),
vec![
//
"v [my-project]",
" Thread 12",
" Thread 11",
" Thread 10",
" Thread 9",
" Thread 8",
" + View More",
]
);
}
#[gpui::test]
async fn test_view_more_batched_expansion(cx: &mut TestAppContext) {
let project = init_test_project("/my-project", cx).await;
let (multi_workspace, cx) =
cx.add_window_view(|window, cx| MultiWorkspace::test_new(project.clone(), window, cx));
let sidebar = setup_sidebar(&multi_workspace, cx);
// Create 17 threads: initially shows 5, then 10, then 15, then all 17 with Collapse
save_n_test_threads(17, &project, cx).await;
let project_group_key = project.read_with(cx, |project, cx| project.project_group_key(cx));
multi_workspace.update_in(cx, |_, _window, cx| cx.notify());
cx.run_until_parked();
// Initially shows 5 threads + View More
let entries = visible_entries_as_strings(&sidebar, cx);
assert_eq!(entries.len(), 7); // header + 5 threads + View More
assert!(entries.iter().any(|e| e.contains("View More")));
// Focus and navigate to View More, then confirm to expand by one batch
focus_sidebar(&sidebar, cx);
for _ in 0..7 {
cx.dispatch_action(SelectNext);
}
cx.dispatch_action(Confirm);
cx.run_until_parked();
// Now shows 10 threads + View More
let entries = visible_entries_as_strings(&sidebar, cx);
assert_eq!(entries.len(), 12); // header + 10 threads + View More
assert!(entries.iter().any(|e| e.contains("View More")));
// Expand again by one batch
sidebar.update_in(cx, |s, _window, cx| {
s.expand_thread_group(&project_group_key, cx);
});
cx.run_until_parked();
// Now shows 15 threads + View More
let entries = visible_entries_as_strings(&sidebar, cx);
assert_eq!(entries.len(), 17); // header + 15 threads + View More
assert!(entries.iter().any(|e| e.contains("View More")));
// Expand one more time - should show all 17 threads with Collapse button
sidebar.update_in(cx, |s, _window, cx| {
s.expand_thread_group(&project_group_key, cx);
});
cx.run_until_parked();
// All 17 threads shown with Collapse button
let entries = visible_entries_as_strings(&sidebar, cx);
assert_eq!(entries.len(), 19); // header + 17 threads + Collapse
assert!(!entries.iter().any(|e| e.contains("View More")));
assert!(entries.iter().any(|e| e.contains("Collapse")));
// Click collapse - should go back to showing 5 threads
sidebar.update_in(cx, |s, _window, cx| {
s.reset_thread_group_expansion(&project_group_key, cx);
});
cx.run_until_parked();
// Back to initial state: 5 threads + View More
let entries = visible_entries_as_strings(&sidebar, cx);
assert_eq!(entries.len(), 7); // header + 5 threads + View More
assert!(entries.iter().any(|e| e.contains("View More")));
}
#[gpui::test]
async fn test_collapse_and_expand_group(cx: &mut TestAppContext) {
let project = init_test_project("/my-project", cx).await;
@ -853,7 +744,6 @@ async fn test_visible_entries_as_strings(cx: &mut TestAppContext) {
key: ProjectGroupKey::new(None, collapsed_path.clone()),
workspaces: Vec::new(),
expanded: false,
visible_thread_count: None,
});
});
@ -992,11 +882,6 @@ async fn test_visible_entries_as_strings(cx: &mut TestAppContext) {
worktrees: Vec::new(),
diff_stats: DiffStats::default(),
}),
// View More entry
ListEntry::ViewMore {
key: ProjectGroupKey::new(None, expanded_path.clone()),
is_fully_expanded: false,
},
// Collapsed project header
ListEntry::ProjectHeader {
key: ProjectGroupKey::new(None, collapsed_path.clone()),
@ -1023,14 +908,13 @@ async fn test_visible_entries_as_strings(cx: &mut TestAppContext) {
" Error thread * (error)",
" Waiting thread (waiting)",
" Notified thread * (!)",
" + View More",
"> [collapsed-project]",
]
);
// Move selection to the collapsed header
sidebar.update_in(cx, |s, _window, _cx| {
s.selection = Some(7);
s.selection = Some(6);
});
assert_eq!(
@ -1219,40 +1103,6 @@ async fn test_keyboard_confirm_on_project_header_toggles_collapse(cx: &mut TestA
);
}
#[gpui::test]
async fn test_keyboard_confirm_on_view_more_expands(cx: &mut TestAppContext) {
let project = init_test_project("/my-project", cx).await;
let (multi_workspace, cx) =
cx.add_window_view(|window, cx| MultiWorkspace::test_new(project.clone(), window, cx));
let sidebar = setup_sidebar(&multi_workspace, cx);
save_n_test_threads(8, &project, cx).await;
multi_workspace.update_in(cx, |_, _window, cx| cx.notify());
cx.run_until_parked();
// Should show header + 5 threads + "View More"
let entries = visible_entries_as_strings(&sidebar, cx);
assert_eq!(entries.len(), 7);
assert!(entries.iter().any(|e| e.contains("View More")));
// Focus sidebar (selection starts at None), then navigate down to the "View More" entry (index 6)
focus_sidebar(&sidebar, cx);
for _ in 0..7 {
cx.dispatch_action(SelectNext);
}
assert_eq!(sidebar.read_with(cx, |s, _| s.selection), Some(6));
// Confirm on "View More" to expand
cx.dispatch_action(Confirm);
cx.run_until_parked();
// All 8 threads should now be visible with a "Collapse" button
let entries = visible_entries_as_strings(&sidebar, cx);
assert_eq!(entries.len(), 10); // header + 8 threads + Collapse button
assert!(!entries.iter().any(|e| e.contains("View More")));
assert!(entries.iter().any(|e| e.contains("Collapse")));
}
#[gpui::test]
async fn test_keyboard_expand_and_collapse_selected_entry(cx: &mut TestAppContext) {
let project = init_test_project("/my-project", cx).await;
@ -1983,60 +1833,6 @@ async fn test_search_matches_workspace_name(cx: &mut TestAppContext) {
);
}
#[gpui::test]
async fn test_search_finds_threads_hidden_behind_view_more(cx: &mut TestAppContext) {
let project = init_test_project("/my-project", cx).await;
let (multi_workspace, cx) =
cx.add_window_view(|window, cx| MultiWorkspace::test_new(project.clone(), window, cx));
let sidebar = setup_sidebar(&multi_workspace, cx);
// Create 8 threads. The oldest one has a unique name and will be
// behind View More (only 5 shown by default).
for i in 0..8u32 {
let title = if i == 0 {
"Hidden gem thread".to_string()
} else {
format!("Thread {}", i + 1)
};
save_thread_metadata(
acp::SessionId::new(Arc::from(format!("thread-{}", i))),
Some(title.into()),
chrono::TimeZone::with_ymd_and_hms(&Utc, 2024, 1, 1, 0, 0, i).unwrap(),
None,
&project,
cx,
)
}
cx.run_until_parked();
// Confirm the thread is not visible and View More is shown.
let entries = visible_entries_as_strings(&sidebar, cx);
assert!(
entries.iter().any(|e| e.contains("View More")),
"should have View More button"
);
assert!(
!entries.iter().any(|e| e.contains("Hidden gem")),
"Hidden gem should be behind View More"
);
// User searches for the hidden thread — it appears, and View More is gone.
type_in_search(&sidebar, "hidden gem", cx);
let filtered = visible_entries_as_strings(&sidebar, cx);
assert_eq!(
filtered,
vec![
//
"v [my-project]",
" Hidden gem thread <== selected",
]
);
assert!(
!filtered.iter().any(|e| e.contains("View More")),
"View More should not appear when filtering"
);
}
#[gpui::test]
async fn test_search_finds_threads_inside_collapsed_groups(cx: &mut TestAppContext) {
let project = init_test_project("/my-project", cx).await;
@ -2341,7 +2137,6 @@ async fn test_confirm_on_historical_thread_in_new_project_group_opens_real_threa
key: project_b_key.clone(),
workspaces: Vec::new(),
expanded: true,
visible_thread_count: None,
});
});
@ -3942,9 +3737,6 @@ async fn test_clicking_worktree_thread_does_not_briefly_render_as_separate_proje
title, worktree_name
);
}
ListEntry::ViewMore { .. } => {
panic!("unexpected `View More` entry while opening linked worktree thread");
}
}
}

View file

@ -50,10 +50,6 @@ actions!(
NextThread,
/// Activates the previous thread in sidebar order.
PreviousThread,
/// Expands the thread list for the current project to show more threads.
ShowMoreThreads,
/// Collapses the thread list for the current project to show fewer threads.
ShowFewerThreads,
/// Creates a new thread in the current workspace.
NewThread,
/// Moves the active project to a new window.
@ -272,20 +268,17 @@ pub struct ProjectGroup {
pub key: ProjectGroupKey,
pub workspaces: Vec<Entity<Workspace>>,
pub expanded: bool,
pub visible_thread_count: Option<usize>,
}
pub struct SerializedProjectGroupState {
pub key: ProjectGroupKey,
pub expanded: bool,
pub visible_thread_count: Option<usize>,
}
#[derive(Clone)]
pub struct ProjectGroupState {
pub key: ProjectGroupKey,
pub expanded: bool,
pub visible_thread_count: Option<usize>,
}
pub struct MultiWorkspace {
@ -641,7 +634,6 @@ impl MultiWorkspace {
ProjectGroupState {
key,
expanded: true,
visible_thread_count: None,
},
);
}
@ -757,23 +749,14 @@ impl MultiWorkspace {
_cx: &mut Context<Self>,
) {
let mut restored: Vec<ProjectGroupState> = Vec::new();
for SerializedProjectGroupState {
key,
expanded,
visible_thread_count,
} in groups
{
for SerializedProjectGroupState { key, expanded } in groups {
if key.path_list().paths().is_empty() {
continue;
}
if restored.iter().any(|group| group.key == key) {
continue;
}
restored.push(ProjectGroupState {
key,
expanded,
visible_thread_count,
});
restored.push(ProjectGroupState { key, expanded });
}
for existing in std::mem::take(&mut self.project_groups) {
if !restored.iter().any(|group| group.key == existing.key) {
@ -802,7 +785,6 @@ impl MultiWorkspace {
.cloned()
.collect(),
expanded: group.expanded,
visible_thread_count: group.visible_thread_count,
})
.collect()
}
@ -830,12 +812,6 @@ impl MultiWorkspace {
}
}
pub fn set_all_groups_visible_thread_count(&mut self, count: Option<usize>) {
for group in &mut self.project_groups {
group.visible_thread_count = count;
}
}
pub fn workspaces_for_project_group(
&self,
key: &ProjectGroupKey,
@ -1329,7 +1305,6 @@ impl MultiWorkspace {
crate::persistence::model::SerializedProjectGroup::from_group(
&group.key,
group.expanded,
group.visible_thread_count,
)
})
.collect::<Vec<_>>(),
@ -1471,7 +1446,6 @@ impl MultiWorkspace {
#[cfg(any(test, feature = "test-support"))]
pub fn test_expand_all_groups(&mut self) {
self.set_all_groups_expanded(true);
self.set_all_groups_visible_thread_count(Some(10_000));
}
#[cfg(any(test, feature = "test-support"))]
@ -1527,7 +1501,6 @@ impl MultiWorkspace {
self.project_groups.push(ProjectGroupState {
key: group.key,
expanded: group.expanded,
visible_thread_count: group.visible_thread_count,
});
}

View file

@ -66,8 +66,6 @@ pub struct SerializedProjectGroup {
pub(crate) location: SerializedWorkspaceLocation,
#[serde(default = "default_expanded")]
pub expanded: bool,
#[serde(default)]
pub visible_thread_count: Option<usize>,
}
fn default_expanded() -> bool {
@ -75,11 +73,7 @@ fn default_expanded() -> bool {
}
impl SerializedProjectGroup {
pub fn from_group(
key: &ProjectGroupKey,
expanded: bool,
visible_thread_count: Option<usize>,
) -> Self {
pub fn from_group(key: &ProjectGroupKey, expanded: bool) -> Self {
Self {
path_list: key.path_list().serialize(),
location: match key.host() {
@ -87,7 +81,6 @@ impl SerializedProjectGroup {
None => SerializedWorkspaceLocation::Local,
},
expanded,
visible_thread_count,
}
}
@ -100,7 +93,6 @@ impl SerializedProjectGroup {
SerializedProjectGroupState {
key: ProjectGroupKey::new(host, path_list),
expanded: self.expanded,
visible_thread_count: self.visible_thread_count,
}
}
}

View file

@ -33,9 +33,9 @@ pub use dock::Panel;
pub use multi_workspace::{
CloseWorkspaceSidebar, DraggedSidebar, FocusWorkspaceSidebar, MoveProjectToNewWindow,
MultiWorkspace, MultiWorkspaceEvent, NewThread, NextProject, NextThread, PreviousProject,
PreviousThread, ProjectGroup, ProjectGroupKey, SerializedProjectGroupState, ShowFewerThreads,
ShowMoreThreads, Sidebar, SidebarEvent, SidebarHandle, SidebarRenderState, SidebarSide,
ToggleWorkspaceSidebar, sidebar_side_context_menu,
PreviousThread, ProjectGroup, ProjectGroupKey, SerializedProjectGroupState, Sidebar,
SidebarEvent, SidebarHandle, SidebarRenderState, SidebarSide, ToggleWorkspaceSidebar,
sidebar_side_context_menu,
};
pub use path_list::{PathList, SerializedPathList};
pub use remote::{
@ -8802,11 +8802,7 @@ pub async fn apply_restored_multiworkspace_state(
// stale keys from previous sessions get normalized and deduped.
let mut resolved_groups: Vec<SerializedProjectGroupState> = Vec::new();
for serialized in project_groups.iter().cloned() {
let SerializedProjectGroupState {
key,
expanded,
visible_thread_count,
} = serialized.into_restored_state();
let SerializedProjectGroupState { key, expanded } = serialized.into_restored_state();
if key.path_list().paths().is_empty() {
continue;
}
@ -8827,7 +8823,6 @@ pub async fn apply_restored_multiworkspace_state(
resolved_groups.push(SerializedProjectGroupState {
key: resolved,
expanded,
visible_thread_count,
});
}
}