collab_ui: Show parents when searching channels (#42005)
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This commit is contained in:
co-authored by
Danilo Leal
parent
81e87c4cd6
commit
366a5db2c0
@@ -7,10 +7,11 @@ use anyhow::Context as _;
|
||||
use call::ActiveCall;
|
||||
use channel::{Channel, ChannelEvent, ChannelStore};
|
||||
use client::{ChannelId, Client, Contact, User, UserStore};
|
||||
use collections::{HashMap, HashSet};
|
||||
use contact_finder::ContactFinder;
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
use fuzzy::{StringMatchCandidate, match_strings};
|
||||
use fuzzy::{StringMatch, StringMatchCandidate, match_strings};
|
||||
use gpui::{
|
||||
AnyElement, App, AsyncWindowContext, Bounds, ClickEvent, ClipboardItem, Context, DismissEvent,
|
||||
Div, Entity, EventEmitter, FocusHandle, Focusable, FontStyle, InteractiveElement, IntoElement,
|
||||
@@ -30,9 +31,9 @@ use smallvec::SmallVec;
|
||||
use std::{mem, sync::Arc};
|
||||
use theme::{ActiveTheme, ThemeSettings};
|
||||
use ui::{
|
||||
Avatar, AvatarAvailabilityIndicator, Button, Color, ContextMenu, Facepile, Icon, IconButton,
|
||||
IconName, IconSize, Indicator, Label, ListHeader, ListItem, Tooltip, prelude::*,
|
||||
tooltip_container,
|
||||
Avatar, AvatarAvailabilityIndicator, Button, Color, ContextMenu, Facepile, HighlightedLabel,
|
||||
Icon, IconButton, IconName, IconSize, Indicator, Label, ListHeader, ListItem, Tooltip,
|
||||
prelude::*, tooltip_container,
|
||||
};
|
||||
use util::{ResultExt, TryFutureExt, maybe};
|
||||
use workspace::{
|
||||
@@ -261,6 +262,8 @@ enum ListEntry {
|
||||
channel: Arc<Channel>,
|
||||
depth: usize,
|
||||
has_children: bool,
|
||||
// `None` when the channel is a parent of a matched channel.
|
||||
string_match: Option<StringMatch>,
|
||||
},
|
||||
ChannelNotes {
|
||||
channel_id: ChannelId,
|
||||
@@ -630,6 +633,10 @@ impl CollabPanel {
|
||||
.enumerate()
|
||||
.map(|(ix, (_, channel))| StringMatchCandidate::new(ix, &channel.name)),
|
||||
);
|
||||
let mut channels = channel_store
|
||||
.ordered_channels()
|
||||
.map(|(_, chan)| chan)
|
||||
.collect::<Vec<_>>();
|
||||
let matches = executor.block(match_strings(
|
||||
&self.match_candidates,
|
||||
&query,
|
||||
@@ -639,14 +646,34 @@ impl CollabPanel {
|
||||
&Default::default(),
|
||||
executor.clone(),
|
||||
));
|
||||
|
||||
let matches_by_id: HashMap<_, _> = matches
|
||||
.iter()
|
||||
.map(|mat| (channels[mat.candidate_id].id, mat.clone()))
|
||||
.collect();
|
||||
|
||||
let channel_ids_of_matches_or_parents: HashSet<_> = matches
|
||||
.iter()
|
||||
.flat_map(|mat| {
|
||||
let match_channel = channels[mat.candidate_id];
|
||||
|
||||
match_channel
|
||||
.parent_path
|
||||
.iter()
|
||||
.copied()
|
||||
.chain(Some(match_channel.id))
|
||||
})
|
||||
.collect();
|
||||
|
||||
channels.retain(|chan| channel_ids_of_matches_or_parents.contains(&chan.id));
|
||||
|
||||
if let Some(state) = &self.channel_editing_state
|
||||
&& matches!(state, ChannelEditingState::Create { location: None, .. })
|
||||
{
|
||||
self.entries.push(ListEntry::ChannelEditor { depth: 0 });
|
||||
}
|
||||
let mut collapse_depth = None;
|
||||
for mat in matches {
|
||||
let channel = channel_store.channel_at_index(mat.candidate_id).unwrap();
|
||||
for (idx, channel) in channels.into_iter().enumerate() {
|
||||
let depth = channel.parent_path.len();
|
||||
|
||||
if collapse_depth.is_none() && self.is_channel_collapsed(channel.id) {
|
||||
@@ -663,7 +690,7 @@ impl CollabPanel {
|
||||
}
|
||||
|
||||
let has_children = channel_store
|
||||
.channel_at_index(mat.candidate_id + 1)
|
||||
.channel_at_index(idx + 1)
|
||||
.is_some_and(|next_channel| next_channel.parent_path.ends_with(&[channel.id]));
|
||||
|
||||
match &self.channel_editing_state {
|
||||
@@ -675,6 +702,7 @@ impl CollabPanel {
|
||||
channel: channel.clone(),
|
||||
depth,
|
||||
has_children: false,
|
||||
string_match: matches_by_id.get(&channel.id).map(|mat| (*mat).clone()),
|
||||
});
|
||||
self.entries
|
||||
.push(ListEntry::ChannelEditor { depth: depth + 1 });
|
||||
@@ -690,6 +718,7 @@ impl CollabPanel {
|
||||
channel: channel.clone(),
|
||||
depth,
|
||||
has_children,
|
||||
string_match: matches_by_id.get(&channel.id).map(|mat| (*mat).clone()),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2321,8 +2350,17 @@ impl CollabPanel {
|
||||
channel,
|
||||
depth,
|
||||
has_children,
|
||||
string_match,
|
||||
} => self
|
||||
.render_channel(channel, *depth, *has_children, is_selected, ix, cx)
|
||||
.render_channel(
|
||||
channel,
|
||||
*depth,
|
||||
*has_children,
|
||||
is_selected,
|
||||
ix,
|
||||
string_match.as_ref(),
|
||||
cx,
|
||||
)
|
||||
.into_any_element(),
|
||||
ListEntry::ChannelEditor { depth } => self
|
||||
.render_channel_editor(*depth, window, cx)
|
||||
@@ -2719,6 +2757,7 @@ impl CollabPanel {
|
||||
has_children: bool,
|
||||
is_selected: bool,
|
||||
ix: usize,
|
||||
string_match: Option<&StringMatch>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl IntoElement {
|
||||
let channel_id = channel.id;
|
||||
@@ -2855,7 +2894,14 @@ impl CollabPanel {
|
||||
.child(
|
||||
h_flex()
|
||||
.id(channel_id.0 as usize)
|
||||
.child(Label::new(channel.name.clone()))
|
||||
.child(match string_match {
|
||||
None => Label::new(channel.name.clone()).into_any_element(),
|
||||
Some(string_match) => HighlightedLabel::new(
|
||||
channel.name.clone(),
|
||||
string_match.positions.clone(),
|
||||
)
|
||||
.into_any_element(),
|
||||
})
|
||||
.children(face_pile.map(|face_pile| face_pile.p_1())),
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user