2112 (#7640)

Conrad Irwin created

It's still slow, but should now work reliably

Release Notes:

- N/A

Change summary

crates/call/src/call.rs              | 21 ++++++++++++++++++---
crates/collab_ui/src/collab_panel.rs | 19 ++++++++++++++++++-
2 files changed, 36 insertions(+), 4 deletions(-)

Detailed changes

crates/call/src/call.rs 🔗

@@ -84,6 +84,7 @@ pub struct ActiveCall {
     ),
     client: Arc<Client>,
     user_store: Model<UserStore>,
+    pending_channel_id: Option<u64>,
     _subscriptions: Vec<client::Subscription>,
 }
 
@@ -97,6 +98,7 @@ impl ActiveCall {
             location: None,
             pending_invites: Default::default(),
             incoming_call: watch::channel(),
+            pending_channel_id: None,
             _join_debouncer: OneAtATime { cancel: None },
             _subscriptions: vec![
                 client.add_request_handler(cx.weak_model(), Self::handle_incoming_call),
@@ -111,6 +113,10 @@ impl ActiveCall {
         self.room()?.read(cx).channel_id()
     }
 
+    pub fn pending_channel_id(&self) -> Option<u64> {
+        self.pending_channel_id
+    }
+
     async fn handle_incoming_call(
         this: Model<Self>,
         envelope: TypedEnvelope<proto::IncomingCall>,
@@ -339,11 +345,13 @@ impl ActiveCall {
         channel_id: u64,
         cx: &mut ModelContext<Self>,
     ) -> Task<Result<Option<Model<Room>>>> {
+        let mut leave = None;
         if let Some(room) = self.room().cloned() {
             if room.read(cx).channel_id() == Some(channel_id) {
                 return Task::ready(Ok(Some(room)));
             } else {
-                room.update(cx, |room, cx| room.clear_state(cx));
+                let (room, _) = self.room.take().unwrap();
+                leave = room.update(cx, |room, cx| Some(room.leave(cx)));
             }
         }
 
@@ -353,14 +361,21 @@ impl ActiveCall {
 
         let client = self.client.clone();
         let user_store = self.user_store.clone();
+        self.pending_channel_id = Some(channel_id);
         let join = self._join_debouncer.spawn(cx, move |cx| async move {
+            if let Some(task) = leave {
+                task.await?
+            }
             Room::join_channel(channel_id, client, user_store, cx).await
         });
 
         cx.spawn(|this, mut cx| async move {
             let room = join.await?;
-            this.update(&mut cx, |this, cx| this.set_room(room.clone(), cx))?
-                .await?;
+            this.update(&mut cx, |this, cx| {
+                this.pending_channel_id.take();
+                this.set_room(room.clone(), cx)
+            })?
+            .await?;
             this.update(&mut cx, |this, cx| {
                 this.report_call_event("join channel", cx)
             })?;

crates/collab_ui/src/collab_panel.rs 🔗

@@ -504,6 +504,20 @@ impl CollabPanel {
                         role: proto::ChannelRole::Member,
                     }));
             }
+        } else if let Some(channel_id) = ActiveCall::global(cx).read(cx).pending_channel_id() {
+            self.entries.push(ListEntry::Header(Section::ActiveCall));
+            if !old_entries
+                .iter()
+                .any(|entry| matches!(entry, ListEntry::Header(Section::ActiveCall)))
+            {
+                scroll_to_top = true;
+            }
+
+            if query.is_empty() {
+                self.entries.push(ListEntry::ChannelCall { channel_id });
+                self.entries.push(ListEntry::ChannelNotes { channel_id });
+                self.entries.push(ListEntry::ChannelChat { channel_id });
+            }
         }
 
         let mut request_entries = Vec::new();
@@ -2195,7 +2209,10 @@ impl CollabPanel {
         let text = match section {
             Section::ActiveCall => {
                 let channel_name = maybe!({
-                    let channel_id = ActiveCall::global(cx).read(cx).channel_id(cx)?;
+                    let channel_id = ActiveCall::global(cx)
+                        .read(cx)
+                        .channel_id(cx)
+                        .or_else(|| ActiveCall::global(cx).read(cx).pending_channel_id())?;
 
                     let channel = self.channel_store.read(cx).channel_for_id(channel_id)?;