Detailed changes
@@ -39,6 +39,7 @@ pub struct LocalParticipant {
#[derive(Clone, Debug)]
pub struct RemoteParticipant {
pub user: Arc<User>,
+ pub peer_id: proto::PeerId,
pub projects: Vec<proto::ParticipantProject>,
pub location: ParticipantLocation,
pub tracks: HashMap<live_kit_client::Sid, Arc<RemoteVideoTrack>>,
@@ -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<LiveKitRoom>,
status: RoomStatus,
local_participant: LocalParticipant,
- remote_participants: BTreeMap<proto::PeerId, RemoteParticipant>,
+ remote_participants: BTreeMap<u64, RemoteParticipant>,
pending_participants: Vec<Arc<User>>,
participant_user_ids: HashSet<u64>,
pending_call_count: usize,
@@ -349,10 +352,16 @@ impl Room {
&self.local_participant
}
- pub fn remote_participants(&self) -> &BTreeMap<proto::PeerId, RemoteParticipant> {
+ pub fn remote_participants(&self) -> &BTreeMap<u64, RemoteParticipant> {
&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<User>] {
&self.pending_participants
}
@@ -417,15 +426,13 @@ impl Room {
}
if let Some(participants) = remote_participants.log_err() {
- let mut participant_peer_ids = HashSet::default();
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);
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,9 +461,11 @@ 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;
+ remote_participant.peer_id = peer_id;
if location != remote_participant.location {
remote_participant.location = location;
cx.emit(Event::ParticipantLocationChanged {
@@ -465,9 +474,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 +498,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 this.participant_user_ids.contains(user_id) {
true
} else {
for project in &participant.projects {
@@ -531,11 +541,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 +554,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,
});
}
}
@@ -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
@@ -492,7 +492,7 @@ async fn test_client_disconnecting_from_room(
// to automatically leave the room.
server
.test_live_kit_server
- .disconnect_client(client_b.peer_id().unwrap().to_string())
+ .disconnect_client(client_b.user_id().unwrap().to_string())
.await;
deterministic.run_until_parked();
active_call_a.update(cx_a, |call, _| assert!(call.room().is_none()));
@@ -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();
@@ -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::<Vec<_>>();
- 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,
@@ -73,7 +73,7 @@ pub fn init(app_state: Arc<AppState>, 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
@@ -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,
});
}
@@ -6,7 +6,6 @@ use prost::Message as _;
use serde::Serialize;
use std::any::{Any, TypeId};
use std::fmt;
-use std::str::FromStr;
use std::{
cmp,
fmt::Debug,
@@ -119,23 +118,6 @@ impl fmt::Display for PeerId {
}
}
-impl FromStr for PeerId {
- type Err = anyhow::Error;
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- let mut components = s.split('/');
- let owner_id = components
- .next()
- .ok_or_else(|| anyhow!("invalid peer id {:?}", s))?
- .parse()?;
- let id = components
- .next()
- .ok_or_else(|| anyhow!("invalid peer id {:?}", s))?
- .parse()?;
- Ok(PeerId { owner_id, id })
- }
-}
-
messages!(
(Ack, Foreground),
(AddProjectCollaborator, Foreground),
@@ -6,4 +6,4 @@ pub use conn::Connection;
pub use peer::*;
mod macros;
-pub const PROTOCOL_VERSION: u32 = 42;
+pub const PROTOCOL_VERSION: u32 = 43;
@@ -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))
});
@@ -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<ViewHandle<SharedScreen>> {
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();