mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-07 02:57:34 +00:00
Add filtering support
This commit is contained in:
parent
4c27f4453c
commit
012543052b
1 changed files with 240 additions and 223 deletions
|
@ -17,7 +17,7 @@ mod contact_finder;
|
||||||
// Client, Contact, User, UserStore,
|
// Client, Contact, User, UserStore,
|
||||||
// };
|
// };
|
||||||
use contact_finder::ContactFinder;
|
use contact_finder::ContactFinder;
|
||||||
use menu::Confirm;
|
use menu::{Cancel, Confirm, SelectNext, SelectPrev};
|
||||||
use rpc::proto;
|
use rpc::proto;
|
||||||
use theme::{ActiveTheme, ThemeSettings};
|
use theme::{ActiveTheme, ThemeSettings};
|
||||||
// use context_menu::{ContextMenu, ContextMenuItem};
|
// use context_menu::{ContextMenu, ContextMenuItem};
|
||||||
|
@ -170,10 +170,10 @@ use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt};
|
||||||
use fuzzy::{match_strings, StringMatchCandidate};
|
use fuzzy::{match_strings, StringMatchCandidate};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, img, overlay, prelude::*, px, rems, serde_json, Action, AppContext,
|
actions, div, img, overlay, prelude::*, px, rems, serde_json, Action, AppContext,
|
||||||
AsyncWindowContext, ClipboardItem, DismissEvent, Div, EventEmitter, FocusHandle, Focusable,
|
AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div, EventEmitter, FocusHandle,
|
||||||
FocusableView, InteractiveElement, IntoElement, Model, MouseDownEvent, ParentElement, Pixels,
|
Focusable, FocusableView, InteractiveElement, IntoElement, Model, MouseDownEvent,
|
||||||
Point, PromptLevel, Render, RenderOnce, SharedString, Stateful, Styled, Subscription, Task,
|
ParentElement, Pixels, Point, PromptLevel, Render, RenderOnce, SharedString, Stateful, Styled,
|
||||||
View, ViewContext, VisualContext, WeakView,
|
Subscription, Task, View, ViewContext, VisualContext, WeakView,
|
||||||
};
|
};
|
||||||
use project::{Fs, Project};
|
use project::{Fs, Project};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
@ -399,28 +399,28 @@ impl CollabPanel {
|
||||||
editor
|
editor
|
||||||
});
|
});
|
||||||
|
|
||||||
// cx.subscribe(&filter_editor, |this, _, event, cx| {
|
cx.subscribe(&filter_editor, |this: &mut Self, _, event, cx| {
|
||||||
// if let editor::Event::BufferEdited = event {
|
if let editor::EditorEvent::BufferEdited = event {
|
||||||
// let query = this.filter_editor.read(cx).text(cx);
|
let query = this.filter_editor.read(cx).text(cx);
|
||||||
// if !query.is_empty() {
|
if !query.is_empty() {
|
||||||
// this.selection.take();
|
this.selection.take();
|
||||||
// }
|
}
|
||||||
// this.update_entries(true, cx);
|
this.update_entries(true, cx);
|
||||||
// if !query.is_empty() {
|
if !query.is_empty() {
|
||||||
// this.selection = this
|
this.selection = this
|
||||||
// .entries
|
.entries
|
||||||
// .iter()
|
.iter()
|
||||||
// .position(|entry| !matches!(entry, ListEntry::Header(_)));
|
.position(|entry| !matches!(entry, ListEntry::Header(_)));
|
||||||
// }
|
}
|
||||||
// } else if let editor::Event::Blurred = event {
|
} else if let editor::EditorEvent::Blurred = event {
|
||||||
// let query = this.filter_editor.read(cx).text(cx);
|
let query = this.filter_editor.read(cx).text(cx);
|
||||||
// if query.is_empty() {
|
if query.is_empty() {
|
||||||
// this.selection.take();
|
this.selection.take();
|
||||||
// this.update_entries(true, cx);
|
this.update_entries(true, cx);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// })
|
})
|
||||||
// .detach();
|
.detach();
|
||||||
|
|
||||||
let channel_name_editor = cx.build_view(|cx| Editor::single_line(cx));
|
let channel_name_editor = cx.build_view(|cx| Editor::single_line(cx));
|
||||||
|
|
||||||
|
@ -1786,26 +1786,27 @@ impl CollabPanel {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
|
fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
|
||||||
// if self.take_editing_state(cx) {
|
if self.take_editing_state(cx) {
|
||||||
// cx.focus(&self.filter_editor);
|
cx.focus_view(&self.filter_editor);
|
||||||
// } else {
|
} else {
|
||||||
// self.filter_editor.update(cx, |editor, cx| {
|
self.filter_editor.update(cx, |editor, cx| {
|
||||||
// if editor.buffer().read(cx).len(cx) > 0 {
|
if editor.buffer().read(cx).len(cx) > 0 {
|
||||||
// editor.set_text("", cx);
|
editor.set_text("", cx);
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// self.update_entries(false, cx);
|
self.update_entries(false, cx);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn select_next(&mut self, _: &SelectNext, cx: &mut ViewContext<Self>) {
|
fn select_next(&mut self, _: &SelectNext, cx: &mut ViewContext<Self>) {
|
||||||
// let ix = self.selection.map_or(0, |ix| ix + 1);
|
let ix = self.selection.map_or(0, |ix| ix + 1);
|
||||||
// if ix < self.entries.len() {
|
if ix < self.entries.len() {
|
||||||
// self.selection = Some(ix);
|
self.selection = Some(ix);
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
// todo!()
|
||||||
// self.list_state.reset(self.entries.len());
|
// self.list_state.reset(self.entries.len());
|
||||||
// if let Some(ix) = self.selection {
|
// if let Some(ix) = self.selection {
|
||||||
// self.list_state.scroll_to(ListOffset {
|
// self.list_state.scroll_to(ListOffset {
|
||||||
|
@ -1813,15 +1814,16 @@ impl CollabPanel {
|
||||||
// offset_in_item: 0.,
|
// offset_in_item: 0.,
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
// cx.notify();
|
cx.notify();
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext<Self>) {
|
fn select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext<Self>) {
|
||||||
// let ix = self.selection.take().unwrap_or(0);
|
let ix = self.selection.take().unwrap_or(0);
|
||||||
// if ix > 0 {
|
if ix > 0 {
|
||||||
// self.selection = Some(ix - 1);
|
self.selection = Some(ix - 1);
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
// todo!()
|
||||||
// self.list_state.reset(self.entries.len());
|
// self.list_state.reset(self.entries.len());
|
||||||
// if let Some(ix) = self.selection {
|
// if let Some(ix) = self.selection {
|
||||||
// self.list_state.scroll_to(ListOffset {
|
// self.list_state.scroll_to(ListOffset {
|
||||||
|
@ -1829,33 +1831,33 @@ impl CollabPanel {
|
||||||
// offset_in_item: 0.,
|
// offset_in_item: 0.,
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
// cx.notify();
|
cx.notify();
|
||||||
// }
|
}
|
||||||
|
|
||||||
fn confirm(&mut self, _: &Confirm, cx: &mut ViewContext<Self>) {
|
fn confirm(&mut self, _: &Confirm, cx: &mut ViewContext<Self>) {
|
||||||
if self.confirm_channel_edit(cx) {
|
if self.confirm_channel_edit(cx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if let Some(selection) = self.selection {
|
if let Some(selection) = self.selection {
|
||||||
// if let Some(entry) = self.entries.get(selection) {
|
if let Some(entry) = self.entries.get(selection) {
|
||||||
// match entry {
|
match entry {
|
||||||
// ListEntry::Header(section) => match section {
|
ListEntry::Header(section) => match section {
|
||||||
// Section::ActiveCall => Self::leave_call(cx),
|
Section::ActiveCall => Self::leave_call(cx),
|
||||||
// Section::Channels => self.new_root_channel(cx),
|
Section::Channels => self.new_root_channel(cx),
|
||||||
// Section::Contacts => self.toggle_contact_finder(cx),
|
Section::Contacts => self.toggle_contact_finder(cx),
|
||||||
// Section::ContactRequests
|
Section::ContactRequests
|
||||||
// | Section::Online
|
| Section::Online
|
||||||
// | Section::Offline
|
| Section::Offline
|
||||||
// | Section::ChannelInvites => {
|
| Section::ChannelInvites => {
|
||||||
// self.toggle_section_expanded(*section, cx);
|
self.toggle_section_expanded(*section, cx);
|
||||||
// }
|
}
|
||||||
// },
|
},
|
||||||
// ListEntry::Contact { contact, calling } => {
|
ListEntry::Contact { contact, calling } => {
|
||||||
// if contact.online && !contact.busy && !calling {
|
if contact.online && !contact.busy && !calling {
|
||||||
// self.call(contact.user.id, Some(self.project.clone()), cx);
|
self.call(contact.user.id, cx);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// ListEntry::ParticipantProject {
|
// ListEntry::ParticipantProject {
|
||||||
// project_id,
|
// project_id,
|
||||||
// host_user_id,
|
// host_user_id,
|
||||||
|
@ -1882,33 +1884,28 @@ impl CollabPanel {
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// ListEntry::Channel { channel, .. } => {
|
ListEntry::Channel { channel, .. } => {
|
||||||
// let is_active = maybe!({
|
let is_active = maybe!({
|
||||||
// let call_channel = ActiveCall::global(cx)
|
let call_channel = ActiveCall::global(cx)
|
||||||
// .read(cx)
|
.read(cx)
|
||||||
// .room()?
|
.room()?
|
||||||
// .read(cx)
|
.read(cx)
|
||||||
// .channel_id()?;
|
.channel_id()?;
|
||||||
|
|
||||||
// Some(call_channel == channel.id)
|
Some(call_channel == channel.id)
|
||||||
// })
|
})
|
||||||
// .unwrap_or(false);
|
.unwrap_or(false);
|
||||||
// if is_active {
|
if is_active {
|
||||||
// self.open_channel_notes(
|
self.open_channel_notes(channel.id, cx)
|
||||||
// &OpenChannelNotes {
|
} else {
|
||||||
// channel_id: channel.id,
|
self.join_channel(channel.id, cx)
|
||||||
// },
|
}
|
||||||
// cx,
|
}
|
||||||
// )
|
ListEntry::ContactPlaceholder => self.toggle_contact_finder(cx),
|
||||||
// } else {
|
_ => {}
|
||||||
// self.join_channel(channel.id, cx)
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// ListEntry::ContactPlaceholder => self.toggle_contact_finder(cx),
|
|
||||||
// _ => {}
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_space(&mut self, _: &InsertSpace, cx: &mut ViewContext<Self>) {
|
fn insert_space(&mut self, _: &InsertSpace, cx: &mut ViewContext<Self>) {
|
||||||
|
@ -1975,33 +1972,33 @@ impl CollabPanel {
|
||||||
self.update_entries(false, cx);
|
self.update_entries(false, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn collapse_selected_channel(
|
fn collapse_selected_channel(
|
||||||
// &mut self,
|
&mut self,
|
||||||
// _: &CollapseSelectedChannel,
|
_: &CollapseSelectedChannel,
|
||||||
// cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
// ) {
|
) {
|
||||||
// let Some(channel_id) = self.selected_channel().map(|channel| channel.id) else {
|
let Some(channel_id) = self.selected_channel().map(|channel| channel.id) else {
|
||||||
// return;
|
return;
|
||||||
// };
|
};
|
||||||
|
|
||||||
// if self.is_channel_collapsed(channel_id) {
|
if self.is_channel_collapsed(channel_id) {
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// self.toggle_channel_collapsed(channel_id, cx);
|
self.toggle_channel_collapsed(channel_id, cx);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn expand_selected_channel(&mut self, _: &ExpandSelectedChannel, cx: &mut ViewContext<Self>) {
|
fn expand_selected_channel(&mut self, _: &ExpandSelectedChannel, cx: &mut ViewContext<Self>) {
|
||||||
// let Some(id) = self.selected_channel().map(|channel| channel.id) else {
|
let Some(id) = self.selected_channel().map(|channel| channel.id) else {
|
||||||
// return;
|
return;
|
||||||
// };
|
};
|
||||||
|
|
||||||
// if !self.is_channel_collapsed(id) {
|
if !self.is_channel_collapsed(id) {
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// self.toggle_channel_collapsed(id, cx)
|
self.toggle_channel_collapsed(id, cx)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn toggle_channel_collapsed_action(
|
// fn toggle_channel_collapsed_action(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
|
@ -2030,11 +2027,11 @@ impl CollabPanel {
|
||||||
self.collapsed_channels.binary_search(&channel_id).is_ok()
|
self.collapsed_channels.binary_search(&channel_id).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn leave_call(cx: &mut ViewContext<Self>) {
|
fn leave_call(cx: &mut ViewContext<Self>) {
|
||||||
// ActiveCall::global(cx)
|
ActiveCall::global(cx)
|
||||||
// .update(cx, |call, cx| call.hang_up(cx))
|
.update(cx, |call, cx| call.hang_up(cx))
|
||||||
// .detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
// }
|
}
|
||||||
|
|
||||||
fn toggle_contact_finder(&mut self, cx: &mut ViewContext<Self>) {
|
fn toggle_contact_finder(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
if let Some(workspace) = self.workspace.upgrade() {
|
if let Some(workspace) = self.workspace.upgrade() {
|
||||||
|
@ -2154,13 +2151,13 @@ impl CollabPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn show_inline_context_menu(&mut self, _: &menu::ShowContextMenu, cx: &mut ViewContext<Self>) {
|
fn show_inline_context_menu(&mut self, _: &menu::ShowContextMenu, cx: &mut ViewContext<Self>) {
|
||||||
// let Some(channel) = self.selected_channel() else {
|
let Some(channel) = self.selected_channel() else {
|
||||||
// return;
|
return;
|
||||||
// };
|
};
|
||||||
|
|
||||||
// self.deploy_channel_context_menu(None, &channel.clone(), self.selection.unwrap(), cx);
|
self.deploy_channel_context_menu(todo!(), channel.id, self.selection.unwrap(), cx);
|
||||||
// }
|
}
|
||||||
|
|
||||||
fn selected_channel(&self) -> Option<&Arc<Channel>> {
|
fn selected_channel(&self) -> Option<&Arc<Channel>> {
|
||||||
self.selection
|
self.selection
|
||||||
|
@ -2350,15 +2347,19 @@ impl CollabPanel {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_signed_in(&mut self, cx: &mut ViewContext<Self>) -> List {
|
fn render_signed_in(&mut self, cx: &mut ViewContext<Self>) -> Div {
|
||||||
let is_selected = false; // todo!() this.selection == Some(ix);
|
div()
|
||||||
|
.child(
|
||||||
List::new().children(
|
div()
|
||||||
self.entries
|
.m_2()
|
||||||
.clone()
|
.rounded(px(2.0))
|
||||||
.into_iter()
|
.child(self.filter_editor.clone()),
|
||||||
.enumerate()
|
)
|
||||||
.map(|(ix, entry)| match entry {
|
.child(
|
||||||
|
List::new().children(self.entries.clone().into_iter().enumerate().map(
|
||||||
|
|(ix, entry)| {
|
||||||
|
let is_selected = self.selection == Some(ix);
|
||||||
|
match entry {
|
||||||
ListEntry::Header(section) => {
|
ListEntry::Header(section) => {
|
||||||
let is_collapsed = self.collapsed_sections.contains(§ion);
|
let is_collapsed = self.collapsed_sections.contains(§ion);
|
||||||
self.render_header(section, is_selected, is_collapsed, cx)
|
self.render_header(section, is_selected, is_collapsed, cx)
|
||||||
|
@ -2386,7 +2387,9 @@ impl CollabPanel {
|
||||||
ListEntry::ChannelEditor { depth } => {
|
ListEntry::ChannelEditor { depth } => {
|
||||||
self.render_channel_editor(depth, cx).into_any_element()
|
self.render_channel_editor(depth, cx).into_any_element()
|
||||||
}
|
}
|
||||||
}),
|
}
|
||||||
|
},
|
||||||
|
)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2494,6 +2497,7 @@ impl CollabPanel {
|
||||||
el.child(
|
el.child(
|
||||||
ListItem::new(text.clone())
|
ListItem::new(text.clone())
|
||||||
.child(div().w_full().child(Label::new(text)))
|
.child(div().w_full().child(Label::new(text)))
|
||||||
|
.selected(is_selected)
|
||||||
.toggle(Some(!is_collapsed))
|
.toggle(Some(!is_collapsed))
|
||||||
.on_click(cx.listener(move |this, _, cx| {
|
.on_click(cx.listener(move |this, _, cx| {
|
||||||
this.toggle_section_expanded(section, cx)
|
this.toggle_section_expanded(section, cx)
|
||||||
|
@ -3214,23 +3218,36 @@ impl CollabPanel {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
impl Render for CollabPanel {
|
impl Render for CollabPanel {
|
||||||
type Element = Focusable<Stateful<Div>>;
|
type Element = Focusable<Div>;
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||||
div()
|
v_stack()
|
||||||
.id("collab-panel")
|
|
||||||
.key_context("CollabPanel")
|
.key_context("CollabPanel")
|
||||||
|
.on_action(cx.listener(CollabPanel::cancel))
|
||||||
|
.on_action(cx.listener(CollabPanel::select_next))
|
||||||
|
.on_action(cx.listener(CollabPanel::select_prev))
|
||||||
|
.on_action(cx.listener(CollabPanel::confirm))
|
||||||
|
.on_action(cx.listener(CollabPanel::insert_space))
|
||||||
|
// .on_action(cx.listener(CollabPanel::remove))
|
||||||
|
.on_action(cx.listener(CollabPanel::remove_selected_channel))
|
||||||
|
.on_action(cx.listener(CollabPanel::show_inline_context_menu))
|
||||||
|
// .on_action(cx.listener(CollabPanel::new_subchannel))
|
||||||
|
// .on_action(cx.listener(CollabPanel::invite_members))
|
||||||
|
// .on_action(cx.listener(CollabPanel::manage_members))
|
||||||
|
.on_action(cx.listener(CollabPanel::rename_selected_channel))
|
||||||
|
// .on_action(cx.listener(CollabPanel::rename_channel))
|
||||||
|
// .on_action(cx.listener(CollabPanel::toggle_channel_collapsed_action))
|
||||||
|
.on_action(cx.listener(CollabPanel::collapse_selected_channel))
|
||||||
|
.on_action(cx.listener(CollabPanel::expand_selected_channel))
|
||||||
|
// .on_action(cx.listener(CollabPanel::open_channel_notes))
|
||||||
|
// .on_action(cx.listener(CollabPanel::join_channel_chat))
|
||||||
|
// .on_action(cx.listener(CollabPanel::copy_channel_link))
|
||||||
.track_focus(&self.focus_handle)
|
.track_focus(&self.focus_handle)
|
||||||
.size_full()
|
.size_full()
|
||||||
.overflow_scroll()
|
.child(if self.user_store.read(cx).current_user().is_none() {
|
||||||
.on_action(cx.listener(Self::confirm))
|
self.render_signed_out(cx)
|
||||||
.on_action(cx.listener(Self::insert_space))
|
|
||||||
.map(|el| {
|
|
||||||
if self.user_store.read(cx).current_user().is_none() {
|
|
||||||
el.child(self.render_signed_out(cx))
|
|
||||||
} else {
|
} else {
|
||||||
el.child(self.render_signed_in(cx))
|
self.render_signed_in(cx)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.children(self.context_menu.as_ref().map(|(menu, position, _)| {
|
.children(self.context_menu.as_ref().map(|(menu, position, _)| {
|
||||||
overlay()
|
overlay()
|
||||||
|
@ -3392,8 +3409,8 @@ impl Panel for CollabPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FocusableView for CollabPanel {
|
impl FocusableView for CollabPanel {
|
||||||
fn focus_handle(&self, _cx: &AppContext) -> gpui::FocusHandle {
|
fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle {
|
||||||
self.focus_handle.clone()
|
self.filter_editor.focus_handle(cx).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue