Channel Context Menu
This commit is contained in:
parent
ee260a5e24
commit
41e7653906
2 changed files with 195 additions and 183 deletions
|
@ -151,10 +151,10 @@ actions!(
|
||||||
// ]
|
// ]
|
||||||
// );
|
// );
|
||||||
|
|
||||||
// #[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
// struct ChannelMoveClipboard {
|
struct ChannelMoveClipboard {
|
||||||
// channel_id: ChannelId,
|
channel_id: ChannelId,
|
||||||
// }
|
}
|
||||||
|
|
||||||
const COLLABORATION_PANEL_KEY: &'static str = "CollaborationPanel";
|
const COLLABORATION_PANEL_KEY: &'static str = "CollaborationPanel";
|
||||||
|
|
||||||
|
@ -168,10 +168,11 @@ use editor::Editor;
|
||||||
use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt};
|
use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt};
|
||||||
use fuzzy::{match_strings, StringMatchCandidate};
|
use fuzzy::{match_strings, StringMatchCandidate};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, img, prelude::*, serde_json, Action, AppContext, AsyncWindowContext,
|
actions, div, img, overlay, prelude::*, px, rems, serde_json, Action, AppContext,
|
||||||
ClipboardItem, Div, EventEmitter, FocusHandle, Focusable, FocusableView, InteractiveElement,
|
AsyncWindowContext, ClipboardItem, DismissEvent, Div, EventEmitter, FocusHandle, Focusable,
|
||||||
IntoElement, Model, ParentElement, Pixels, Point, PromptLevel, Render, RenderOnce,
|
FocusableView, InteractiveElement, IntoElement, Model, MouseDownEvent, ParentElement, Pixels,
|
||||||
SharedString, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView,
|
Point, PromptLevel, Render, RenderOnce, SharedString, Styled, Subscription, Task, View,
|
||||||
|
ViewContext, VisualContext, WeakView,
|
||||||
};
|
};
|
||||||
use project::Fs;
|
use project::Fs;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
@ -286,7 +287,7 @@ pub struct CollabPanel {
|
||||||
width: Option<f32>,
|
width: Option<f32>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
// channel_clipboard: Option<ChannelMoveClipboard>,
|
channel_clipboard: Option<ChannelMoveClipboard>,
|
||||||
pending_serialization: Task<Option<()>>,
|
pending_serialization: Task<Option<()>>,
|
||||||
context_menu: Option<(View<ContextMenu>, Point<Pixels>, Subscription)>,
|
context_menu: Option<(View<ContextMenu>, Point<Pixels>, Subscription)>,
|
||||||
filter_editor: View<Editor>,
|
filter_editor: View<Editor>,
|
||||||
|
@ -569,7 +570,7 @@ impl CollabPanel {
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
width: None,
|
width: None,
|
||||||
focus_handle: cx.focus_handle(),
|
focus_handle: cx.focus_handle(),
|
||||||
// channel_clipboard: None,
|
channel_clipboard: None,
|
||||||
fs: workspace.app_state().fs.clone(),
|
fs: workspace.app_state().fs.clone(),
|
||||||
pending_serialization: Task::ready(None),
|
pending_serialization: Task::ready(None),
|
||||||
context_menu: None,
|
context_menu: None,
|
||||||
|
@ -1665,46 +1666,44 @@ impl CollabPanel {
|
||||||
// .into_any()
|
// .into_any()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// fn has_subchannels(&self, ix: usize) -> bool {
|
fn has_subchannels(&self, ix: usize) -> bool {
|
||||||
// self.entries.get(ix).map_or(false, |entry| {
|
self.entries.get(ix).map_or(false, |entry| {
|
||||||
// if let ListEntry::Channel { has_children, .. } = entry {
|
if let ListEntry::Channel { has_children, .. } = entry {
|
||||||
// *has_children
|
*has_children
|
||||||
// } else {
|
} else {
|
||||||
// false
|
false
|
||||||
// }
|
}
|
||||||
// })
|
})
|
||||||
// }
|
}
|
||||||
|
|
||||||
fn deploy_channel_context_menu(
|
fn deploy_channel_context_menu(
|
||||||
&mut self,
|
&mut self,
|
||||||
position: Point<Pixels>,
|
position: Point<Pixels>,
|
||||||
channel: &Channel,
|
channel_id: ChannelId,
|
||||||
ix: usize,
|
ix: usize,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
// self.context_menu_on_selected = position.is_none();
|
// self.context_menu_on_selected = position.is_none();
|
||||||
|
|
||||||
// let clipboard_channel_name = self.channel_clipboard.as_ref().and_then(|clipboard| {
|
let clipboard_channel_name = self.channel_clipboard.as_ref().and_then(|clipboard| {
|
||||||
// self.channel_store
|
self.channel_store
|
||||||
// .read(cx)
|
.read(cx)
|
||||||
// .channel_for_id(clipboard.channel_id)
|
.channel_for_id(clipboard.channel_id)
|
||||||
// .map(|channel| channel.name.clone())
|
.map(|channel| channel.name.clone())
|
||||||
// });
|
});
|
||||||
let this = cx.view();
|
let this = cx.view().clone();
|
||||||
let has_subchannels = self.has_subchannels(ix);
|
|
||||||
let is_channel_collapsed = self.is_channel_collapsed(channel_id);
|
|
||||||
|
|
||||||
let menu = ContextMenu::build(cx, |context_menu, cx| {
|
let context_menu = ContextMenu::build(cx, |mut context_menu, cx| {
|
||||||
if has_subchannels {
|
if self.has_subchannels(ix) {
|
||||||
let expand_action_name = if is_channel_collapsed {
|
let expand_action_name = if self.is_channel_collapsed(channel_id) {
|
||||||
"Expand Subchannels"
|
"Expand Subchannels"
|
||||||
} else {
|
} else {
|
||||||
"Collapse Subchannels"
|
"Collapse Subchannels"
|
||||||
};
|
};
|
||||||
context_menu = context_menu.entry(
|
context_menu = context_menu.entry(
|
||||||
expand_action_name,
|
expand_action_name,
|
||||||
cx.handler_for(&this, |this, cx| {
|
cx.handler_for(&this, move |this, cx| {
|
||||||
this.toggle_channel_collapsed(channel.id, cx)
|
this.toggle_channel_collapsed(channel_id, cx)
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1712,80 +1711,75 @@ impl CollabPanel {
|
||||||
context_menu = context_menu
|
context_menu = context_menu
|
||||||
.entry(
|
.entry(
|
||||||
"Open Notes",
|
"Open Notes",
|
||||||
cx.handler_for(&this, |this, cx| this.open_channel_notes(channel.id, cx)),
|
cx.handler_for(&this, move |this, cx| {
|
||||||
|
this.open_channel_notes(channel_id, cx)
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.entry(
|
.entry(
|
||||||
"Open Chat",
|
"Open Chat",
|
||||||
cx.handler_for(&this, |this, cx| this.join_channel_chat(channel.id, cx)),
|
cx.handler_for(&this, move |this, cx| {
|
||||||
|
this.join_channel_chat(channel_id, cx)
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.entry(
|
.entry(
|
||||||
"Copy Channel Link",
|
"Copy Channel Link",
|
||||||
cx.handler_for(&this, |this, cx| this.copy_channel_link(channel.id, cx)),
|
cx.handler_for(&this, move |this, cx| {
|
||||||
|
this.copy_channel_link(channel_id, cx)
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
if self.channel_store.read(cx).is_channel_admin(channel.id) {
|
if self.channel_store.read(cx).is_channel_admin(channel_id) {
|
||||||
context_menu = context_menu
|
context_menu = context_menu
|
||||||
.separator()
|
.separator()
|
||||||
.entry(
|
.entry(
|
||||||
"New Subchannel",
|
"New Subchannel",
|
||||||
cx.handler_for(&this, |this, cx| this.new_subchannel(channel.id, cx)),
|
cx.handler_for(&this, move |this, cx| this.new_subchannel(channel_id, cx)),
|
||||||
)
|
)
|
||||||
.entry(
|
.entry(
|
||||||
"Rename",
|
"Rename",
|
||||||
cx.handler_for(&this, |this, cx| this.rename_channel(channel.id, cx)),
|
cx.handler_for(&this, move |this, cx| this.rename_channel(channel_id, cx)),
|
||||||
)
|
)
|
||||||
.entry(
|
.entry(
|
||||||
"Move this channel",
|
"Move this channel",
|
||||||
cx.handler_for(&this, |this, cx| this.start_move_channel(channel.id, cx)),
|
cx.handler_for(&this, move |this, cx| {
|
||||||
|
this.start_move_channel(channel_id, cx)
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// if let Some(channel_name) = clipboard_channel_name {
|
if let Some(channel_name) = clipboard_channel_name {
|
||||||
// items.push(ContextMenuItem::Separator);
|
context_menu = context_menu.separator().entry(
|
||||||
// items.push(ContextMenuItem::action(
|
format!("Move '#{}' here", channel_name),
|
||||||
// format!("Move '#{}' here", channel_name),
|
cx.handler_for(&this, move |this, cx| {
|
||||||
// MoveChannel { to: channel.id },
|
this.move_channel_on_clipboard(channel_id, cx)
|
||||||
// ));
|
}),
|
||||||
// }
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// items.extend([
|
context_menu = context_menu
|
||||||
// ContextMenuItem::Separator,
|
.separator()
|
||||||
// ContextMenuItem::action(
|
.entry(
|
||||||
// "Invite Members",
|
"Invite Members",
|
||||||
// InviteMembers {
|
cx.handler_for(&this, move |this, cx| this.invite_members(channel_id, cx)),
|
||||||
// channel_id: channel.id,
|
)
|
||||||
// },
|
.entry(
|
||||||
// ),
|
"Manage Members",
|
||||||
// ContextMenuItem::action(
|
cx.handler_for(&this, move |this, cx| this.manage_members(channel_id, cx)),
|
||||||
// "Manage Members",
|
)
|
||||||
// ManageMembers {
|
.entry(
|
||||||
// channel_id: channel.id,
|
"Delete",
|
||||||
// },
|
cx.handler_for(&this, move |this, cx| this.remove_channel(channel_id, cx)),
|
||||||
// ),
|
);
|
||||||
// ContextMenuItem::Separator,
|
|
||||||
// ContextMenuItem::action(
|
|
||||||
// "Delete",
|
|
||||||
// RemoveChannel {
|
|
||||||
// channel_id: channel.id,
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// context_menu.show(
|
|
||||||
// position.unwrap_or_default(),
|
|
||||||
// if self.context_menu_on_selected {
|
|
||||||
// gpui::elements::AnchorCorner::TopRight
|
|
||||||
// } else {
|
|
||||||
// gpui::elements::AnchorCorner::BottomLeft
|
|
||||||
// },
|
|
||||||
// items,
|
|
||||||
// cx,
|
|
||||||
// );
|
|
||||||
|
|
||||||
context_menu
|
context_menu
|
||||||
});
|
});
|
||||||
|
|
||||||
self.context_menu = Some((menu, (), ()));
|
cx.focus_view(&context_menu);
|
||||||
|
let subscription = cx.subscribe(&context_menu, |this, _, _: &DismissEvent, cx| {
|
||||||
|
this.context_menu.take();
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
self.context_menu = Some((context_menu, position, subscription));
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
@ -2074,55 +2068,52 @@ impl CollabPanel {
|
||||||
self.collapsed_channels
|
self.collapsed_channels
|
||||||
.retain(|channel| *channel != channel_id);
|
.retain(|channel| *channel != channel_id);
|
||||||
self.channel_editing_state = Some(ChannelEditingState::Create {
|
self.channel_editing_state = Some(ChannelEditingState::Create {
|
||||||
location: Some(action.location.to_owned()),
|
location: Some(channel_id),
|
||||||
pending_name: None,
|
pending_name: None,
|
||||||
});
|
});
|
||||||
self.update_entries(false, cx);
|
self.update_entries(false, cx);
|
||||||
self.select_channel_editor();
|
self.select_channel_editor();
|
||||||
cx.focus(self.channel_name_editor.as_any());
|
cx.focus_view(&self.channel_name_editor);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn invite_members(&mut self, action: &InviteMembers, cx: &mut ViewContext<Self>) {
|
fn invite_members(&mut self, channel_id: ChannelId, cx: &mut ViewContext<Self>) {
|
||||||
// self.show_channel_modal(action.channel_id, channel_modal::Mode::InviteMembers, cx);
|
todo!();
|
||||||
// }
|
// self.show_channel_modal(channel_id, channel_modal::Mode::InviteMembers, cx);
|
||||||
|
}
|
||||||
|
|
||||||
// fn manage_members(&mut self, action: &ManageMembers, cx: &mut ViewContext<Self>) {
|
fn manage_members(&mut self, channel_id: ChannelId, cx: &mut ViewContext<Self>) {
|
||||||
// self.show_channel_modal(action.channel_id, channel_modal::Mode::ManageMembers, cx);
|
todo!();
|
||||||
// }
|
// self.show_channel_modal(channel_id, channel_modal::Mode::ManageMembers, cx);
|
||||||
|
}
|
||||||
|
|
||||||
// fn remove(&mut self, _: &Remove, cx: &mut ViewContext<Self>) {
|
fn remove_selected_channel(&mut self, _: &Remove, cx: &mut ViewContext<Self>) {
|
||||||
// if let Some(channel) = self.selected_channel() {
|
if let Some(channel) = self.selected_channel() {
|
||||||
// self.remove_channel(channel.id, cx)
|
self.remove_channel(channel.id, cx)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn rename_selected_channel(&mut self, _: &menu::SecondaryConfirm, cx: &mut ViewContext<Self>) {
|
fn rename_selected_channel(&mut self, _: &menu::SecondaryConfirm, cx: &mut ViewContext<Self>) {
|
||||||
// if let Some(channel) = self.selected_channel() {
|
if let Some(channel) = self.selected_channel() {
|
||||||
// self.rename_channel(
|
self.rename_channel(channel.id, cx);
|
||||||
// &RenameChannel {
|
}
|
||||||
// channel_id: channel.id,
|
}
|
||||||
// },
|
|
||||||
// cx,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn rename_channel(&mut self, action: &RenameChannel, cx: &mut ViewContext<Self>) {
|
fn rename_channel(&mut self, channel_id: ChannelId, cx: &mut ViewContext<Self>) {
|
||||||
let channel_store = self.channel_store.read(cx);
|
let channel_store = self.channel_store.read(cx);
|
||||||
if !channel_store.is_channel_admin(action.channel_id) {
|
if !channel_store.is_channel_admin(channel_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(channel) = channel_store.channel_for_id(action.channel_id).cloned() {
|
if let Some(channel) = channel_store.channel_for_id(channel_id).cloned() {
|
||||||
self.channel_editing_state = Some(ChannelEditingState::Rename {
|
self.channel_editing_state = Some(ChannelEditingState::Rename {
|
||||||
location: action.channel_id.to_owned(),
|
location: channel_id,
|
||||||
pending_name: None,
|
pending_name: None,
|
||||||
});
|
});
|
||||||
self.channel_name_editor.update(cx, |editor, cx| {
|
self.channel_name_editor.update(cx, |editor, cx| {
|
||||||
editor.set_text(channel.name.clone(), cx);
|
editor.set_text(channel.name.clone(), cx);
|
||||||
editor.select_all(&Default::default(), cx);
|
editor.select_all(&Default::default(), cx);
|
||||||
});
|
});
|
||||||
cx.focus(self.channel_name_editor.as_any());
|
cx.focus_view(&self.channel_name_editor);
|
||||||
self.update_entries(false, cx);
|
self.update_entries(false, cx);
|
||||||
self.select_channel_editor();
|
self.select_channel_editor();
|
||||||
}
|
}
|
||||||
|
@ -2140,7 +2131,21 @@ impl CollabPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_channel_notes(&mut self, action: &OpenChannelNotes, cx: &mut ViewContext<Self>) {
|
fn move_channel_on_clipboard(
|
||||||
|
&mut self,
|
||||||
|
to_channel_id: ChannelId,
|
||||||
|
cx: &mut ViewContext<CollabPanel>,
|
||||||
|
) {
|
||||||
|
if let Some(clipboard) = self.channel_clipboard.take() {
|
||||||
|
self.channel_store.update(cx, |channel_store, cx| {
|
||||||
|
channel_store
|
||||||
|
.move_channel(clipboard.channel_id, Some(to_channel_id), cx)
|
||||||
|
.detach_and_log_err(cx)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open_channel_notes(&mut self, channel_id: ChannelId, cx: &mut ViewContext<Self>) {
|
||||||
if let Some(workspace) = self.workspace.upgrade() {
|
if let Some(workspace) = self.workspace.upgrade() {
|
||||||
todo!();
|
todo!();
|
||||||
// ChannelView::open(action.channel_id, workspace, cx).detach();
|
// ChannelView::open(action.channel_id, workspace, cx).detach();
|
||||||
|
@ -2201,35 +2206,29 @@ impl CollabPanel {
|
||||||
// self.remove_channel(action.channel_id, cx)
|
// self.remove_channel(action.channel_id, cx)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// fn remove_channel(&mut self, channel_id: ChannelId, cx: &mut ViewContext<Self>) {
|
fn remove_channel(&mut self, channel_id: ChannelId, cx: &mut ViewContext<Self>) {
|
||||||
// let channel_store = self.channel_store.clone();
|
let channel_store = self.channel_store.clone();
|
||||||
// if let Some(channel) = channel_store.read(cx).channel_for_id(channel_id) {
|
if let Some(channel) = channel_store.read(cx).channel_for_id(channel_id) {
|
||||||
// let prompt_message = format!(
|
let prompt_message = format!(
|
||||||
// "Are you sure you want to remove the channel \"{}\"?",
|
"Are you sure you want to remove the channel \"{}\"?",
|
||||||
// channel.name
|
channel.name
|
||||||
// );
|
);
|
||||||
// let mut answer =
|
let mut answer =
|
||||||
// cx.prompt(PromptLevel::Warning, &prompt_message, &["Remove", "Cancel"]);
|
cx.prompt(PromptLevel::Warning, &prompt_message, &["Remove", "Cancel"]);
|
||||||
// let window = cx.window();
|
let window = cx.window();
|
||||||
// cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
// if answer.next().await == Some(0) {
|
if answer.await? == 0 {
|
||||||
// if let Err(e) = channel_store
|
channel_store
|
||||||
// .update(&mut cx, |channels, _| channels.remove_channel(channel_id))
|
.update(&mut cx, |channels, _| channels.remove_channel(channel_id))?
|
||||||
// .await
|
.await
|
||||||
// {
|
.notify_async_err(&mut cx);
|
||||||
// window.prompt(
|
this.update(&mut cx, |_, cx| cx.focus_self()).ok();
|
||||||
// PromptLevel::Info,
|
}
|
||||||
// &format!("Failed to remove channel: {}", e),
|
anyhow::Ok(())
|
||||||
// &["Ok"],
|
})
|
||||||
// &mut cx,
|
.detach();
|
||||||
// );
|
}
|
||||||
// }
|
}
|
||||||
// this.update(&mut cx, |_, cx| cx.focus_self()).ok();
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// .detach();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Should move to the filter editor if clicking on it
|
// // Should move to the filter editor if clicking on it
|
||||||
// // Should move selection to the channel editor if activating it
|
// // Should move selection to the channel editor if activating it
|
||||||
|
@ -2314,15 +2313,16 @@ impl CollabPanel {
|
||||||
let Some(workspace) = self.workspace.upgrade() else {
|
let Some(workspace) = self.workspace.upgrade() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
cx.defer(move |cx| {
|
cx.window_context().defer(move |cx| {
|
||||||
workspace.update(cx, |workspace, cx| {
|
workspace.update(cx, |workspace, cx| {
|
||||||
if let Some(panel) = workspace.focus_panel::<ChatPanel>(cx) {
|
todo!();
|
||||||
panel.update(cx, |panel, cx| {
|
// if let Some(panel) = workspace.focus_panel::<ChatPanel>(cx) {
|
||||||
panel
|
// panel.update(cx, |panel, cx| {
|
||||||
.select_channel(channel_id, None, cx)
|
// panel
|
||||||
.detach_and_log_err(cx);
|
// .select_channel(channel_id, None, cx)
|
||||||
});
|
// .detach_and_log_err(cx);
|
||||||
}
|
// });
|
||||||
|
// }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2354,37 +2354,41 @@ impl CollabPanel {
|
||||||
fn render_signed_in(&mut self, cx: &mut ViewContext<Self>) -> List {
|
fn render_signed_in(&mut self, cx: &mut ViewContext<Self>) -> List {
|
||||||
let is_selected = false; // todo!() this.selection == Some(ix);
|
let is_selected = false; // todo!() this.selection == Some(ix);
|
||||||
|
|
||||||
List::new().children(self.entries.clone().into_iter().map(|entry| {
|
List::new().children(
|
||||||
match entry {
|
self.entries
|
||||||
ListEntry::Header(section) => {
|
.clone()
|
||||||
let is_collapsed = self.collapsed_sections.contains(§ion);
|
.into_iter()
|
||||||
self.render_header(section, is_selected, is_collapsed, cx)
|
.enumerate()
|
||||||
.into_any_element()
|
.map(|(ix, entry)| match entry {
|
||||||
}
|
ListEntry::Header(section) => {
|
||||||
ListEntry::Contact { contact, calling } => self
|
let is_collapsed = self.collapsed_sections.contains(§ion);
|
||||||
.render_contact(&*contact, calling, is_selected, cx)
|
self.render_header(section, is_selected, is_collapsed, cx)
|
||||||
.into_any_element(),
|
.into_any_element()
|
||||||
ListEntry::ContactPlaceholder => self
|
}
|
||||||
.render_contact_placeholder(is_selected, cx)
|
ListEntry::Contact { contact, calling } => self
|
||||||
.into_any_element(),
|
.render_contact(&*contact, calling, is_selected, cx)
|
||||||
ListEntry::IncomingRequest(user) => self
|
.into_any_element(),
|
||||||
.render_contact_request(user, true, is_selected, cx)
|
ListEntry::ContactPlaceholder => self
|
||||||
.into_any_element(),
|
.render_contact_placeholder(is_selected, cx)
|
||||||
ListEntry::OutgoingRequest(user) => self
|
.into_any_element(),
|
||||||
.render_contact_request(user, false, is_selected, cx)
|
ListEntry::IncomingRequest(user) => self
|
||||||
.into_any_element(),
|
.render_contact_request(user, true, is_selected, cx)
|
||||||
ListEntry::Channel {
|
.into_any_element(),
|
||||||
channel,
|
ListEntry::OutgoingRequest(user) => self
|
||||||
depth,
|
.render_contact_request(user, false, is_selected, cx)
|
||||||
has_children,
|
.into_any_element(),
|
||||||
} => self
|
ListEntry::Channel {
|
||||||
.render_channel(&*channel, depth, has_children, is_selected, cx)
|
channel,
|
||||||
.into_any_element(),
|
depth,
|
||||||
ListEntry::ChannelEditor { depth } => {
|
has_children,
|
||||||
self.render_channel_editor(depth, cx).into_any_element()
|
} => self
|
||||||
}
|
.render_channel(&*channel, depth, has_children, is_selected, ix, cx)
|
||||||
}
|
.into_any_element(),
|
||||||
}))
|
ListEntry::ChannelEditor { depth } => {
|
||||||
|
self.render_channel_editor(depth, cx).into_any_element()
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_header(
|
fn render_header(
|
||||||
|
@ -2713,6 +2717,7 @@ impl CollabPanel {
|
||||||
depth: usize,
|
depth: usize,
|
||||||
has_children: bool,
|
has_children: bool,
|
||||||
is_selected: bool,
|
is_selected: bool,
|
||||||
|
ix: usize,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> impl IntoElement {
|
) -> impl IntoElement {
|
||||||
let channel_id = channel.id;
|
let channel_id = channel.id;
|
||||||
|
@ -2769,6 +2774,7 @@ impl CollabPanel {
|
||||||
div().group("").child(
|
div().group("").child(
|
||||||
ListItem::new(channel_id as usize)
|
ListItem::new(channel_id as usize)
|
||||||
.indent_level(depth)
|
.indent_level(depth)
|
||||||
|
.indent_step_size(cx.rem_size() * 14.0 / 16.0) // @todo()! @nate this is to step over the disclosure toggle
|
||||||
.left_icon(if is_public { Icon::Public } else { Icon::Hash })
|
.left_icon(if is_public { Icon::Public } else { Icon::Hash })
|
||||||
.selected(is_selected || is_active)
|
.selected(is_selected || is_active)
|
||||||
.child(
|
.child(
|
||||||
|
@ -2829,14 +2835,14 @@ impl CollabPanel {
|
||||||
.on_click(cx.listener(move |this, _, cx| {
|
.on_click(cx.listener(move |this, _, cx| {
|
||||||
if this.drag_target_channel == ChannelDragTarget::None {
|
if this.drag_target_channel == ChannelDragTarget::None {
|
||||||
if is_active {
|
if is_active {
|
||||||
this.open_channel_notes(&OpenChannelNotes { channel_id }, cx)
|
this.open_channel_notes(channel_id, cx)
|
||||||
} else {
|
} else {
|
||||||
this.join_channel(channel_id, cx)
|
this.join_channel(channel_id, cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.on_secondary_mouse_down(cx.listener(|this, _, cx| {
|
.on_secondary_mouse_down(cx.listener(move |this, event: &MouseDownEvent, cx| {
|
||||||
todo!() // open context menu
|
this.deploy_channel_context_menu(event.position, channel_id, ix, cx)
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3235,6 +3241,12 @@ impl Render for CollabPanel {
|
||||||
el.child(self.render_signed_in(cx))
|
el.child(self.render_signed_in(cx))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.children(self.context_menu.as_ref().map(|(menu, position, _)| {
|
||||||
|
overlay()
|
||||||
|
.position(*position)
|
||||||
|
.anchor(gpui::AnchorCorner::TopLeft)
|
||||||
|
.child(menu.clone())
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1480,7 +1480,7 @@ impl Render for ProjectPanel {
|
||||||
.children(self.context_menu.as_ref().map(|(menu, position, _)| {
|
.children(self.context_menu.as_ref().map(|(menu, position, _)| {
|
||||||
overlay()
|
overlay()
|
||||||
.position(*position)
|
.position(*position)
|
||||||
.anchor(gpui::AnchorCorner::BottomLeft)
|
.anchor(gpui::AnchorCorner::TopLeft)
|
||||||
.child(menu.clone())
|
.child(menu.clone())
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue