Add persistence to the Show Occupied Channels collab toggle (#53029)
This PR adds persistence to the toggle state for the `Show Occupied Channels` filter. Also, while driving by, I: - renamed a few variables to use `occupied` over `active`, which should've happened in https://github.com/zed-industries/zed/pull/52531. - extracted `"favorite_channels"` into a global Self-Review Checklist: - [X] I've reviewed my own diff for quality, security, and reliability - [X] Unsafe blocks (if any) have justifying comments - [X] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [X] Performance impact has been considered and is acceptable Closes #ISSUE Release Notes: - Added persistence to the `Show Occupied Channels` collab toggle.
This commit is contained in:
1 parent
3eeaf0d4ae
commit
b2bf725663
1 file changed
+58
-16
@@ -44,6 +44,9 @@ use workspace::{
|
||||
notifications::{DetachAndPromptErr, NotifyResultExt},
|
||||
};
|
||||
|
||||
const FILTER_OCCUPIED_CHANNELS_KEY: &str = "filter_occupied_channels";
|
||||
const FAVORITE_CHANNELS_KEY: &str = "favorite_channels";
|
||||
|
||||
actions!(
|
||||
collab_panel,
|
||||
[
|
||||
@@ -244,7 +247,9 @@ pub struct CollabPanel {
|
||||
fs: Arc<dyn Fs>,
|
||||
focus_handle: FocusHandle,
|
||||
channel_clipboard: Option<ChannelMoveClipboard>,
|
||||
pending_serialization: Task<Option<()>>,
|
||||
pending_panel_serialization: Task<Option<()>>,
|
||||
pending_favorites_serialization: Task<Option<()>>,
|
||||
pending_filter_serialization: Task<Option<()>>,
|
||||
context_menu: Option<(Entity<ContextMenu>, Point<Pixels>, Subscription)>,
|
||||
list_state: ListState,
|
||||
filter_editor: Entity<Editor>,
|
||||
@@ -260,7 +265,7 @@ pub struct CollabPanel {
|
||||
subscriptions: Vec<Subscription>,
|
||||
collapsed_sections: Vec<Section>,
|
||||
collapsed_channels: Vec<ChannelId>,
|
||||
filter_active_channels: bool,
|
||||
filter_occupied_channels: bool,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
}
|
||||
|
||||
@@ -378,7 +383,9 @@ impl CollabPanel {
|
||||
focus_handle: cx.focus_handle(),
|
||||
channel_clipboard: None,
|
||||
fs: workspace.app_state().fs.clone(),
|
||||
pending_serialization: Task::ready(None),
|
||||
pending_panel_serialization: Task::ready(None),
|
||||
pending_favorites_serialization: Task::ready(None),
|
||||
pending_filter_serialization: Task::ready(None),
|
||||
context_menu: None,
|
||||
list_state: ListState::new(0, gpui::ListAlignment::Top, px(1000.)),
|
||||
channel_name_editor,
|
||||
@@ -393,7 +400,7 @@ impl CollabPanel {
|
||||
match_candidates: Vec::default(),
|
||||
collapsed_sections: vec![Section::Offline],
|
||||
collapsed_channels: Vec::default(),
|
||||
filter_active_channels: false,
|
||||
filter_occupied_channels: false,
|
||||
workspace: workspace.weak_handle(),
|
||||
client: workspace.app_state().client.clone(),
|
||||
};
|
||||
@@ -474,8 +481,22 @@ impl CollabPanel {
|
||||
});
|
||||
}
|
||||
|
||||
let filter_occupied_channels = KeyValueStore::global(cx)
|
||||
.read_kvp(FILTER_OCCUPIED_CHANNELS_KEY)
|
||||
.ok()
|
||||
.flatten()
|
||||
.is_some();
|
||||
|
||||
panel.update(cx, |panel, cx| {
|
||||
panel.filter_occupied_channels = filter_occupied_channels;
|
||||
|
||||
if filter_occupied_channels {
|
||||
panel.update_entries(false, cx);
|
||||
}
|
||||
});
|
||||
|
||||
let favorites: Vec<ChannelId> = KeyValueStore::global(cx)
|
||||
.read_kvp("favorite_channels")
|
||||
.read_kvp(FAVORITE_CHANNELS_KEY)
|
||||
.ok()
|
||||
.flatten()
|
||||
.and_then(|json| serde_json::from_str::<Vec<u64>>(&json).ok())
|
||||
@@ -520,7 +541,7 @@ impl CollabPanel {
|
||||
};
|
||||
|
||||
let kvp = KeyValueStore::global(cx);
|
||||
self.pending_serialization = cx.background_spawn(
|
||||
self.pending_panel_serialization = cx.background_spawn(
|
||||
async move {
|
||||
kvp.write_kvp(
|
||||
serialization_key,
|
||||
@@ -780,14 +801,14 @@ 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
|
||||
if self.filter_occupied_channels {
|
||||
let occupied_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));
|
||||
channels.retain(|channel| occupied_channel_ids_or_ancestors.contains(&channel.id));
|
||||
}
|
||||
|
||||
if let Some(state) = &self.channel_editing_state
|
||||
@@ -796,7 +817,7 @@ impl CollabPanel {
|
||||
self.entries.push(ListEntry::ChannelEditor { depth: 0 });
|
||||
}
|
||||
|
||||
let should_respect_collapse = query.is_empty() && !self.filter_active_channels;
|
||||
let should_respect_collapse = query.is_empty() && !self.filter_occupied_channels;
|
||||
let mut collapse_depth = None;
|
||||
|
||||
for (idx, channel) in channels.into_iter().enumerate() {
|
||||
@@ -1970,6 +1991,26 @@ impl CollabPanel {
|
||||
self.channel_store.read(cx).is_channel_favorited(channel_id)
|
||||
}
|
||||
|
||||
fn persist_filter_occupied_channels(&mut self, cx: &mut Context<Self>) {
|
||||
let is_enabled = self.filter_occupied_channels;
|
||||
let kvp_store = KeyValueStore::global(cx);
|
||||
self.pending_filter_serialization = cx.background_spawn(
|
||||
async move {
|
||||
if is_enabled {
|
||||
kvp_store
|
||||
.write_kvp(FILTER_OCCUPIED_CHANNELS_KEY.to_string(), "1".to_string())
|
||||
.await?;
|
||||
} else {
|
||||
kvp_store
|
||||
.delete_kvp(FILTER_OCCUPIED_CHANNELS_KEY.to_string())
|
||||
.await?;
|
||||
}
|
||||
anyhow::Ok(())
|
||||
}
|
||||
.log_err(),
|
||||
);
|
||||
}
|
||||
|
||||
fn persist_favorites(&mut self, cx: &mut Context<Self>) {
|
||||
let favorite_ids: Vec<u64> = self
|
||||
.channel_store
|
||||
@@ -1979,11 +2020,11 @@ impl CollabPanel {
|
||||
.map(|id| id.0)
|
||||
.collect();
|
||||
let kvp_store = KeyValueStore::global(cx);
|
||||
self.pending_serialization = cx.background_spawn(
|
||||
self.pending_favorites_serialization = cx.background_spawn(
|
||||
async move {
|
||||
let json = serde_json::to_string(&favorite_ids)?;
|
||||
kvp_store
|
||||
.write_kvp("favorite_channels".to_string(), json)
|
||||
.write_kvp(FAVORITE_CHANNELS_KEY.to_string(), json)
|
||||
.await?;
|
||||
anyhow::Ok(())
|
||||
}
|
||||
@@ -2843,14 +2884,15 @@ impl CollabPanel {
|
||||
Some(
|
||||
h_flex()
|
||||
.child(
|
||||
IconButton::new("filter-active-channels", IconName::ListFilter)
|
||||
IconButton::new("filter-occupied-channels", IconName::ListFilter)
|
||||
.icon_size(IconSize::Small)
|
||||
.toggle_state(self.filter_active_channels)
|
||||
.toggle_state(self.filter_occupied_channels)
|
||||
.on_click(cx.listener(|this, _, _window, cx| {
|
||||
this.filter_active_channels = !this.filter_active_channels;
|
||||
this.filter_occupied_channels = !this.filter_occupied_channels;
|
||||
this.update_entries(true, cx);
|
||||
this.persist_filter_occupied_channels(cx);
|
||||
}))
|
||||
.tooltip(Tooltip::text(if self.filter_active_channels {
|
||||
.tooltip(Tooltip::text(if self.filter_occupied_channels {
|
||||
"Show All Channels"
|
||||
} else {
|
||||
"Show Occupied Channels"
|
||||
|
||||
Reference in new issue
Block a user