channel management fixes (#4066)

- Close modals when focus leaves
- Disallow self-management for admins

Release Notes:

- Fixes changing role of invited channel members
This commit is contained in:
Conrad Irwin 2024-01-16 14:53:14 -07:00 committed by GitHub
commit 6bcc97ead4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 22 additions and 14 deletions

View file

@ -348,6 +348,10 @@ 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, role)) = self.user_at_index(self.selected_index) {
if Some(selected_user.id) == self.user_store.read(cx).current_user().map(|user| user.id)
{
return;
}
match self.mode { match self.mode {
Mode::ManageMembers => { Mode::ManageMembers => {
self.show_context_menu(selected_user, role.unwrap_or(ChannelRole::Member), cx) self.show_context_menu(selected_user, role.unwrap_or(ChannelRole::Member), cx)
@ -383,6 +387,7 @@ impl PickerDelegate for ChannelModalDelegate {
) -> Option<Self::ListItem> { ) -> Option<Self::ListItem> {
let (user, role) = self.user_at_index(ix)?; let (user, role) = self.user_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);
Some( Some(
ListItem::new(ix) ListItem::new(ix)
@ -406,7 +411,10 @@ impl PickerDelegate for ChannelModalDelegate {
Some(ChannelRole::Guest) => Some(Label::new("Guest")), Some(ChannelRole::Guest) => Some(Label::new("Guest")),
_ => None, _ => None,
}) })
.child(IconButton::new("ellipsis", IconName::Ellipsis)) .when(!is_me, |el| {
el.child(IconButton::new("ellipsis", IconName::Ellipsis))
})
.when(is_me, |el| el.child(Label::new("You").color(Color::Muted)))
.children( .children(
if let (Some((menu, _)), true) = (&self.context_menu, selected) { if let (Some((menu, _)), true) = (&self.context_menu, selected) {
Some( Some(

View file

@ -27,7 +27,7 @@ impl<V: ModalView> ModalViewHandle for View<V> {
pub struct ActiveModal { pub struct ActiveModal {
modal: Box<dyn ModalViewHandle>, modal: Box<dyn ModalViewHandle>,
_subscription: Subscription, _subscriptions: [Subscription; 2],
previous_focus_handle: Option<FocusHandle>, previous_focus_handle: Option<FocusHandle>,
focus_handle: FocusHandle, focus_handle: FocusHandle,
} }
@ -61,13 +61,19 @@ impl ModalLayer {
where where
V: ModalView, V: ModalView,
{ {
let focus_handle = cx.focus_handle();
self.active_modal = Some(ActiveModal { self.active_modal = Some(ActiveModal {
modal: Box::new(new_modal.clone()), modal: Box::new(new_modal.clone()),
_subscription: cx.subscribe(&new_modal, |this, _, _: &DismissEvent, cx| { _subscriptions: [
cx.subscribe(&new_modal, |this, _, _: &DismissEvent, cx| {
this.hide_modal(cx); this.hide_modal(cx);
}), }),
cx.on_focus_out(&focus_handle, |this, cx| {
this.hide_modal(cx);
}),
],
previous_focus_handle: cx.focused(), previous_focus_handle: cx.focused(),
focus_handle: cx.focus_handle(), focus_handle,
}); });
cx.focus_view(&new_modal); cx.focus_view(&new_modal);
cx.notify(); cx.notify();
@ -108,7 +114,7 @@ impl ModalLayer {
} }
impl Render for ModalLayer { impl Render for ModalLayer {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement { fn render(&mut self, _: &mut ViewContext<Self>) -> impl IntoElement {
let Some(active_modal) = &self.active_modal else { let Some(active_modal) = &self.active_modal else {
return div(); return div();
}; };
@ -127,13 +133,7 @@ impl Render for ModalLayer {
.flex_col() .flex_col()
.items_center() .items_center()
.track_focus(&active_modal.focus_handle) .track_focus(&active_modal.focus_handle)
.child( .child(h_flex().child(active_modal.modal.view())),
h_flex()
.on_mouse_down_out(cx.listener(|this, _, cx| {
this.hide_modal(cx);
}))
.child(active_modal.modal.view()),
),
) )
} }
} }