Open chat when joining a channel with guests

Conrad Irwin created

(and close it when leaving a channel again)

Change summary

crates/call/src/call.rs                                           |  6 
crates/call/src/room.rs                                           | 17 
crates/collab_ui/src/chat_panel.rs                                | 21 
crates/collab_ui/src/notifications/project_shared_notification.rs |  2 
4 files changed, 35 insertions(+), 11 deletions(-)

Detailed changes

crates/call/src/call.rs 🔗

@@ -442,10 +442,8 @@ impl ActiveCall {
                         .location
                         .as_ref()
                         .and_then(|location| location.upgrade());
-                    let (channel_id, role) = room.update(cx, |room, _| {
-                        (room.channel_id(), room.local_participant().role)
-                    });
-                    cx.emit(Event::RoomJoined { channel_id, role });
+                    let channel_id = room.read(cx).channel_id();
+                    cx.emit(Event::RoomJoined { channel_id });
                     room.update(cx, |room, cx| room.set_location(location.as_ref(), cx))
                 }
             } else {

crates/call/src/room.rs 🔗

@@ -28,7 +28,6 @@ pub const RECONNECT_TIMEOUT: Duration = Duration::from_secs(30);
 pub enum Event {
     RoomJoined {
         channel_id: Option<u64>,
-        role: proto::ChannelRole,
     },
     ParticipantLocationChanged {
         participant_id: proto::PeerId,
@@ -53,7 +52,9 @@ pub enum Event {
     RemoteProjectInvitationDiscarded {
         project_id: u64,
     },
-    Left,
+    Left {
+        channel_id: Option<u64>,
+    },
 }
 
 pub struct Room {
@@ -361,7 +362,9 @@ impl Room {
 
     pub(crate) fn leave(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
         cx.notify();
-        cx.emit(Event::Left);
+        cx.emit(Event::Left {
+            channel_id: self.channel_id(),
+        });
         self.leave_internal(cx)
     }
 
@@ -602,6 +605,14 @@ impl Room {
             .map(|participant| participant.role)
     }
 
+    pub fn contains_guests(&self) -> bool {
+        self.local_participant.role == proto::ChannelRole::Guest
+            || self
+                .remote_participants
+                .values()
+                .any(|p| p.role == proto::ChannelRole::Guest)
+    }
+
     pub fn local_participant_is_admin(&self) -> bool {
         self.local_participant.role == proto::ChannelRole::Admin
     }

crates/collab_ui/src/chat_panel.rs 🔗

@@ -143,17 +143,26 @@ impl ChatPanel {
             ));
             this.subscriptions.push(cx.subscribe(
                 &ActiveCall::global(cx),
-                move |this: &mut Self, _, event: &room::Event, cx| match event {
-                    room::Event::RoomJoined { channel_id, role } => {
+                move |this: &mut Self, call, event: &room::Event, cx| match event {
+                    room::Event::RoomJoined { channel_id } => {
                         if let Some(channel_id) = channel_id {
                             this.select_channel(*channel_id, None, cx)
                                 .detach_and_log_err(cx);
 
-                            if *role == proto::ChannelRole::Guest {
+                            if call
+                                .read(cx)
+                                .room()
+                                .is_some_and(|room| room.read(cx).contains_guests())
+                            {
                                 cx.emit(PanelEvent::Activate)
                             }
                         }
                     }
+                    room::Event::Left { channel_id } => {
+                        if channel_id == &this.channel_id(cx) {
+                            cx.emit(PanelEvent::Close)
+                        }
+                    }
                     _ => {}
                 },
             ));
@@ -162,6 +171,12 @@ impl ChatPanel {
         })
     }
 
+    pub fn channel_id(&self, cx: &AppContext) -> Option<u64> {
+        self.active_chat
+            .as_ref()
+            .map(|(chat, _)| chat.read(cx).channel_id)
+    }
+
     pub fn is_scrolled_to_bottom(&self) -> bool {
         self.is_scrolled_to_bottom
     }