Tune UX for context menus

Co-authored-by: max <max@zed.dev>
This commit is contained in:
Mikayla 2023-08-07 17:14:09 -07:00
parent bedf60b6b2
commit fa71de8842
No known key found for this signature in database
3 changed files with 56 additions and 21 deletions

View file

@ -165,17 +165,29 @@ impl UserStore {
}); });
current_user_tx.send(user).await.ok(); current_user_tx.send(user).await.ok();
this.update(&mut cx, |_, cx| {
cx.notify();
});
} }
} }
Status::SignedOut => { Status::SignedOut => {
current_user_tx.send(None).await.ok(); current_user_tx.send(None).await.ok();
if let Some(this) = this.upgrade(&cx) { if let Some(this) = this.upgrade(&cx) {
this.update(&mut cx, |this, _| this.clear_contacts()).await; this.update(&mut cx, |this, cx| {
cx.notify();
this.clear_contacts()
})
.await;
} }
} }
Status::ConnectionLost => { Status::ConnectionLost => {
if let Some(this) = this.upgrade(&cx) { if let Some(this) = this.upgrade(&cx) {
this.update(&mut cx, |this, _| this.clear_contacts()).await; this.update(&mut cx, |this, cx| {
cx.notify();
this.clear_contacts()
})
.await;
} }
} }
_ => {} _ => {}

View file

@ -4,7 +4,7 @@ mod panel_settings;
use anyhow::Result; use anyhow::Result;
use call::ActiveCall; use call::ActiveCall;
use client::{proto::PeerId, Channel, ChannelStore, Client, Contact, User, UserStore}; use client::{proto::PeerId, Channel, ChannelId, ChannelStore, Client, Contact, User, UserStore};
use contact_finder::build_contact_finder; use contact_finder::build_contact_finder;
use context_menu::{ContextMenu, ContextMenuItem}; use context_menu::{ContextMenu, ContextMenuItem};
use db::kvp::KEY_VALUE_STORE; use db::kvp::KEY_VALUE_STORE;
@ -55,13 +55,21 @@ struct NewChannel {
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
struct AddMember { struct InviteMembers {
channel_id: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
struct ManageMembers {
channel_id: u64, channel_id: u64,
} }
actions!(collab_panel, [ToggleFocus]); actions!(collab_panel, [ToggleFocus]);
impl_actions!(collab_panel, [RemoveChannel, NewChannel, AddMember]); impl_actions!(
collab_panel,
[RemoveChannel, NewChannel, InviteMembers, ManageMembers]
);
const CHANNELS_PANEL_KEY: &'static str = "ChannelsPanel"; const CHANNELS_PANEL_KEY: &'static str = "ChannelsPanel";
@ -76,7 +84,8 @@ pub fn init(_client: Arc<Client>, cx: &mut AppContext) {
cx.add_action(CollabPanel::confirm); cx.add_action(CollabPanel::confirm);
cx.add_action(CollabPanel::remove_channel); cx.add_action(CollabPanel::remove_channel);
cx.add_action(CollabPanel::new_subchannel); cx.add_action(CollabPanel::new_subchannel);
cx.add_action(CollabPanel::add_member); cx.add_action(CollabPanel::invite_members);
cx.add_action(CollabPanel::manage_members);
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -325,6 +334,7 @@ impl CollabPanel {
client: workspace.app_state().client.clone(), client: workspace.app_state().client.clone(),
list_state, list_state,
}; };
this.update_entries(cx); this.update_entries(cx);
// Update the dock position when the setting changes. // Update the dock position when the setting changes.
@ -1549,7 +1559,8 @@ impl CollabPanel {
vec![ vec![
ContextMenuItem::action("New Channel", NewChannel { channel_id }), ContextMenuItem::action("New Channel", NewChannel { channel_id }),
ContextMenuItem::action("Remove Channel", RemoveChannel { channel_id }), ContextMenuItem::action("Remove Channel", RemoveChannel { channel_id }),
ContextMenuItem::action("Add member", AddMember { channel_id }), ContextMenuItem::action("Manage members", ManageMembers { channel_id }),
ContextMenuItem::action("Invite members", InviteMembers { channel_id }),
], ],
cx, cx,
); );
@ -1710,8 +1721,20 @@ impl CollabPanel {
cx.notify(); cx.notify();
} }
fn add_member(&mut self, action: &AddMember, cx: &mut ViewContext<Self>) { fn invite_members(&mut self, action: &InviteMembers, cx: &mut ViewContext<Self>) {
let channel_id = action.channel_id; self.show_channel_modal(action.channel_id, channel_modal::Mode::InviteMembers, cx);
}
fn manage_members(&mut self, action: &ManageMembers, cx: &mut ViewContext<Self>) {
self.show_channel_modal(action.channel_id, channel_modal::Mode::ManageMembers, cx);
}
fn show_channel_modal(
&mut self,
channel_id: ChannelId,
mode: channel_modal::Mode,
cx: &mut ViewContext<Self>,
) {
let workspace = self.workspace.clone(); let workspace = self.workspace.clone();
let user_store = self.user_store.clone(); let user_store = self.user_store.clone();
let channel_store = self.channel_store.clone(); let channel_store = self.channel_store.clone();
@ -1728,7 +1751,7 @@ impl CollabPanel {
user_store.clone(), user_store.clone(),
channel_store.clone(), channel_store.clone(),
channel_id, channel_id,
channel_modal::Mode::InviteMembers, mode,
members, members,
cx, cx,
) )
@ -1879,12 +1902,8 @@ impl View for CollabPanel {
}) })
.on_click(MouseButton::Left, |_, this, cx| { .on_click(MouseButton::Left, |_, this, cx| {
let client = this.client.clone(); let client = this.client.clone();
cx.spawn(|this, mut cx| async move { cx.spawn(|_, cx| async move {
client.authenticate_and_connect(true, &cx).await.log_err(); client.authenticate_and_connect(true, &cx).await.log_err();
this.update(&mut cx, |_, cx| {
cx.notify();
})
}) })
.detach(); .detach();
}) })

View file

@ -337,7 +337,7 @@ impl PickerDelegate for ChannelModalDelegate {
Mode::ManageMembers => self.show_context_menu(admin.unwrap_or(false), cx), Mode::ManageMembers => self.show_context_menu(admin.unwrap_or(false), 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_selected_member(cx);
} }
Some(proto::channel_member::Kind::AncestorMember) | None => { Some(proto::channel_member::Kind::AncestorMember) | None => {
self.invite_member(selected_user, cx) self.invite_member(selected_user, cx)
@ -502,6 +502,7 @@ impl ChannelModalDelegate {
if let Some(member) = this.members.iter_mut().find(|m| m.user.id == user.id) { if let Some(member) = this.members.iter_mut().find(|m| m.user.id == user.id) {
member.admin = admin; member.admin = admin;
} }
cx.focus_self();
cx.notify(); cx.notify();
}) })
}) })
@ -511,11 +512,7 @@ impl ChannelModalDelegate {
fn remove_selected_member(&mut self, cx: &mut ViewContext<Picker<Self>>) -> Option<()> { fn remove_selected_member(&mut self, cx: &mut ViewContext<Picker<Self>>) -> Option<()> {
let (user, _) = self.user_at_index(self.selected_index)?; let (user, _) = self.user_at_index(self.selected_index)?;
self.remove_member(user.id, cx); let user_id = user.id;
Some(())
}
fn remove_member(&mut self, user_id: u64, cx: &mut ViewContext<Picker<Self>>) {
let update = self.channel_store.update(cx, |store, cx| { let update = self.channel_store.update(cx, |store, cx| {
store.remove_member(self.channel_id, user_id, cx) store.remove_member(self.channel_id, user_id, cx)
}); });
@ -534,10 +531,17 @@ impl ChannelModalDelegate {
true true
}) })
} }
this.selected_index = this
.selected_index
.min(this.matching_member_indices.len() - 1);
cx.focus_self();
cx.notify(); cx.notify();
}) })
}) })
.detach_and_log_err(cx); .detach_and_log_err(cx);
Some(())
} }
fn invite_member(&mut self, user: Arc<User>, cx: &mut ViewContext<Picker<Self>>) { fn invite_member(&mut self, user: Arc<User>, cx: &mut ViewContext<Picker<Self>>) {