From 3f53a3a8ab3566ea2b283b7cffbb8ac6031aac28 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Mon, 9 Feb 2026 18:17:45 -0500 Subject: [PATCH] Add a `Show All Channels` button to the collab panel (#48826) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it easy to see all the activity that is happening in a more condensed view. Helps you fend off endless scrolling in the collaboration panel when trying to find the meeting room. ⚔️ https://github.com/user-attachments/assets/5b538636-5672-42a4-a831-ffe303051c84 - [X] Tests or screenshots needed? - [ ] Code Reviewed - [X] Manual QA Release Notes: - Added a `Show All Channels` button to the collab panel to filter down to only channels with participants. --- crates/collab_ui/src/collab_panel.rs | 50 ++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/crates/collab_ui/src/collab_panel.rs b/crates/collab_ui/src/collab_panel.rs index 663d64d56d3e9832a6a92c2916fa62d22afd23e6..60262951ef916183bdaf72df90ab39f2edd83f27 100644 --- a/crates/collab_ui/src/collab_panel.rs +++ b/crates/collab_ui/src/collab_panel.rs @@ -227,6 +227,7 @@ pub struct CollabPanel { subscriptions: Vec, collapsed_sections: Vec
, collapsed_channels: Vec, + filter_active_channels: bool, workspace: WeakEntity, } @@ -359,6 +360,7 @@ impl CollabPanel { match_candidates: Vec::default(), collapsed_sections: vec![Section::Offline], collapsed_channels: Vec::default(), + filter_active_channels: false, workspace: workspace.weak_handle(), client: workspace.app_state().client.clone(), }; @@ -679,13 +681,23 @@ impl CollabPanel { channels.retain(|chan| channel_ids_of_matches_or_parents.contains(&chan.id)); + if self.filter_active_channels { + let active_channel_ids_or_ancestors: HashSet<_> = channel_store + .ordered_channels() + .map(|(_, channel)| channel) + .filter(|channel| !channel_store.channel_participants(channel.id).is_empty()) + .flat_map(|channel| channel.parent_path.iter().copied().chain(Some(channel.id))) + .collect(); + channels.retain(|channel| active_channel_ids_or_ancestors.contains(&channel.id)); + } + if let Some(state) = &self.channel_editing_state && matches!(state, ChannelEditingState::Create { location: None, .. }) { self.entries.push(ListEntry::ChannelEditor { depth: 0 }); } - let should_respect_collapse = query.is_empty(); + let should_respect_collapse = query.is_empty() && !self.filter_active_channels; let mut collapse_depth = None; for (idx, channel) in channels.into_iter().enumerate() { @@ -2554,12 +2566,36 @@ impl CollabPanel { .tooltip(Tooltip::text("Search for new contact")) .into_any_element(), ), - Section::Channels => Some( - IconButton::new("add-channel", IconName::Plus) - .on_click(cx.listener(|this, _, window, cx| this.new_root_channel(window, cx))) - .tooltip(Tooltip::text("Create a channel")) - .into_any_element(), - ), + Section::Channels => { + Some( + h_flex() + .gap_1() + .child( + IconButton::new("filter-active-channels", IconName::ListFilter) + .toggle_state(self.filter_active_channels) + .when(!self.filter_active_channels, |button| { + button.visible_on_hover("section-header") + }) + .on_click(cx.listener(|this, _, _window, cx| { + this.filter_active_channels = !this.filter_active_channels; + this.update_entries(true, cx); + })) + .tooltip(Tooltip::text(if self.filter_active_channels { + "Show All Channels" + } else { + "Show Active Channels" + })), + ) + .child( + IconButton::new("add-channel", IconName::Plus) + .on_click(cx.listener(|this, _, window, cx| { + this.new_root_channel(window, cx) + })) + .tooltip(Tooltip::text("Create a channel")), + ) + .into_any_element(), + ) + } _ => None, };