More small following-related fixes (#3110)

Max Brunsfeld created

Change summary

crates/call/src/room.rs           | 33 ++++++++++++++++++---------------
crates/client/src/client.rs       | 18 +++++++++++++++++-
crates/workspace/src/workspace.rs | 15 +++++++++------
3 files changed, 44 insertions(+), 22 deletions(-)

Detailed changes

crates/call/src/room.rs 🔗

@@ -600,27 +600,30 @@ impl Room {
 
     /// Returns the most 'active' projects, defined as most people in the project
     pub fn most_active_project(&self) -> Option<(u64, u64)> {
-        let mut projects = HashMap::default();
-        let mut hosts = HashMap::default();
+        let mut project_hosts_and_guest_counts = HashMap::<u64, (Option<u64>, u32)>::default();
         for participant in self.remote_participants.values() {
             match participant.location {
                 ParticipantLocation::SharedProject { project_id } => {
-                    *projects.entry(project_id).or_insert(0) += 1;
+                    project_hosts_and_guest_counts
+                        .entry(project_id)
+                        .or_default()
+                        .1 += 1;
                 }
                 ParticipantLocation::External | ParticipantLocation::UnsharedProject => {}
             }
             for project in &participant.projects {
-                *projects.entry(project.id).or_insert(0) += 1;
-                hosts.insert(project.id, participant.user.id);
+                project_hosts_and_guest_counts
+                    .entry(project.id)
+                    .or_default()
+                    .0 = Some(participant.user.id);
             }
         }
 
-        let mut pairs: Vec<(u64, usize)> = projects.into_iter().collect();
-        pairs.sort_by_key(|(_, count)| *count as i32);
-
-        pairs
-            .first()
-            .map(|(project_id, _)| (*project_id, hosts[&project_id]))
+        project_hosts_and_guest_counts
+            .into_iter()
+            .filter_map(|(id, (host, guest_count))| Some((id, host?, guest_count)))
+            .max_by_key(|(_, _, guest_count)| *guest_count)
+            .map(|(id, host, _)| (id, host))
     }
 
     async fn handle_room_updated(
@@ -686,6 +689,7 @@ impl Room {
                         let Some(peer_id) = participant.peer_id else {
                             continue;
                         };
+                        let participant_index = ParticipantIndex(participant.participant_index);
                         this.participant_user_ids.insert(participant.user_id);
 
                         let old_projects = this
@@ -736,8 +740,9 @@ impl Room {
                         if let Some(remote_participant) =
                             this.remote_participants.get_mut(&participant.user_id)
                         {
-                            remote_participant.projects = participant.projects;
                             remote_participant.peer_id = peer_id;
+                            remote_participant.projects = participant.projects;
+                            remote_participant.participant_index = participant_index;
                             if location != remote_participant.location {
                                 remote_participant.location = location;
                                 cx.emit(Event::ParticipantLocationChanged {
@@ -749,9 +754,7 @@ impl Room {
                                 participant.user_id,
                                 RemoteParticipant {
                                     user: user.clone(),
-                                    participant_index: ParticipantIndex(
-                                        participant.participant_index,
-                                    ),
+                                    participant_index,
                                     peer_id,
                                     projects: participant.projects,
                                     location,

crates/client/src/client.rs 🔗

@@ -70,7 +70,7 @@ pub const ZED_SECRET_CLIENT_TOKEN: &str = "618033988749894";
 pub const INITIAL_RECONNECTION_DELAY: Duration = Duration::from_millis(100);
 pub const CONNECTION_TIMEOUT: Duration = Duration::from_secs(5);
 
-actions!(client, [SignIn, SignOut]);
+actions!(client, [SignIn, SignOut, Reconnect]);
 
 pub fn init_settings(cx: &mut AppContext) {
     settings::register::<TelemetrySettings>(cx);
@@ -102,6 +102,17 @@ pub fn init(client: &Arc<Client>, cx: &mut AppContext) {
             }
         }
     });
+    cx.add_global_action({
+        let client = client.clone();
+        move |_: &Reconnect, cx| {
+            if let Some(client) = client.upgrade() {
+                cx.spawn(|cx| async move {
+                    client.reconnect(&cx);
+                })
+                .detach();
+            }
+        }
+    });
 }
 
 pub struct Client {
@@ -1212,6 +1223,11 @@ impl Client {
         self.set_status(Status::SignedOut, cx);
     }
 
+    pub fn reconnect(self: &Arc<Self>, cx: &AsyncAppContext) {
+        self.peer.teardown();
+        self.set_status(Status::ConnectionLost, cx);
+    }
+
     fn connection_id(&self) -> Result<ConnectionId> {
         if let Status::Connected { connection_id, .. } = *self.status().borrow() {
             Ok(connection_id)

crates/workspace/src/workspace.rs 🔗

@@ -3105,16 +3105,19 @@ impl Workspace {
             if state.leader_id != leader_id {
                 continue;
             }
-            if leader_in_this_app {
-                let item = state
-                    .active_view_id
-                    .and_then(|id| state.items_by_leader_view_id.get(&id));
-                if let Some(item) = item {
+            if let (Some(active_view_id), true) = (state.active_view_id, leader_in_this_app) {
+                if let Some(item) = state.items_by_leader_view_id.get(&active_view_id) {
                     if leader_in_this_project || !item.is_project_item(cx) {
                         items_to_activate.push((pane.clone(), item.boxed_clone()));
                     }
-                    continue;
+                } else {
+                    log::warn!(
+                        "unknown view id {:?} for leader {:?}",
+                        active_view_id,
+                        leader_id
+                    );
                 }
+                continue;
             }
             if let Some(shared_screen) = self.shared_screen_for_peer(leader_id, pane, cx) {
                 items_to_activate.push((pane.clone(), Box::new(shared_screen)));