diff --git a/crates/call/src/participant.rs b/crates/call/src/participant.rs index d5c6d85154..4b9e7ba034 100644 --- a/crates/call/src/participant.rs +++ b/crates/call/src/participant.rs @@ -39,6 +39,7 @@ pub struct LocalParticipant { #[derive(Clone, Debug)] pub struct RemoteParticipant { pub user: Arc, + pub peer_id: proto::PeerId, pub projects: Vec, pub location: ParticipantLocation, pub tracks: HashMap>, diff --git a/crates/call/src/room.rs b/crates/call/src/room.rs index 1d22fe50f1..f2d40b0129 100644 --- a/crates/call/src/room.rs +++ b/crates/call/src/room.rs @@ -3,7 +3,10 @@ use crate::{ IncomingCall, }; use anyhow::{anyhow, Result}; -use client::{proto, Client, TypedEnvelope, User, UserStore}; +use client::{ + proto::{self, PeerId}, + Client, TypedEnvelope, User, UserStore, +}; use collections::{BTreeMap, HashSet}; use futures::{FutureExt, StreamExt}; use gpui::{ @@ -41,7 +44,7 @@ pub struct Room { live_kit: Option, status: RoomStatus, local_participant: LocalParticipant, - remote_participants: BTreeMap, + remote_participants: BTreeMap, pending_participants: Vec>, participant_user_ids: HashSet, pending_call_count: usize, @@ -349,10 +352,16 @@ impl Room { &self.local_participant } - pub fn remote_participants(&self) -> &BTreeMap { + pub fn remote_participants(&self) -> &BTreeMap { &self.remote_participants } + pub fn remote_participant_for_peer_id(&self, peer_id: PeerId) -> Option<&RemoteParticipant> { + self.remote_participants + .values() + .find(|p| p.peer_id == peer_id) + } + pub fn pending_participants(&self) -> &[Arc] { &self.pending_participants } @@ -421,11 +430,11 @@ impl Room { for (participant, user) in room.participants.into_iter().zip(participants) { let Some(peer_id) = participant.peer_id else { continue }; this.participant_user_ids.insert(participant.user_id); - participant_peer_ids.insert(peer_id); + participant_peer_ids.insert(participant.user_id); let old_projects = this .remote_participants - .get(&peer_id) + .get(&participant.user_id) .into_iter() .flat_map(|existing| &existing.projects) .map(|project| project.id) @@ -454,7 +463,8 @@ impl Room { let location = ParticipantLocation::from_proto(participant.location) .unwrap_or(ParticipantLocation::External); - if let Some(remote_participant) = this.remote_participants.get_mut(&peer_id) + if let Some(remote_participant) = + this.remote_participants.get_mut(&participant.user_id) { remote_participant.projects = participant.projects; if location != remote_participant.location { @@ -465,9 +475,10 @@ impl Room { } } else { this.remote_participants.insert( - peer_id, + participant.user_id, RemoteParticipant { user: user.clone(), + peer_id, projects: participant.projects, location, tracks: Default::default(), @@ -488,8 +499,8 @@ impl Room { } } - this.remote_participants.retain(|peer_id, participant| { - if participant_peer_ids.contains(peer_id) { + this.remote_participants.retain(|user_id, participant| { + if participant_peer_ids.contains(user_id) { true } else { for project in &participant.projects { @@ -531,11 +542,11 @@ impl Room { ) -> Result<()> { match change { RemoteVideoTrackUpdate::Subscribed(track) => { - let peer_id = track.publisher_id().parse()?; + let user_id = track.publisher_id().parse()?; let track_id = track.sid().to_string(); let participant = self .remote_participants - .get_mut(&peer_id) + .get_mut(&user_id) .ok_or_else(|| anyhow!("subscribed to track by unknown participant"))?; participant.tracks.insert( track_id.clone(), @@ -544,21 +555,21 @@ impl Room { }), ); cx.emit(Event::RemoteVideoTracksChanged { - participant_id: peer_id, + participant_id: participant.peer_id, }); } RemoteVideoTrackUpdate::Unsubscribed { publisher_id, track_id, } => { - let peer_id = publisher_id.parse()?; + let user_id = publisher_id.parse()?; let participant = self .remote_participants - .get_mut(&peer_id) + .get_mut(&user_id) .ok_or_else(|| anyhow!("unsubscribed from track by unknown participant"))?; participant.tracks.remove(&track_id); cx.emit(Event::RemoteVideoTracksChanged { - participant_id: peer_id, + participant_id: participant.peer_id, }); } } diff --git a/crates/collab/src/integration_tests.rs b/crates/collab/src/integration_tests.rs index 2629d340da..6c773503bb 100644 --- a/crates/collab/src/integration_tests.rs +++ b/crates/collab/src/integration_tests.rs @@ -199,7 +199,7 @@ async fn test_basic_calls( assert_eq!(participant_id, client_a.peer_id().unwrap()); room_b.read_with(cx_b, |room, _| { assert_eq!( - room.remote_participants()[&client_a.peer_id().unwrap()] + room.remote_participants()[&client_a.user_id().unwrap()] .tracks .len(), 1 diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 6a8ae61ed0..03e6eb50e2 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -850,7 +850,7 @@ async fn create_room( .trace_err() { if let Some(token) = live_kit - .room_token(&live_kit_room, &session.connection_id.to_string()) + .room_token(&live_kit_room, &session.user_id.to_string()) .trace_err() { Some(proto::LiveKitConnectionInfo { @@ -918,7 +918,7 @@ async fn join_room( let live_kit_connection_info = if let Some(live_kit) = session.live_kit_client.as_ref() { if let Some(token) = live_kit - .room_token(&room.live_kit_room, &session.connection_id.to_string()) + .room_token(&room.live_kit_room, &session.user_id.to_string()) .trace_err() { Some(proto::LiveKitConnectionInfo { @@ -2066,7 +2066,7 @@ async fn leave_room_for_session(session: &Session) -> Result<()> { if let Some(live_kit) = session.live_kit_client.as_ref() { live_kit - .remove_participant(live_kit_room.clone(), session.connection_id.to_string()) + .remove_participant(live_kit_room.clone(), session.user_id.to_string()) .await .trace_err(); diff --git a/crates/collab_ui/src/collab_titlebar_item.rs b/crates/collab_ui/src/collab_titlebar_item.rs index 2288f77cd3..3351fb9eb9 100644 --- a/crates/collab_ui/src/collab_titlebar_item.rs +++ b/crates/collab_ui/src/collab_titlebar_item.rs @@ -342,24 +342,27 @@ impl CollabTitlebarItem { let mut participants = room .read(cx) .remote_participants() - .iter() - .map(|(peer_id, collaborator)| (*peer_id, collaborator.clone())) + .values() + .cloned() .collect::>(); - participants - .sort_by_key(|(peer_id, _)| Some(project.collaborators().get(peer_id)?.replica_id)); + participants.sort_by_key(|p| Some(project.collaborators().get(&p.peer_id)?.replica_id)); participants .into_iter() - .filter_map(|(peer_id, participant)| { + .filter_map(|participant| { let project = workspace.read(cx).project().read(cx); let replica_id = project .collaborators() - .get(&peer_id) + .get(&participant.peer_id) .map(|collaborator| collaborator.replica_id); let user = participant.user.clone(); Some(self.render_avatar( &user, replica_id, - Some((peer_id, &user.github_login, participant.location)), + Some(( + participant.peer_id, + &user.github_login, + participant.location, + )), workspace, theme, cx, diff --git a/crates/collab_ui/src/collab_ui.rs b/crates/collab_ui/src/collab_ui.rs index 1b851c3f75..1041382515 100644 --- a/crates/collab_ui/src/collab_ui.rs +++ b/crates/collab_ui/src/collab_ui.rs @@ -73,7 +73,7 @@ pub fn init(app_state: Arc, cx: &mut MutableAppContext) { .remote_participants() .iter() .find(|(_, participant)| participant.user.id == follow_user_id) - .map(|(peer_id, _)| *peer_id) + .map(|(_, p)| p.peer_id) .or_else(|| { // If we couldn't follow the given user, follow the host instead. let collaborator = workspace diff --git a/crates/collab_ui/src/contact_list.rs b/crates/collab_ui/src/contact_list.rs index 48a4d1a2b5..ba6b236a82 100644 --- a/crates/collab_ui/src/contact_list.rs +++ b/crates/collab_ui/src/contact_list.rs @@ -461,15 +461,13 @@ impl ContactList { // Populate remote participants. self.match_candidates.clear(); self.match_candidates - .extend( - room.remote_participants() - .iter() - .map(|(peer_id, participant)| StringMatchCandidate { - id: peer_id.as_u64() as usize, - string: participant.user.github_login.clone(), - char_bag: participant.user.github_login.chars().collect(), - }), - ); + .extend(room.remote_participants().iter().map(|(_, participant)| { + StringMatchCandidate { + id: participant.user.id as usize, + string: participant.user.github_login.clone(), + char_bag: participant.user.github_login.chars().collect(), + } + })); let matches = executor.block(match_strings( &self.match_candidates, &query, @@ -479,8 +477,8 @@ impl ContactList { executor.clone(), )); for mat in matches { - let peer_id = PeerId::from_u64(mat.candidate_id as u64); - let participant = &room.remote_participants()[&peer_id]; + let user_id = mat.candidate_id as u64; + let participant = &room.remote_participants()[&user_id]; participant_entries.push(ContactEntry::CallParticipant { user: participant.user.clone(), is_pending: false, @@ -496,7 +494,7 @@ impl ContactList { } if !participant.tracks.is_empty() { participant_entries.push(ContactEntry::ParticipantScreen { - peer_id, + peer_id: participant.peer_id, is_last: true, }); } diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index b8e73d6f6f..72e4baee2e 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -148,7 +148,7 @@ impl Member { .and_then(|leader_id| { let room = active_call?.read(cx).room()?.read(cx); let collaborator = project.read(cx).collaborators().get(leader_id)?; - let participant = room.remote_participants().get(&leader_id)?; + let participant = room.remote_participant_for_peer_id(*leader_id)?; Some((collaborator.replica_id, participant)) }); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index c30dc2ea29..287bbc2b13 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -2141,7 +2141,7 @@ impl Workspace { let call = self.active_call()?; let room = call.read(cx).room()?.read(cx); - let participant = room.remote_participants().get(&leader_id)?; + let participant = room.remote_participant_for_peer_id(leader_id)?; let mut items_to_add = Vec::new(); match participant.location { @@ -2190,7 +2190,7 @@ impl Workspace { ) -> Option> { let call = self.active_call()?; let room = call.read(cx).room()?.read(cx); - let participant = room.remote_participants().get(&peer_id)?; + let participant = room.remote_participant_for_peer_id(peer_id)?; let track = participant.tracks.values().next()?.clone(); let user = participant.user.clone();