@@ -1100,16 +1100,21 @@ async fn test_channel_membership_notifications(
let user_b = client_b.user_id().unwrap();
let channels = server
- .make_channel_tree(&[("zed", None), ("vim", Some("zed"))], (&client_a, cx_a))
+ .make_channel_tree(
+ &[("zed", None), ("vim", Some("zed")), ("opensource", None)],
+ (&client_a, cx_a),
+ )
.await;
let zed_channel = channels[0];
let vim_channel = channels[1];
+ let opensource_channel = channels[2];
try_join_all(client_a.channel_store().update(cx_a, |channel_store, cx| {
[
channel_store.set_channel_visibility(zed_channel, proto::ChannelVisibility::Public, cx),
channel_store.set_channel_visibility(vim_channel, proto::ChannelVisibility::Public, cx),
- channel_store.invite_member(zed_channel, user_b, proto::ChannelRole::Guest, cx),
+ channel_store.invite_member(zed_channel, user_b, proto::ChannelRole::Admin, cx),
+ channel_store.invite_member(opensource_channel, user_b, proto::ChannelRole::Member, cx),
]
}))
.await
@@ -1144,6 +1149,34 @@ async fn test_channel_membership_notifications(
},
],
);
+
+ client_b.channel_store().update(cx_b, |channel_store, _| {
+ channel_store.is_channel_admin(zed_channel)
+ });
+
+ client_b
+ .channel_store()
+ .update(cx_b, |channel_store, cx| {
+ channel_store.respond_to_channel_invite(opensource_channel, true, cx)
+ })
+ .await
+ .unwrap();
+
+ cx_a.run_until_parked();
+
+ client_a
+ .channel_store()
+ .update(cx_a, |channel_store, cx| {
+ channel_store.set_member_role(opensource_channel, user_b, ChannelRole::Admin, cx)
+ })
+ .await
+ .unwrap();
+
+ cx_a.run_until_parked();
+
+ client_b.channel_store().update(cx_b, |channel_store, _| {
+ channel_store.is_channel_admin(opensource_channel)
+ });
}
#[gpui::test]
@@ -23,7 +23,7 @@ use gpui::{
use menu::{Cancel, Confirm, SecondaryConfirm, SelectNext, SelectPrev};
use project::{Fs, Project};
use rpc::{
- proto::{self, PeerId},
+ proto::{self, ChannelVisibility, PeerId},
ErrorCode, ErrorExt,
};
use serde_derive::{Deserialize, Serialize};
@@ -1134,13 +1134,6 @@ impl CollabPanel {
"Rename",
Some(Box::new(SecondaryConfirm)),
cx.handler_for(&this, move |this, cx| this.rename_channel(channel_id, cx)),
- )
- .entry(
- "Move this channel",
- None,
- cx.handler_for(&this, move |this, cx| {
- this.start_move_channel(channel_id, cx)
- }),
);
if let Some(channel_name) = clipboard_channel_name {
@@ -1153,23 +1146,52 @@ impl CollabPanel {
);
}
- context_menu = context_menu
- .separator()
- .entry(
- "Invite Members",
- None,
- cx.handler_for(&this, move |this, cx| this.invite_members(channel_id, cx)),
- )
- .entry(
+ if self.channel_store.read(cx).is_root_channel(channel_id) {
+ context_menu = context_menu.separator().entry(
"Manage Members",
None,
cx.handler_for(&this, move |this, cx| this.manage_members(channel_id, cx)),
)
- .entry(
- "Delete",
+ } else {
+ context_menu = context_menu.entry(
+ "Move this channel",
None,
- cx.handler_for(&this, move |this, cx| this.remove_channel(channel_id, cx)),
+ cx.handler_for(&this, move |this, cx| {
+ this.start_move_channel(channel_id, cx)
+ }),
);
+ if self.channel_store.read(cx).is_public_channel(channel_id) {
+ context_menu = context_menu.separator().entry(
+ "Make Channel Private",
+ None,
+ cx.handler_for(&this, move |this, cx| {
+ this.set_channel_visibility(
+ channel_id,
+ ChannelVisibility::Members,
+ cx,
+ )
+ }),
+ )
+ } else {
+ context_menu = context_menu.separator().entry(
+ "Make Channel Public",
+ None,
+ cx.handler_for(&this, move |this, cx| {
+ this.set_channel_visibility(
+ channel_id,
+ ChannelVisibility::Public,
+ cx,
+ )
+ }),
+ )
+ }
+ }
+
+ context_menu = context_menu.entry(
+ "Delete",
+ None,
+ cx.handler_for(&this, move |this, cx| this.remove_channel(channel_id, cx)),
+ );
}
context_menu
@@ -1490,10 +1512,6 @@ impl CollabPanel {
cx.notify();
}
- fn invite_members(&mut self, channel_id: ChannelId, cx: &mut ViewContext<Self>) {
- self.show_channel_modal(channel_id, channel_modal::Mode::InviteMembers, cx);
- }
-
fn manage_members(&mut self, channel_id: ChannelId, cx: &mut ViewContext<Self>) {
self.show_channel_modal(channel_id, channel_modal::Mode::ManageMembers, cx);
}
@@ -1530,6 +1548,27 @@ impl CollabPanel {
}
}
+ fn set_channel_visibility(
+ &mut self,
+ channel_id: ChannelId,
+ visibility: ChannelVisibility,
+ cx: &mut ViewContext<Self>,
+ ) {
+ self.channel_store
+ .update(cx, |channel_store, cx| {
+ channel_store.set_channel_visibility(channel_id, visibility, cx)
+ })
+ .detach_and_prompt_err("Failed to set channel visibility", cx, |e, _| match e.error_code() {
+ ErrorCode::BadPublicNesting =>
+ if e.error_tag("direction") == Some("parent") {
+ Some("To make a channel public, its parent channel must be public.".to_string())
+ } else {
+ Some("To make a channel private, all of its subchannels must be private.".to_string())
+ },
+ _ => None
+ });
+ }
+
fn start_move_channel(&mut self, channel_id: ChannelId, _cx: &mut ViewContext<Self>) {
self.channel_clipboard = Some(ChannelMoveClipboard { channel_id });
}