Update Channel membership UI
* Remove ability to act on people defined in parent channels * Show promote buttons on guests
This commit is contained in:
parent
2bfbd72483
commit
a9ddef8227
1 changed files with 79 additions and 49 deletions
|
@ -10,10 +10,11 @@ use gpui::{
|
||||||
WeakView,
|
WeakView,
|
||||||
};
|
};
|
||||||
use picker::{Picker, PickerDelegate};
|
use picker::{Picker, PickerDelegate};
|
||||||
|
use rpc::proto::channel_member;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ui::{prelude::*, Avatar, Checkbox, ContextMenu, ListItem, ListItemSpacing};
|
use ui::{prelude::*, Avatar, Checkbox, ContextMenu, ListItem, ListItemSpacing};
|
||||||
use util::TryFutureExt;
|
use util::TryFutureExt;
|
||||||
use workspace::ModalView;
|
use workspace::{notifications::NotifyTaskExt, ModalView};
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
channel_modal,
|
channel_modal,
|
||||||
|
@ -347,15 +348,13 @@ impl PickerDelegate for ChannelModalDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm(&mut self, _: bool, cx: &mut ViewContext<Picker<Self>>) {
|
fn confirm(&mut self, _: bool, cx: &mut ViewContext<Picker<Self>>) {
|
||||||
if let Some((selected_user, role)) = self.user_at_index(self.selected_index) {
|
if let Some(selected_user) = self.user_at_index(self.selected_index) {
|
||||||
if Some(selected_user.id) == self.user_store.read(cx).current_user().map(|user| user.id)
|
if Some(selected_user.id) == self.user_store.read(cx).current_user().map(|user| user.id)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
match self.mode {
|
match self.mode {
|
||||||
Mode::ManageMembers => {
|
Mode::ManageMembers => self.show_context_menu(self.selected_index, cx),
|
||||||
self.show_context_menu(selected_user, role.unwrap_or(ChannelRole::Member), cx)
|
|
||||||
}
|
|
||||||
Mode::InviteMembers => match self.member_status(selected_user.id, cx) {
|
Mode::InviteMembers => match self.member_status(selected_user.id, cx) {
|
||||||
Some(proto::channel_member::Kind::Invitee) => {
|
Some(proto::channel_member::Kind::Invitee) => {
|
||||||
self.remove_member(selected_user.id, cx);
|
self.remove_member(selected_user.id, cx);
|
||||||
|
@ -385,7 +384,8 @@ impl PickerDelegate for ChannelModalDelegate {
|
||||||
selected: bool,
|
selected: bool,
|
||||||
cx: &mut ViewContext<Picker<Self>>,
|
cx: &mut ViewContext<Picker<Self>>,
|
||||||
) -> Option<Self::ListItem> {
|
) -> Option<Self::ListItem> {
|
||||||
let (user, role) = self.user_at_index(ix)?;
|
let user = self.user_at_index(ix)?;
|
||||||
|
let membership = self.member_at_index(ix);
|
||||||
let request_status = self.member_status(user.id, cx);
|
let request_status = self.member_status(user.id, cx);
|
||||||
let is_me = self.user_store.read(cx).current_user().map(|user| user.id) == Some(user.id);
|
let is_me = self.user_store.read(cx).current_user().map(|user| user.id) == Some(user.id);
|
||||||
|
|
||||||
|
@ -402,11 +402,15 @@ impl PickerDelegate for ChannelModalDelegate {
|
||||||
.children(
|
.children(
|
||||||
if request_status == Some(proto::channel_member::Kind::Invitee) {
|
if request_status == Some(proto::channel_member::Kind::Invitee) {
|
||||||
Some(Label::new("Invited"))
|
Some(Label::new("Invited"))
|
||||||
|
} else if membership.map(|m| m.kind)
|
||||||
|
== Some(channel_member::Kind::AncestorMember)
|
||||||
|
{
|
||||||
|
Some(Label::new("Parent"))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.children(match role {
|
.children(match membership.map(|m| m.role) {
|
||||||
Some(ChannelRole::Admin) => Some(Label::new("Admin")),
|
Some(ChannelRole::Admin) => Some(Label::new("Admin")),
|
||||||
Some(ChannelRole::Guest) => Some(Label::new("Guest")),
|
Some(ChannelRole::Guest) => Some(Label::new("Guest")),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -419,7 +423,7 @@ impl PickerDelegate for ChannelModalDelegate {
|
||||||
if let (Some((menu, _)), true) = (&self.context_menu, selected) {
|
if let (Some((menu, _)), true) = (&self.context_menu, selected) {
|
||||||
Some(
|
Some(
|
||||||
overlay()
|
overlay()
|
||||||
.anchor(gpui::AnchorCorner::TopLeft)
|
.anchor(gpui::AnchorCorner::TopRight)
|
||||||
.child(menu.clone()),
|
.child(menu.clone()),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -458,16 +462,19 @@ impl ChannelModalDelegate {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn user_at_index(&self, ix: usize) -> Option<(Arc<User>, Option<ChannelRole>)> {
|
fn member_at_index(&self, ix: usize) -> Option<&ChannelMembership> {
|
||||||
|
self.matching_member_indices
|
||||||
|
.get(ix)
|
||||||
|
.and_then(|ix| self.members.get(*ix))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn user_at_index(&self, ix: usize) -> Option<Arc<User>> {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
Mode::ManageMembers => self.matching_member_indices.get(ix).and_then(|ix| {
|
Mode::ManageMembers => self.matching_member_indices.get(ix).and_then(|ix| {
|
||||||
let channel_membership = self.members.get(*ix)?;
|
let channel_membership = self.members.get(*ix)?;
|
||||||
Some((
|
Some(channel_membership.user.clone())
|
||||||
channel_membership.user.clone(),
|
|
||||||
Some(channel_membership.role),
|
|
||||||
))
|
|
||||||
}),
|
}),
|
||||||
Mode::InviteMembers => Some((self.matching_users.get(ix).cloned()?, None)),
|
Mode::InviteMembers => self.matching_users.get(ix).cloned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +498,7 @@ impl ChannelModalDelegate {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.detach_and_log_err(cx);
|
.detach_and_notify_err(cx);
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,7 +530,7 @@ impl ChannelModalDelegate {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.detach_and_log_err(cx);
|
.detach_and_notify_err(cx);
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,19 +556,66 @@ impl ChannelModalDelegate {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.detach_and_log_err(cx);
|
.detach_and_notify_err(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_context_menu(
|
fn show_context_menu(&mut self, ix: usize, cx: &mut ViewContext<Picker<Self>>) {
|
||||||
&mut self,
|
let Some(membership) = self.member_at_index(ix) else {
|
||||||
user: Arc<User>,
|
return;
|
||||||
role: ChannelRole,
|
};
|
||||||
cx: &mut ViewContext<Picker<Self>>,
|
if membership.kind == proto::channel_member::Kind::AncestorMember {
|
||||||
) {
|
return;
|
||||||
let user_id = user.id;
|
}
|
||||||
|
let user_id = membership.user.id;
|
||||||
let picker = cx.view().clone();
|
let picker = cx.view().clone();
|
||||||
let context_menu = ContextMenu::build(cx, |mut menu, _cx| {
|
let context_menu = ContextMenu::build(cx, |mut menu, _cx| {
|
||||||
menu = menu.entry("Remove Member", None, {
|
if membership.kind == channel_member::Kind::AncestorMember {
|
||||||
|
return menu.entry("Inherited membership", None, |_| {});
|
||||||
|
};
|
||||||
|
|
||||||
|
let role = membership.role;
|
||||||
|
|
||||||
|
if role == ChannelRole::Admin || role == ChannelRole::Member {
|
||||||
|
let picker = picker.clone();
|
||||||
|
menu = menu.entry("Demote to Guest", None, move |cx| {
|
||||||
|
picker.update(cx, |picker, cx| {
|
||||||
|
picker
|
||||||
|
.delegate
|
||||||
|
.set_user_role(user_id, ChannelRole::Guest, cx);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if role == ChannelRole::Admin || role == ChannelRole::Guest {
|
||||||
|
let picker = picker.clone();
|
||||||
|
let label = if role == ChannelRole::Guest {
|
||||||
|
"Promote to Member"
|
||||||
|
} else {
|
||||||
|
"Demote to Member"
|
||||||
|
};
|
||||||
|
|
||||||
|
menu = menu.entry(label, None, move |cx| {
|
||||||
|
picker.update(cx, |picker, cx| {
|
||||||
|
picker
|
||||||
|
.delegate
|
||||||
|
.set_user_role(user_id, ChannelRole::Member, cx);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if role == ChannelRole::Member || role == ChannelRole::Guest {
|
||||||
|
let picker = picker.clone();
|
||||||
|
menu = menu.entry("Promote to Admin", None, move |cx| {
|
||||||
|
picker.update(cx, |picker, cx| {
|
||||||
|
picker
|
||||||
|
.delegate
|
||||||
|
.set_user_role(user_id, ChannelRole::Admin, cx);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
menu = menu.separator();
|
||||||
|
menu = menu.entry("Remove from Channel", None, {
|
||||||
let picker = picker.clone();
|
let picker = picker.clone();
|
||||||
move |cx| {
|
move |cx| {
|
||||||
picker.update(cx, |picker, cx| {
|
picker.update(cx, |picker, cx| {
|
||||||
|
@ -569,30 +623,6 @@ impl ChannelModalDelegate {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let picker = picker.clone();
|
|
||||||
match role {
|
|
||||||
ChannelRole::Admin => {
|
|
||||||
menu = menu.entry("Revoke Admin", None, move |cx| {
|
|
||||||
picker.update(cx, |picker, cx| {
|
|
||||||
picker
|
|
||||||
.delegate
|
|
||||||
.set_user_role(user_id, ChannelRole::Member, cx);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ChannelRole::Member => {
|
|
||||||
menu = menu.entry("Make Admin", None, move |cx| {
|
|
||||||
picker.update(cx, |picker, cx| {
|
|
||||||
picker
|
|
||||||
.delegate
|
|
||||||
.set_user_role(user_id, ChannelRole::Admin, cx);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
|
|
||||||
menu
|
menu
|
||||||
});
|
});
|
||||||
cx.focus_view(&context_menu);
|
cx.focus_view(&context_menu);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue