mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-07 02:57:34 +00:00
Start work on adding sub-channels in the UI
Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
b389dcc637
commit
6a404dfe31
1 changed files with 179 additions and 136 deletions
|
@ -17,7 +17,10 @@ use gpui::{
|
|||
Canvas, ChildView, Empty, Flex, Image, Label, List, ListOffset, ListState,
|
||||
MouseEventHandler, Orientation, Padding, ParentElement, Stack, Svg,
|
||||
},
|
||||
geometry::{rect::RectF, vector::vec2f},
|
||||
geometry::{
|
||||
rect::RectF,
|
||||
vector::{vec2f, Vector2F},
|
||||
},
|
||||
impl_actions,
|
||||
platform::{CursorStyle, MouseButton, PromptLevel},
|
||||
serde_json, AnyElement, AppContext, AsyncAppContext, Element, Entity, ModelHandle,
|
||||
|
@ -42,9 +45,14 @@ struct RemoveChannel {
|
|||
channel_id: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
struct NewChannel {
|
||||
channel_id: u64,
|
||||
}
|
||||
|
||||
actions!(collab_panel, [ToggleFocus]);
|
||||
|
||||
impl_actions!(collab_panel, [RemoveChannel]);
|
||||
impl_actions!(collab_panel, [RemoveChannel, NewChannel]);
|
||||
|
||||
const CHANNELS_PANEL_KEY: &'static str = "ChannelsPanel";
|
||||
|
||||
|
@ -58,11 +66,12 @@ pub fn init(_client: Arc<Client>, cx: &mut AppContext) {
|
|||
cx.add_action(CollabPanel::select_prev);
|
||||
cx.add_action(CollabPanel::confirm);
|
||||
cx.add_action(CollabPanel::remove_channel);
|
||||
cx.add_action(CollabPanel::new_subchannel);
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ChannelEditingState {
|
||||
root_channel: bool,
|
||||
parent_id: Option<u64>,
|
||||
}
|
||||
|
||||
pub struct CollabPanel {
|
||||
|
@ -74,7 +83,7 @@ pub struct CollabPanel {
|
|||
filter_editor: ViewHandle<Editor>,
|
||||
channel_name_editor: ViewHandle<Editor>,
|
||||
channel_editing_state: Option<ChannelEditingState>,
|
||||
entries: Vec<ContactEntry>,
|
||||
entries: Vec<ListEntry>,
|
||||
selection: Option<usize>,
|
||||
user_store: ModelHandle<UserStore>,
|
||||
channel_store: ModelHandle<ChannelStore>,
|
||||
|
@ -109,7 +118,7 @@ enum Section {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum ContactEntry {
|
||||
enum ListEntry {
|
||||
Header(Section, usize),
|
||||
CallParticipant {
|
||||
user: Arc<User>,
|
||||
|
@ -125,10 +134,13 @@ enum ContactEntry {
|
|||
peer_id: PeerId,
|
||||
is_last: bool,
|
||||
},
|
||||
ChannelInvite(Arc<Channel>),
|
||||
IncomingRequest(Arc<User>),
|
||||
OutgoingRequest(Arc<User>),
|
||||
ChannelInvite(Arc<Channel>),
|
||||
Channel(Arc<Channel>),
|
||||
ChannelEditor {
|
||||
depth: usize,
|
||||
},
|
||||
Contact {
|
||||
contact: Arc<Contact>,
|
||||
calling: bool,
|
||||
|
@ -166,7 +178,7 @@ impl CollabPanel {
|
|||
this.selection = this
|
||||
.entries
|
||||
.iter()
|
||||
.position(|entry| !matches!(entry, ContactEntry::Header(_, _)));
|
||||
.position(|entry| !matches!(entry, ListEntry::Header(_, _)));
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -184,6 +196,7 @@ impl CollabPanel {
|
|||
cx.subscribe(&channel_name_editor, |this, _, event, cx| {
|
||||
if let editor::Event::Blurred = event {
|
||||
this.take_editing_state(cx);
|
||||
this.update_entries(cx);
|
||||
cx.notify();
|
||||
}
|
||||
})
|
||||
|
@ -196,7 +209,7 @@ impl CollabPanel {
|
|||
let current_project_id = this.project.read(cx).remote_id();
|
||||
|
||||
match &this.entries[ix] {
|
||||
ContactEntry::Header(section, depth) => {
|
||||
ListEntry::Header(section, depth) => {
|
||||
let is_collapsed = this.collapsed_sections.contains(section);
|
||||
this.render_header(
|
||||
*section,
|
||||
|
@ -207,7 +220,7 @@ impl CollabPanel {
|
|||
cx,
|
||||
)
|
||||
}
|
||||
ContactEntry::CallParticipant { user, is_pending } => {
|
||||
ListEntry::CallParticipant { user, is_pending } => {
|
||||
Self::render_call_participant(
|
||||
user,
|
||||
*is_pending,
|
||||
|
@ -215,7 +228,7 @@ impl CollabPanel {
|
|||
&theme.collab_panel,
|
||||
)
|
||||
}
|
||||
ContactEntry::ParticipantProject {
|
||||
ListEntry::ParticipantProject {
|
||||
project_id,
|
||||
worktree_root_names,
|
||||
host_user_id,
|
||||
|
@ -230,7 +243,7 @@ impl CollabPanel {
|
|||
&theme.collab_panel,
|
||||
cx,
|
||||
),
|
||||
ContactEntry::ParticipantScreen { peer_id, is_last } => {
|
||||
ListEntry::ParticipantScreen { peer_id, is_last } => {
|
||||
Self::render_participant_screen(
|
||||
*peer_id,
|
||||
*is_last,
|
||||
|
@ -239,17 +252,17 @@ impl CollabPanel {
|
|||
cx,
|
||||
)
|
||||
}
|
||||
ContactEntry::Channel(channel) => {
|
||||
ListEntry::Channel(channel) => {
|
||||
Self::render_channel(&*channel, &theme.collab_panel, is_selected, cx)
|
||||
}
|
||||
ContactEntry::ChannelInvite(channel) => Self::render_channel_invite(
|
||||
ListEntry::ChannelInvite(channel) => Self::render_channel_invite(
|
||||
channel.clone(),
|
||||
this.channel_store.clone(),
|
||||
&theme.collab_panel,
|
||||
is_selected,
|
||||
cx,
|
||||
),
|
||||
ContactEntry::IncomingRequest(user) => Self::render_contact_request(
|
||||
ListEntry::IncomingRequest(user) => Self::render_contact_request(
|
||||
user.clone(),
|
||||
this.user_store.clone(),
|
||||
&theme.collab_panel,
|
||||
|
@ -257,7 +270,7 @@ impl CollabPanel {
|
|||
is_selected,
|
||||
cx,
|
||||
),
|
||||
ContactEntry::OutgoingRequest(user) => Self::render_contact_request(
|
||||
ListEntry::OutgoingRequest(user) => Self::render_contact_request(
|
||||
user.clone(),
|
||||
this.user_store.clone(),
|
||||
&theme.collab_panel,
|
||||
|
@ -265,7 +278,7 @@ impl CollabPanel {
|
|||
is_selected,
|
||||
cx,
|
||||
),
|
||||
ContactEntry::Contact { contact, calling } => Self::render_contact(
|
||||
ListEntry::Contact { contact, calling } => Self::render_contact(
|
||||
contact,
|
||||
*calling,
|
||||
&this.project,
|
||||
|
@ -273,6 +286,9 @@ impl CollabPanel {
|
|||
is_selected,
|
||||
cx,
|
||||
),
|
||||
ListEntry::ChannelEditor { depth } => {
|
||||
this.render_channel_editor(&theme.collab_panel, *depth, cx)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -369,13 +385,6 @@ impl CollabPanel {
|
|||
);
|
||||
}
|
||||
|
||||
fn is_editing_root_channel(&self) -> bool {
|
||||
self.channel_editing_state
|
||||
.as_ref()
|
||||
.map(|state| state.root_channel)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn update_entries(&mut self, cx: &mut ViewContext<Self>) {
|
||||
let channel_store = self.channel_store.read(cx);
|
||||
let user_store = self.user_store.read(cx);
|
||||
|
@ -407,13 +416,13 @@ impl CollabPanel {
|
|||
));
|
||||
if !matches.is_empty() {
|
||||
let user_id = user.id;
|
||||
participant_entries.push(ContactEntry::CallParticipant {
|
||||
participant_entries.push(ListEntry::CallParticipant {
|
||||
user,
|
||||
is_pending: false,
|
||||
});
|
||||
let mut projects = room.local_participant().projects.iter().peekable();
|
||||
while let Some(project) = projects.next() {
|
||||
participant_entries.push(ContactEntry::ParticipantProject {
|
||||
participant_entries.push(ListEntry::ParticipantProject {
|
||||
project_id: project.id,
|
||||
worktree_root_names: project.worktree_root_names.clone(),
|
||||
host_user_id: user_id,
|
||||
|
@ -444,13 +453,13 @@ impl CollabPanel {
|
|||
for mat in matches {
|
||||
let user_id = mat.candidate_id as u64;
|
||||
let participant = &room.remote_participants()[&user_id];
|
||||
participant_entries.push(ContactEntry::CallParticipant {
|
||||
participant_entries.push(ListEntry::CallParticipant {
|
||||
user: participant.user.clone(),
|
||||
is_pending: false,
|
||||
});
|
||||
let mut projects = participant.projects.iter().peekable();
|
||||
while let Some(project) = projects.next() {
|
||||
participant_entries.push(ContactEntry::ParticipantProject {
|
||||
participant_entries.push(ListEntry::ParticipantProject {
|
||||
project_id: project.id,
|
||||
worktree_root_names: project.worktree_root_names.clone(),
|
||||
host_user_id: participant.user.id,
|
||||
|
@ -458,7 +467,7 @@ impl CollabPanel {
|
|||
});
|
||||
}
|
||||
if !participant.video_tracks.is_empty() {
|
||||
participant_entries.push(ContactEntry::ParticipantScreen {
|
||||
participant_entries.push(ListEntry::ParticipantScreen {
|
||||
peer_id: participant.peer_id,
|
||||
is_last: true,
|
||||
});
|
||||
|
@ -486,22 +495,20 @@ impl CollabPanel {
|
|||
&Default::default(),
|
||||
executor.clone(),
|
||||
));
|
||||
participant_entries.extend(matches.iter().map(|mat| ContactEntry::CallParticipant {
|
||||
participant_entries.extend(matches.iter().map(|mat| ListEntry::CallParticipant {
|
||||
user: room.pending_participants()[mat.candidate_id].clone(),
|
||||
is_pending: true,
|
||||
}));
|
||||
|
||||
if !participant_entries.is_empty() {
|
||||
self.entries
|
||||
.push(ContactEntry::Header(Section::ActiveCall, 0));
|
||||
self.entries.push(ListEntry::Header(Section::ActiveCall, 0));
|
||||
if !self.collapsed_sections.contains(&Section::ActiveCall) {
|
||||
self.entries.extend(participant_entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.entries
|
||||
.push(ContactEntry::Header(Section::Channels, 0));
|
||||
self.entries.push(ListEntry::Header(Section::Channels, 0));
|
||||
|
||||
let channels = channel_store.channels();
|
||||
if !channels.is_empty() {
|
||||
|
@ -525,15 +532,25 @@ impl CollabPanel {
|
|||
&Default::default(),
|
||||
executor.clone(),
|
||||
));
|
||||
self.entries.extend(
|
||||
matches
|
||||
.iter()
|
||||
.map(|mat| ContactEntry::Channel(channels[mat.candidate_id].clone())),
|
||||
);
|
||||
if let Some(state) = &self.channel_editing_state {
|
||||
if state.parent_id.is_none() {
|
||||
self.entries.push(ListEntry::ChannelEditor { depth: 0 });
|
||||
}
|
||||
}
|
||||
for mat in matches {
|
||||
let channel = &channels[mat.candidate_id];
|
||||
self.entries.push(ListEntry::Channel(channel.clone()));
|
||||
if let Some(state) = &self.channel_editing_state {
|
||||
if state.parent_id == Some(channel.id) {
|
||||
self.entries.push(ListEntry::ChannelEditor {
|
||||
depth: channel.depth + 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.entries
|
||||
.push(ContactEntry::Header(Section::Contacts, 0));
|
||||
self.entries.push(ListEntry::Header(Section::Contacts, 0));
|
||||
|
||||
let mut request_entries = Vec::new();
|
||||
let channel_invites = channel_store.channel_invitations();
|
||||
|
@ -556,9 +573,9 @@ impl CollabPanel {
|
|||
executor.clone(),
|
||||
));
|
||||
request_entries.extend(
|
||||
matches.iter().map(|mat| {
|
||||
ContactEntry::ChannelInvite(channel_invites[mat.candidate_id].clone())
|
||||
}),
|
||||
matches
|
||||
.iter()
|
||||
.map(|mat| ListEntry::ChannelInvite(channel_invites[mat.candidate_id].clone())),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -587,7 +604,7 @@ impl CollabPanel {
|
|||
request_entries.extend(
|
||||
matches
|
||||
.iter()
|
||||
.map(|mat| ContactEntry::IncomingRequest(incoming[mat.candidate_id].clone())),
|
||||
.map(|mat| ListEntry::IncomingRequest(incoming[mat.candidate_id].clone())),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -616,13 +633,12 @@ impl CollabPanel {
|
|||
request_entries.extend(
|
||||
matches
|
||||
.iter()
|
||||
.map(|mat| ContactEntry::OutgoingRequest(outgoing[mat.candidate_id].clone())),
|
||||
.map(|mat| ListEntry::OutgoingRequest(outgoing[mat.candidate_id].clone())),
|
||||
);
|
||||
}
|
||||
|
||||
if !request_entries.is_empty() {
|
||||
self.entries
|
||||
.push(ContactEntry::Header(Section::Requests, 1));
|
||||
self.entries.push(ListEntry::Header(Section::Requests, 1));
|
||||
if !self.collapsed_sections.contains(&Section::Requests) {
|
||||
self.entries.append(&mut request_entries);
|
||||
}
|
||||
|
@ -668,12 +684,12 @@ impl CollabPanel {
|
|||
(offline_contacts, Section::Offline),
|
||||
] {
|
||||
if !matches.is_empty() {
|
||||
self.entries.push(ContactEntry::Header(section, 1));
|
||||
self.entries.push(ListEntry::Header(section, 1));
|
||||
if !self.collapsed_sections.contains(§ion) {
|
||||
let active_call = &ActiveCall::global(cx).read(cx);
|
||||
for mat in matches {
|
||||
let contact = &contacts[mat.candidate_id];
|
||||
self.entries.push(ContactEntry::Contact {
|
||||
self.entries.push(ListEntry::Contact {
|
||||
contact: contact.clone(),
|
||||
calling: active_call.pending_invites().contains(&contact.user.id),
|
||||
});
|
||||
|
@ -1072,15 +1088,7 @@ impl CollabPanel {
|
|||
render_icon_button(&theme.collab_panel.add_contact_button, "icons/plus_16.svg")
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, |_, this, cx| {
|
||||
if this.channel_editing_state.is_none() {
|
||||
this.channel_editing_state =
|
||||
Some(ChannelEditingState { root_channel: true });
|
||||
}
|
||||
|
||||
cx.focus(this.channel_name_editor.as_any());
|
||||
cx.notify();
|
||||
})
|
||||
.on_click(MouseButton::Left, |_, this, cx| this.new_root_channel(cx))
|
||||
.with_tooltip::<AddChannel>(
|
||||
0,
|
||||
"Add or join a channel".into(),
|
||||
|
@ -1092,13 +1100,6 @@ impl CollabPanel {
|
|||
_ => None,
|
||||
};
|
||||
|
||||
let addition = match section {
|
||||
Section::Channels if self.is_editing_root_channel() => {
|
||||
Some(ChildView::new(self.channel_name_editor.as_any(), cx))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let can_collapse = depth > 0;
|
||||
let icon_size = (&theme.collab_panel).section_icon_size;
|
||||
MouseEventHandler::<Header, Self>::new(section as usize, cx, |state, _| {
|
||||
|
@ -1112,44 +1113,40 @@ impl CollabPanel {
|
|||
&theme.collab_panel.header_row
|
||||
};
|
||||
|
||||
Flex::column()
|
||||
.with_child(
|
||||
Flex::row()
|
||||
.with_children(if can_collapse {
|
||||
Some(
|
||||
Svg::new(if is_collapsed {
|
||||
"icons/chevron_right_8.svg"
|
||||
} else {
|
||||
"icons/chevron_down_8.svg"
|
||||
})
|
||||
.with_color(header_style.text.color)
|
||||
.constrained()
|
||||
.with_max_width(icon_size)
|
||||
.with_max_height(icon_size)
|
||||
.aligned()
|
||||
.constrained()
|
||||
.with_width(icon_size)
|
||||
.contained()
|
||||
.with_margin_right(
|
||||
theme.collab_panel.contact_username.container.margin.left,
|
||||
),
|
||||
)
|
||||
Flex::row()
|
||||
.with_children(if can_collapse {
|
||||
Some(
|
||||
Svg::new(if is_collapsed {
|
||||
"icons/chevron_right_8.svg"
|
||||
} else {
|
||||
None
|
||||
"icons/chevron_down_8.svg"
|
||||
})
|
||||
.with_child(
|
||||
Label::new(text, header_style.text.clone())
|
||||
.aligned()
|
||||
.left()
|
||||
.flex(1., true),
|
||||
)
|
||||
.with_children(button.map(|button| button.aligned().right()))
|
||||
.with_color(header_style.text.color)
|
||||
.constrained()
|
||||
.with_height(theme.collab_panel.row_height)
|
||||
.with_max_width(icon_size)
|
||||
.with_max_height(icon_size)
|
||||
.aligned()
|
||||
.constrained()
|
||||
.with_width(icon_size)
|
||||
.contained()
|
||||
.with_style(header_style.container),
|
||||
.with_margin_right(
|
||||
theme.collab_panel.contact_username.container.margin.left,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.with_child(
|
||||
Label::new(text, header_style.text.clone())
|
||||
.aligned()
|
||||
.left()
|
||||
.flex(1., true),
|
||||
)
|
||||
.with_children(addition)
|
||||
.with_children(button.map(|button| button.aligned().right()))
|
||||
.constrained()
|
||||
.with_height(theme.collab_panel.row_height)
|
||||
.contained()
|
||||
.with_style(header_style.container)
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||
|
@ -1258,6 +1255,15 @@ impl CollabPanel {
|
|||
event_handler.into_any()
|
||||
}
|
||||
|
||||
fn render_channel_editor(
|
||||
&self,
|
||||
theme: &theme::CollabPanel,
|
||||
depth: usize,
|
||||
cx: &AppContext,
|
||||
) -> AnyElement<Self> {
|
||||
ChildView::new(&self.channel_name_editor, cx).into_any()
|
||||
}
|
||||
|
||||
fn render_channel(
|
||||
channel: &Channel,
|
||||
theme: &theme::CollabPanel,
|
||||
|
@ -1285,22 +1291,13 @@ impl CollabPanel {
|
|||
.with_height(theme.row_height)
|
||||
.contained()
|
||||
.with_style(*theme.contact_row.in_state(is_selected).style_for(state))
|
||||
.with_margin_left(10. * channel.depth as f32)
|
||||
})
|
||||
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||
this.join_channel(channel_id, cx);
|
||||
})
|
||||
.on_click(MouseButton::Right, move |e, this, cx| {
|
||||
this.context_menu.update(cx, |context_menu, cx| {
|
||||
context_menu.show(
|
||||
e.position,
|
||||
gpui::elements::AnchorCorner::BottomLeft,
|
||||
vec![ContextMenuItem::action(
|
||||
"Remove Channel",
|
||||
RemoveChannel { channel_id },
|
||||
)],
|
||||
cx,
|
||||
);
|
||||
});
|
||||
this.deploy_channel_context_menu(e.position, channel_id, cx);
|
||||
})
|
||||
.into_any()
|
||||
}
|
||||
|
@ -1489,6 +1486,25 @@ impl CollabPanel {
|
|||
.into_any()
|
||||
}
|
||||
|
||||
fn deploy_channel_context_menu(
|
||||
&mut self,
|
||||
position: Vector2F,
|
||||
channel_id: u64,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
self.context_menu.update(cx, |context_menu, cx| {
|
||||
context_menu.show(
|
||||
position,
|
||||
gpui::elements::AnchorCorner::BottomLeft,
|
||||
vec![
|
||||
ContextMenuItem::action("New Channel", NewChannel { channel_id }),
|
||||
ContextMenuItem::action("Remove Channel", RemoveChannel { channel_id }),
|
||||
],
|
||||
cx,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
|
||||
let mut did_clear = self.filter_editor.update(cx, |editor, cx| {
|
||||
if editor.buffer().read(cx).len(cx) > 0 {
|
||||
|
@ -1553,15 +1569,15 @@ impl CollabPanel {
|
|||
if let Some(selection) = self.selection {
|
||||
if let Some(entry) = self.entries.get(selection) {
|
||||
match entry {
|
||||
ContactEntry::Header(section, _) => {
|
||||
ListEntry::Header(section, _) => {
|
||||
self.toggle_expanded(*section, cx);
|
||||
}
|
||||
ContactEntry::Contact { contact, calling } => {
|
||||
ListEntry::Contact { contact, calling } => {
|
||||
if contact.online && !contact.busy && !calling {
|
||||
self.call(contact.user.id, Some(self.project.clone()), cx);
|
||||
}
|
||||
}
|
||||
ContactEntry::ParticipantProject {
|
||||
ListEntry::ParticipantProject {
|
||||
project_id,
|
||||
host_user_id,
|
||||
..
|
||||
|
@ -1577,7 +1593,7 @@ impl CollabPanel {
|
|||
.detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
ContactEntry::ParticipantScreen { peer_id, .. } => {
|
||||
ListEntry::ParticipantScreen { peer_id, .. } => {
|
||||
if let Some(workspace) = self.workspace.upgrade(cx) {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.open_shared_screen(*peer_id, cx)
|
||||
|
@ -1587,9 +1603,9 @@ impl CollabPanel {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
} else if let Some((_editing_state, channel_name)) = self.take_editing_state(cx) {
|
||||
} else if let Some((editing_state, channel_name)) = self.take_editing_state(cx) {
|
||||
let create_channel = self.channel_store.update(cx, |channel_store, cx| {
|
||||
channel_store.create_channel(&channel_name, None)
|
||||
channel_store.create_channel(&channel_name, editing_state.parent_id)
|
||||
});
|
||||
|
||||
cx.foreground()
|
||||
|
@ -1623,6 +1639,28 @@ impl CollabPanel {
|
|||
}
|
||||
}
|
||||
|
||||
fn new_root_channel(&mut self, cx: &mut ViewContext<Self>) {
|
||||
if self.channel_editing_state.is_none() {
|
||||
self.channel_editing_state = Some(ChannelEditingState { parent_id: None });
|
||||
self.update_entries(cx);
|
||||
}
|
||||
|
||||
cx.focus(self.channel_name_editor.as_any());
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn new_subchannel(&mut self, action: &NewChannel, cx: &mut ViewContext<Self>) {
|
||||
if self.channel_editing_state.is_none() {
|
||||
self.channel_editing_state = Some(ChannelEditingState {
|
||||
parent_id: Some(action.channel_id),
|
||||
});
|
||||
self.update_entries(cx);
|
||||
}
|
||||
|
||||
cx.focus(self.channel_name_editor.as_any());
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn remove_channel(&mut self, action: &RemoveChannel, cx: &mut ViewContext<Self>) {
|
||||
let channel_id = action.channel_id;
|
||||
let channel_store = self.channel_store.clone();
|
||||
|
@ -1838,9 +1876,9 @@ impl Panel for CollabPanel {
|
|||
}
|
||||
}
|
||||
|
||||
impl ContactEntry {
|
||||
impl ListEntry {
|
||||
fn is_selectable(&self) -> bool {
|
||||
if let ContactEntry::Header(_, 0) = self {
|
||||
if let ListEntry::Header(_, 0) = self {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
|
@ -1848,24 +1886,24 @@ impl ContactEntry {
|
|||
}
|
||||
}
|
||||
|
||||
impl PartialEq for ContactEntry {
|
||||
impl PartialEq for ListEntry {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match self {
|
||||
ContactEntry::Header(section_1, depth_1) => {
|
||||
if let ContactEntry::Header(section_2, depth_2) = other {
|
||||
ListEntry::Header(section_1, depth_1) => {
|
||||
if let ListEntry::Header(section_2, depth_2) = other {
|
||||
return section_1 == section_2 && depth_1 == depth_2;
|
||||
}
|
||||
}
|
||||
ContactEntry::CallParticipant { user: user_1, .. } => {
|
||||
if let ContactEntry::CallParticipant { user: user_2, .. } = other {
|
||||
ListEntry::CallParticipant { user: user_1, .. } => {
|
||||
if let ListEntry::CallParticipant { user: user_2, .. } = other {
|
||||
return user_1.id == user_2.id;
|
||||
}
|
||||
}
|
||||
ContactEntry::ParticipantProject {
|
||||
ListEntry::ParticipantProject {
|
||||
project_id: project_id_1,
|
||||
..
|
||||
} => {
|
||||
if let ContactEntry::ParticipantProject {
|
||||
if let ListEntry::ParticipantProject {
|
||||
project_id: project_id_2,
|
||||
..
|
||||
} = other
|
||||
|
@ -1873,46 +1911,51 @@ impl PartialEq for ContactEntry {
|
|||
return project_id_1 == project_id_2;
|
||||
}
|
||||
}
|
||||
ContactEntry::ParticipantScreen {
|
||||
ListEntry::ParticipantScreen {
|
||||
peer_id: peer_id_1, ..
|
||||
} => {
|
||||
if let ContactEntry::ParticipantScreen {
|
||||
if let ListEntry::ParticipantScreen {
|
||||
peer_id: peer_id_2, ..
|
||||
} = other
|
||||
{
|
||||
return peer_id_1 == peer_id_2;
|
||||
}
|
||||
}
|
||||
ContactEntry::Channel(channel_1) => {
|
||||
if let ContactEntry::Channel(channel_2) = other {
|
||||
ListEntry::Channel(channel_1) => {
|
||||
if let ListEntry::Channel(channel_2) = other {
|
||||
return channel_1.id == channel_2.id;
|
||||
}
|
||||
}
|
||||
ContactEntry::ChannelInvite(channel_1) => {
|
||||
if let ContactEntry::ChannelInvite(channel_2) = other {
|
||||
ListEntry::ChannelInvite(channel_1) => {
|
||||
if let ListEntry::ChannelInvite(channel_2) = other {
|
||||
return channel_1.id == channel_2.id;
|
||||
}
|
||||
}
|
||||
ContactEntry::IncomingRequest(user_1) => {
|
||||
if let ContactEntry::IncomingRequest(user_2) = other {
|
||||
ListEntry::IncomingRequest(user_1) => {
|
||||
if let ListEntry::IncomingRequest(user_2) = other {
|
||||
return user_1.id == user_2.id;
|
||||
}
|
||||
}
|
||||
ContactEntry::OutgoingRequest(user_1) => {
|
||||
if let ContactEntry::OutgoingRequest(user_2) = other {
|
||||
ListEntry::OutgoingRequest(user_1) => {
|
||||
if let ListEntry::OutgoingRequest(user_2) = other {
|
||||
return user_1.id == user_2.id;
|
||||
}
|
||||
}
|
||||
ContactEntry::Contact {
|
||||
ListEntry::Contact {
|
||||
contact: contact_1, ..
|
||||
} => {
|
||||
if let ContactEntry::Contact {
|
||||
if let ListEntry::Contact {
|
||||
contact: contact_2, ..
|
||||
} = other
|
||||
{
|
||||
return contact_1.user.id == contact_2.user.id;
|
||||
}
|
||||
}
|
||||
ListEntry::ChannelEditor { depth } => {
|
||||
if let ListEntry::ChannelEditor { depth: other_depth } = other {
|
||||
return depth == other_depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue