collab ui: Dismiss project shared notifications when leaving room (#10160)

Bennet Bo Fenner created

When leaving a call/room in which a project was shared, the shared
project notification was not getting dismissed when the person that
shared the project left the room.
Although there was a `cx.emit(Event::Left)` call inside room, the event
was never received in the `project_shared_notification` module, because
the room is dropped before the event can be dispatched. Moving the
`cx.emit(Event::Left)` to the active call fixed the problem. Also
renamed `Event::Left` to `Event::RoomLeft` because the room join
equivalent is also called `Event::RoomJoined`.


Release Notes:

- Fixed project shared notification staying open, when the user that
shared the project left the room

Change summary

crates/call/src/call.rs                                           |  3 
crates/call/src/room.rs                                           |  5 
crates/collab/src/tests/integration_tests.rs                      | 18 +
crates/collab_ui/src/chat_panel.rs                                |  2 
crates/collab_ui/src/notifications/project_shared_notification.rs |  2 
5 files changed, 24 insertions(+), 6 deletions(-)

Detailed changes

crates/call/src/call.rs 🔗

@@ -373,7 +373,10 @@ impl ActiveCall {
         self.report_call_event("hang up", cx);
 
         Audio::end_call(cx);
+
+        let channel_id = self.channel_id(cx);
         if let Some((room, _)) = self.room.take() {
+            cx.emit(Event::RoomLeft { channel_id });
             room.update(cx, |room, cx| room.leave(cx))
         } else {
             Task::ready(Ok(()))

crates/call/src/room.rs 🔗

@@ -52,7 +52,7 @@ pub enum Event {
     RemoteProjectInvitationDiscarded {
         project_id: u64,
     },
-    Left {
+    RoomLeft {
         channel_id: Option<ChannelId>,
     },
 }
@@ -366,9 +366,6 @@ impl Room {
 
     pub(crate) fn leave(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
         cx.notify();
-        cx.emit(Event::Left {
-            channel_id: self.channel_id(),
-        });
         self.leave_internal(cx)
     }
 

crates/collab/src/tests/integration_tests.rs 🔗

@@ -1866,6 +1866,24 @@ async fn test_active_call_events(
     executor.run_until_parked();
     assert_eq!(mem::take(&mut *events_a.borrow_mut()), vec![]);
     assert_eq!(mem::take(&mut *events_b.borrow_mut()), vec![]);
+
+    // Unsharing a project should dispatch the RemoteProjectUnshared event.
+    active_call_a
+        .update(cx_a, |call, cx| call.hang_up(cx))
+        .await
+        .unwrap();
+    executor.run_until_parked();
+
+    assert_eq!(
+        mem::take(&mut *events_a.borrow_mut()),
+        vec![room::Event::RoomLeft { channel_id: None }]
+    );
+    assert_eq!(
+        mem::take(&mut *events_b.borrow_mut()),
+        vec![room::Event::RemoteProjectUnshared {
+            project_id: project_a_id,
+        }]
+    );
 }
 
 fn active_call_events(cx: &mut TestAppContext) -> Rc<RefCell<Vec<room::Event>>> {

crates/collab_ui/src/chat_panel.rs 🔗

@@ -156,7 +156,7 @@ impl ChatPanel {
                             }
                         }
                     }
-                    room::Event::Left { channel_id } => {
+                    room::Event::RoomLeft { channel_id } => {
                         if channel_id == &this.channel_id(cx) {
                             cx.emit(PanelEvent::Close)
                         }