client: Rename `UserId` to `LegacyUserId` (#56185)

Marshall Bowers created

This PR renames the `UserId` type in the `client` crate to
`LegacyUserId`.

The `id` field on the `User` has also been renamed to `legacy_id`.

This is strictly a rename, no change in behavior.

Release Notes:

- N/A

Change summary

crates/call/src/call_impl/mod.rs                                      |  2 
crates/call/src/call_impl/room.rs                                     | 19 
crates/channel/src/channel_store.rs                                   | 14 
crates/client/src/user.rs                                             | 28 
crates/collab/tests/integration/channel_buffer_tests.rs               |  7 
crates/collab/tests/integration/channel_tests.rs                      |  8 
crates/collab/tests/integration/integration_tests.rs                  |  4 
crates/collab/tests/integration/random_project_collaboration_tests.rs |  4 
crates/collab/tests/integration/test_server.rs                        |  8 
crates/collab_ui/src/collab_panel.rs                                  | 42 
crates/collab_ui/src/collab_panel/channel_modal.rs                    | 52 
crates/collab_ui/src/collab_panel/contact_finder.rs                   |  4 
crates/collab_ui/src/notifications/incoming_call_notification.rs      |  2 
crates/collab_ui/src/notifications/project_shared_notification.rs     |  2 
crates/title_bar/src/collab.rs                                        |  4 
crates/title_bar/src/title_bar.rs                                     |  2 
crates/workspace/src/pane_group.rs                                    |  2 
crates/workspace/src/workspace.rs                                     | 16 
18 files changed, 131 insertions(+), 89 deletions(-)

Detailed changes

crates/call/src/call_impl/mod.rs 🔗

@@ -189,7 +189,7 @@ impl AnyActiveCall for ActiveCallEntity {
         let room = self.0.read(cx).room()?.read(cx);
         room.remote_participants()
             .values()
-            .find(|p| p.user.id == user_id)
+            .find(|p| p.user.legacy_id == user_id)
             .map(|p| p.peer_id)
     }
 

crates/call/src/call_impl/room.rs 🔗

@@ -680,7 +680,7 @@ impl Room {
                 project_hosts_and_guest_counts
                     .entry(project.id)
                     .or_default()
-                    .0 = Some(participant.user.id);
+                    .0 = Some(participant.user.legacy_id);
             }
         }
 
@@ -689,7 +689,7 @@ impl Room {
                 project_hosts_and_guest_counts
                     .entry(project.id)
                     .or_default()
-                    .0 = Some(user.id);
+                    .0 = Some(user.legacy_id);
             }
         }
 
@@ -902,7 +902,7 @@ impl Room {
 
                             if let Some(livekit_participants) = &livekit_participants
                                 && let Some(livekit_participant) = livekit_participants
-                                    .get(&ParticipantIdentity(user.id.to_string()))
+                                    .get(&ParticipantIdentity(user.legacy_id.to_string()))
                             {
                                 for publication in
                                     livekit_participant.track_publications().into_values()
@@ -948,7 +948,7 @@ impl Room {
                 if let Some(pending_participants) = pending_participants.log_err() {
                     this.pending_participants = pending_participants;
                     for participant in &this.pending_participants {
-                        this.participant_user_ids.insert(participant.id);
+                        this.participant_user_ids.insert(participant.legacy_id);
                     }
                 }
 
@@ -1153,13 +1153,16 @@ impl Room {
         #[cfg(any(test, feature = "test-support"))]
         {
             for participant in self.remote_participants.values() {
-                assert!(self.participant_user_ids.contains(&participant.user.id));
-                assert_ne!(participant.user.id, self.client.user_id().unwrap());
+                assert!(
+                    self.participant_user_ids
+                        .contains(&participant.user.legacy_id)
+                );
+                assert_ne!(participant.user.legacy_id, self.client.user_id().unwrap());
             }
 
             for participant in &self.pending_participants {
-                assert!(self.participant_user_ids.contains(&participant.id));
-                assert_ne!(participant.id, self.client.user_id().unwrap());
+                assert!(self.participant_user_ids.contains(&participant.legacy_id));
+                assert_ne!(participant.legacy_id, self.client.user_id().unwrap());
             }
 
             assert_eq!(

crates/channel/src/channel_store.rs 🔗

@@ -3,7 +3,7 @@ mod channel_index;
 use crate::channel_buffer::ChannelBuffer;
 use anyhow::{Context as _, Result, anyhow};
 use channel_index::ChannelIndex;
-use client::{ChannelId, Client, ClientSettings, Subscription, User, UserId, UserStore};
+use client::{ChannelId, Client, ClientSettings, LegacyUserId, Subscription, User, UserStore};
 use collections::{HashMap, HashSet};
 use futures::{Future, FutureExt, StreamExt, channel::mpsc, future::Shared};
 use gpui::{
@@ -39,7 +39,7 @@ pub struct ChannelStore {
     channel_participants: HashMap<ChannelId, Vec<Arc<User>>>,
     channel_states: HashMap<ChannelId, ChannelState>,
     favorite_channel_ids: Vec<ChannelId>,
-    outgoing_invites: HashSet<(ChannelId, UserId)>,
+    outgoing_invites: HashSet<(ChannelId, LegacyUserId)>,
     update_channels_tx: mpsc::UnboundedSender<proto::UpdateChannels>,
     opened_buffers: HashMap<ChannelId, OpenEntityHandle<ChannelBuffer>>,
     client: Arc<Client>,
@@ -632,7 +632,7 @@ impl ChannelStore {
     pub fn invite_member(
         &mut self,
         channel_id: ChannelId,
-        user_id: UserId,
+        user_id: LegacyUserId,
         role: proto::ChannelRole,
         cx: &mut Context<Self>,
     ) -> Task<Result<()>> {
@@ -694,7 +694,7 @@ impl ChannelStore {
     pub fn set_member_role(
         &mut self,
         channel_id: ChannelId,
-        user_id: UserId,
+        user_id: LegacyUserId,
         role: proto::ChannelRole,
         cx: &mut Context<Self>,
     ) -> Task<Result<()>> {
@@ -830,7 +830,7 @@ impl ChannelStore {
         false
     }
 
-    pub fn has_pending_channel_invite(&self, channel_id: ChannelId, user_id: UserId) -> bool {
+    pub fn has_pending_channel_invite(&self, channel_id: ChannelId, user_id: LegacyUserId) -> bool {
         self.outgoing_invites.contains(&(channel_id, user_id))
     }
 
@@ -1167,13 +1167,13 @@ impl ChannelStore {
                         .iter()
                         .filter_map(|user_id| {
                             users
-                                .binary_search_by_key(&user_id, |user| &user.id)
+                                .binary_search_by_key(&user_id, |user| &user.legacy_id)
                                 .ok()
                                 .map(|ix| users[ix].clone())
                         })
                         .collect();
 
-                    participants.sort_by_key(|u| u.id);
+                    participants.sort_by_key(|u| u.legacy_id);
 
                     this.channel_participants
                         .insert(ChannelId(entry.channel_id), participants);

crates/client/src/user.rs 🔗

@@ -30,7 +30,7 @@ use util::{ResultExt, TryFutureExt as _};
 
 const CURRENT_ORGANIZATION_ID_KEY: &str = "current_organization_id";
 
-pub type UserId = u64;
+pub type LegacyUserId = u64;
 
 #[derive(
     Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, serde::Serialize, serde::Deserialize,
@@ -57,7 +57,7 @@ pub struct ParticipantIndex(pub u32);
 
 #[derive(Default, Debug)]
 pub struct User {
-    pub id: UserId,
+    pub legacy_id: LegacyUserId,
     pub github_login: SharedString,
     pub avatar_uri: SharedUri,
     pub name: Option<String>,
@@ -67,7 +67,7 @@ pub struct User {
 pub struct Collaborator {
     pub peer_id: proto::PeerId,
     pub replica_id: ReplicaId,
-    pub user_id: UserId,
+    pub user_id: LegacyUserId,
     pub is_host: bool,
     pub committer_name: Option<String>,
     pub committer_email: Option<String>,
@@ -87,7 +87,7 @@ impl Ord for User {
 
 impl PartialEq for User {
     fn eq(&self, other: &Self) -> bool {
-        self.id == other.id && self.github_login == other.github_login
+        self.legacy_id == other.legacy_id && self.github_login == other.github_login
     }
 }
 
@@ -240,7 +240,7 @@ impl UserStore {
 
                                 let current_user_and_response = if let Some(response) = response {
                                     let user = Arc::new(User {
-                                        id: user_id,
+                                        legacy_id: user_id,
                                         github_login: response.user.github_login.clone().into(),
                                         avatar_uri: response.user.avatar_url.clone().into(),
                                         name: response.user.name.clone(),
@@ -404,7 +404,7 @@ impl UserStore {
                     this.update(cx, |this, cx| {
                         // Remove contacts
                         this.contacts
-                            .retain(|contact| !removed_contacts.contains(&contact.user.id));
+                            .retain(|contact| !removed_contacts.contains(&contact.user.legacy_id));
                         // Update existing contacts and insert new ones
                         for updated_contact in updated_contacts {
                             match this.contacts.binary_search_by_key(
@@ -418,7 +418,7 @@ impl UserStore {
 
                         // Remove incoming contact requests
                         this.incoming_contact_requests.retain(|user| {
-                            if removed_incoming_requests.contains(&user.id) {
+                            if removed_incoming_requests.contains(&user.legacy_id) {
                                 cx.emit(Event::Contact {
                                     user: user.clone(),
                                     kind: ContactEventKind::Cancelled,
@@ -442,7 +442,7 @@ impl UserStore {
 
                         // Remove outgoing contact requests
                         this.outgoing_contact_requests
-                            .retain(|user| !removed_outgoing_requests.contains(&user.id));
+                            .retain(|user| !removed_outgoing_requests.contains(&user.legacy_id));
                         // Update existing incoming requests and insert new ones
                         for request in outgoing_requests {
                             match this
@@ -483,7 +483,7 @@ impl UserStore {
     }
 
     pub fn is_contact_request_pending(&self, user: &User) -> bool {
-        self.pending_contact_requests.contains_key(&user.id)
+        self.pending_contact_requests.contains_key(&user.legacy_id)
     }
 
     pub fn contact_request_status(&self, user: &User) -> ContactRequestStatus {
@@ -525,7 +525,7 @@ impl UserStore {
     pub fn has_incoming_contact_request(&self, user_id: u64) -> bool {
         self.incoming_contact_requests
             .iter()
-            .any(|user| user.id == user_id)
+            .any(|user| user.legacy_id == user_id)
     }
 
     pub fn respond_to_contact_request(
@@ -967,13 +967,13 @@ impl UserStore {
         let mut ret = Vec::with_capacity(users.len());
         for user in users {
             let user = User::new(user);
-            if let Some(old) = self.users.insert(user.id, user.clone())
+            if let Some(old) = self.users.insert(user.legacy_id, user.clone())
                 && old.github_login != user.github_login
             {
                 self.by_github_login.remove(&old.github_login);
             }
             self.by_github_login
-                .insert(user.github_login.clone(), user.id);
+                .insert(user.github_login.clone(), user.legacy_id);
             ret.push(user)
         }
         ret
@@ -1023,7 +1023,7 @@ impl UserStore {
 impl User {
     fn new(message: proto::User) -> Arc<Self> {
         Arc::new(User {
-            id: message.id,
+            legacy_id: message.id,
             github_login: message.github_login.into(),
             avatar_uri: message.avatar_url.into(),
             name: message.name,
@@ -1055,7 +1055,7 @@ impl Collaborator {
         Ok(Self {
             peer_id: message.peer_id.context("invalid peer id")?,
             replica_id: ReplicaId::new(message.replica_id as u16),
-            user_id: message.user_id as UserId,
+            user_id: message.user_id as LegacyUserId,
             is_host: message.is_host,
             committer_name: message.committer_name,
             committer_email: message.committer_email,

crates/collab/tests/integration/channel_buffer_tests.rs 🔗

@@ -1,7 +1,7 @@
 use crate::{TestServer, test_server::open_channel_notes};
 use call::ActiveCall;
 use channel::ACKNOWLEDGE_DEBOUNCE_INTERVAL;
-use client::{Collaborator, ParticipantIndex, UserId};
+use client::{Collaborator, LegacyUserId, ParticipantIndex};
 use collab::rpc::{CLEANUP_TIMEOUT, RECONNECT_TIMEOUT};
 
 use collab_ui::channel_view::ChannelView;
@@ -864,7 +864,10 @@ async fn test_channel_buffer_operations_lost_on_reconnect(
 }
 
 #[track_caller]
-fn assert_collaborators(collaborators: &HashMap<PeerId, Collaborator>, ids: &[Option<UserId>]) {
+fn assert_collaborators(
+    collaborators: &HashMap<PeerId, Collaborator>,
+    ids: &[Option<LegacyUserId>],
+) {
     let mut user_ids = collaborators
         .values()
         .map(|collaborator| collaborator.user_id)

crates/collab/tests/integration/channel_tests.rs 🔗

@@ -314,7 +314,7 @@ async fn test_core_channels(
 #[track_caller]
 fn assert_participants_eq(participants: &[Arc<User>], expected_partitipants: &[u64]) {
     assert_eq!(
-        participants.iter().map(|p| p.id).collect::<Vec<_>>(),
+        participants.iter().map(|p| p.legacy_id).collect::<Vec<_>>(),
         expected_partitipants
     );
 }
@@ -327,7 +327,7 @@ fn assert_members_eq(
     assert_eq!(
         members
             .iter()
-            .map(|member| (member.user.id, member.role, member.kind))
+            .map(|member| (member.user.legacy_id, member.role, member.kind))
             .collect::<Vec<_>>(),
         expected_members
     );
@@ -1259,7 +1259,7 @@ async fn test_guest_access(
     client_a.channel_store().update(cx_a, |channel_store, _| {
         let participants = channel_store.channel_participants(channel_a);
         assert_eq!(participants.len(), 1);
-        assert_eq!(participants[0].id, client_b.user_id().unwrap());
+        assert_eq!(participants[0].legacy_id, client_b.user_id().unwrap());
     });
 }
 
@@ -1320,7 +1320,7 @@ async fn test_invite_access(
     client_a.channel_store().update(cx_a, |channel_store, _| {
         let participants = channel_store.channel_participants(channel_b_id);
         assert_eq!(participants.len(), 1);
-        assert_eq!(participants[0].id, client_b.user_id().unwrap());
+        assert_eq!(participants[0].legacy_id, client_b.user_id().unwrap());
     })
 }
 

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

@@ -1872,7 +1872,7 @@ async fn test_active_call_events(
         mem::take(&mut *events_b.borrow_mut()),
         vec![room::Event::RemoteProjectShared {
             owner: Arc::new(User {
-                id: client_a.user_id().unwrap(),
+                legacy_id: client_a.user_id().unwrap(),
                 github_login: "user_a".into(),
                 avatar_uri: "avatar_a".into(),
                 name: None,
@@ -1891,7 +1891,7 @@ async fn test_active_call_events(
         mem::take(&mut *events_a.borrow_mut()),
         vec![room::Event::RemoteProjectShared {
             owner: Arc::new(User {
-                id: client_b.user_id().unwrap(),
+                legacy_id: client_b.user_id().unwrap(),
                 github_login: "user_b".into(),
                 avatar_uri: "avatar_b".into(),
                 name: None,

crates/collab/tests/integration/random_project_collaboration_tests.rs 🔗

@@ -196,7 +196,7 @@ impl RandomizedTest for ProjectCollaborationTest {
                             if !available_contacts.is_empty() {
                                 let contact = available_contacts.choose(rng).unwrap();
                                 break ClientOperation::InviteContactToCall {
-                                    user_id: UserId(contact.user.id as i32),
+                                    user_id: UserId(contact.user.legacy_id as i32),
                                 };
                             }
                         }
@@ -235,7 +235,7 @@ impl RandomizedTest for ProjectCollaborationTest {
                                                 None
                                             } else {
                                                 Some((
-                                                    UserId::from_proto(participant.user.id),
+                                                    UserId::from_proto(participant.user.legacy_id),
                                                     project.worktree_root_names[0].clone(),
                                                 ))
                                             }

crates/collab/tests/integration/test_server.rs 🔗

@@ -658,11 +658,9 @@ impl TestClient {
     }
 
     pub fn current_user_id(&self, cx: &TestAppContext) -> UserId {
-        UserId::from_proto(
-            self.app_state
-                .user_store
-                .read_with(cx, |user_store, _| user_store.current_user().unwrap().id),
-        )
+        UserId::from_proto(self.app_state.user_store.read_with(cx, |user_store, _| {
+            user_store.current_user().unwrap().legacy_id
+        }))
     }
 
     pub async fn wait_for_current_user(&self, cx: &TestAppContext) {

crates/collab_ui/src/collab_panel.rs 🔗

@@ -618,7 +618,7 @@ impl CollabPanel {
                         executor.clone(),
                     ));
                     if !matches.is_empty() {
-                        let user_id = user.id;
+                        let user_id = user.legacy_id;
                         self.entries.push(ListEntry::CallParticipant {
                             user,
                             peer_id: None,
@@ -648,7 +648,7 @@ impl CollabPanel {
                 self.match_candidates
                     .extend(room.remote_participants().values().map(|participant| {
                         StringMatchCandidate::new(
-                            participant.user.id as usize,
+                            participant.user.legacy_id as usize,
                             &participant.user.github_login,
                         )
                     }));
@@ -684,7 +684,7 @@ impl CollabPanel {
                         self.entries.push(ListEntry::ParticipantProject {
                             project_id: project.id,
                             worktree_root_names: project.worktree_root_names.clone(),
-                            host_user_id: participant.user.id,
+                            host_user_id: participant.user.legacy_id,
                             is_last: projects.peek().is_none() && !participant.has_video_tracks(),
                         });
                     }
@@ -1024,7 +1024,9 @@ impl CollabPanel {
                             let contact = &contacts[mat.candidate_id];
                             self.entries.push(ListEntry::Contact {
                                 contact: contact.clone(),
-                                calling: active_call.pending_invites().contains(&contact.user.id),
+                                calling: active_call
+                                    .pending_invites()
+                                    .contains(&contact.user.legacy_id),
                             });
                         }
                     }
@@ -1122,9 +1124,13 @@ impl CollabPanel {
         is_selected: bool,
         cx: &mut Context<Self>,
     ) -> ListItem {
-        let user_id = user.id;
-        let is_current_user =
-            self.user_store.read(cx).current_user().map(|user| user.id) == Some(user_id);
+        let user_id = user.legacy_id;
+        let is_current_user = self
+            .user_store
+            .read(cx)
+            .current_user()
+            .map(|user| user.legacy_id)
+            == Some(user_id);
         let tooltip = format!("Follow {}", user.github_login);
 
         let is_call_admin = ActiveCall::global(cx).read(cx).room().is_some_and(|room| {
@@ -1650,7 +1656,7 @@ impl CollabPanel {
         let in_room = ActiveCall::global(cx).read(cx).room().is_some();
 
         let context_menu = ContextMenu::build(window, cx, |mut context_menu, _, _| {
-            let user_id = contact.user.id;
+            let user_id = contact.user.legacy_id;
 
             if contact.online && !contact.busy {
                 let label = if in_room {
@@ -1673,7 +1679,7 @@ impl CollabPanel {
                 move |window, cx| {
                     this.update(cx, |this, cx| {
                         this.remove_contact(
-                            contact.user.id,
+                            contact.user.legacy_id,
                             &contact.user.github_login,
                             window,
                             cx,
@@ -1777,7 +1783,7 @@ impl CollabPanel {
                 },
                 ListEntry::Contact { contact, calling } => {
                     if contact.online && !contact.busy && !calling {
-                        self.call(contact.user.id, window, cx);
+                        self.call(contact.user.legacy_id, window, cx);
                     }
                 }
                 ListEntry::ParticipantProject {
@@ -1834,7 +1840,7 @@ impl CollabPanel {
                     }
                 }
                 ListEntry::IncomingRequest(user) => {
-                    self.respond_to_contact_request(user.id, true, window, cx)
+                    self.respond_to_contact_request(user.legacy_id, true, window, cx)
                 }
                 ListEntry::ChannelInvite(channel) => {
                     self.respond_to_channel_invite(channel.id, true, cx)
@@ -2450,7 +2456,7 @@ impl CollabPanel {
     }
 
     fn leave_channel(&self, channel_id: ChannelId, window: &mut Window, cx: &mut Context<Self>) {
-        let Some(user_id) = self.user_store.read(cx).current_user().map(|u| u.id) else {
+        let Some(user_id) = self.user_store.read(cx).current_user().map(|u| u.legacy_id) else {
             return;
         };
         let Some(channel) = self.channel_store.read(cx).channel_for_id(channel_id) else {
@@ -2705,7 +2711,7 @@ impl CollabPanel {
                     .into_any_element()
             }
             ListEntry::Contact { contact, calling } => {
-                self.mark_contact_request_accepted_notifications_read(contact.user.id, cx);
+                self.mark_contact_request_accepted_notifications_read(contact.user.legacy_id, cx);
                 self.render_contact(&contact, calling, is_selected, cx)
                     .into_any_element()
             }
@@ -3122,7 +3128,7 @@ impl CollabPanel {
         cx: &mut Context<Self>,
     ) -> impl IntoElement {
         let github_login = user.github_login.clone();
-        let user_id = user.id;
+        let user_id = user.legacy_id;
         let is_response_pending = self.user_store.read(cx).is_contact_request_pending(user);
         let color = if is_response_pending {
             Color::Muted
@@ -3854,7 +3860,7 @@ impl PartialEq for ListEntry {
             }
             ListEntry::CallParticipant { user: user_1, .. } => {
                 if let ListEntry::CallParticipant { user: user_2, .. } = other {
-                    return user_1.id == user_2.id;
+                    return user_1.legacy_id == user_2.legacy_id;
                 }
             }
             ListEntry::ParticipantProject {
@@ -3908,12 +3914,12 @@ impl PartialEq for ListEntry {
             }
             ListEntry::IncomingRequest(user_1) => {
                 if let ListEntry::IncomingRequest(user_2) = other {
-                    return user_1.id == user_2.id;
+                    return user_1.legacy_id == user_2.legacy_id;
                 }
             }
             ListEntry::OutgoingRequest(user_1) => {
                 if let ListEntry::OutgoingRequest(user_2) = other {
-                    return user_1.id == user_2.id;
+                    return user_1.legacy_id == user_2.legacy_id;
                 }
             }
             ListEntry::Contact {
@@ -3923,7 +3929,7 @@ impl PartialEq for ListEntry {
                     contact: contact_2, ..
                 } = other
                 {
-                    return contact_1.user.id == contact_2.user.id;
+                    return contact_1.user.legacy_id == contact_2.user.legacy_id;
                 }
             }
             ListEntry::ChannelEditor { depth } => {

crates/collab_ui/src/collab_panel/channel_modal.rs 🔗

@@ -1,6 +1,6 @@
 use channel::{ChannelMembership, ChannelStore};
 use client::{
-    ChannelId, User, UserId, UserStore,
+    ChannelId, LegacyUserId, User, UserStore,
     proto::{self, ChannelRole, ChannelVisibility},
 };
 use fuzzy::{StringMatchCandidate, match_strings};
@@ -364,15 +364,20 @@ impl PickerDelegate for ChannelModalDelegate {
 
     fn confirm(&mut self, _: bool, window: &mut Window, cx: &mut Context<Picker<Self>>) {
         if let Some(selected_user) = self.user_at_index(self.selected_index) {
-            if Some(selected_user.id) == self.user_store.read(cx).current_user().map(|user| user.id)
+            if Some(selected_user.legacy_id)
+                == self
+                    .user_store
+                    .read(cx)
+                    .current_user()
+                    .map(|user| user.legacy_id)
             {
                 return;
             }
             match self.mode {
                 Mode::ManageMembers => self.show_context_menu(self.selected_index, window, cx),
-                Mode::InviteMembers => match self.member_status(selected_user.id, cx) {
+                Mode::InviteMembers => match self.member_status(selected_user.legacy_id, cx) {
                     Some(proto::channel_member::Kind::Invitee) => {
-                        self.remove_member(selected_user.id, window, cx);
+                        self.remove_member(selected_user.legacy_id, window, cx);
                     }
                     Some(proto::channel_member::Kind::Member) => {}
                     None => self.invite_member(selected_user, window, cx),
@@ -400,8 +405,13 @@ impl PickerDelegate for ChannelModalDelegate {
     ) -> Option<Self::ListItem> {
         let user = self.user_at_index(ix)?;
         let membership = self.member_at_index(ix);
-        let request_status = self.member_status(user.id, cx);
-        let is_me = self.user_store.read(cx).current_user().map(|user| user.id) == Some(user.id);
+        let request_status = self.member_status(user.legacy_id, cx);
+        let is_me = self
+            .user_store
+            .read(cx)
+            .current_user()
+            .map(|user| user.legacy_id)
+            == Some(user.legacy_id);
 
         Some(
             ListItem::new(ix)
@@ -459,10 +469,16 @@ impl PickerDelegate for ChannelModalDelegate {
 }
 
 impl ChannelModalDelegate {
-    fn member_status(&self, user_id: UserId, cx: &App) -> Option<proto::channel_member::Kind> {
+    fn member_status(
+        &self,
+        user_id: LegacyUserId,
+        cx: &App,
+    ) -> Option<proto::channel_member::Kind> {
         self.members
             .iter()
-            .find_map(|membership| (membership.user.id == user_id).then_some(membership.kind))
+            .find_map(|membership| {
+                (membership.user.legacy_id == user_id).then_some(membership.kind)
+            })
             .or_else(|| {
                 self.channel_store
                     .read(cx)
@@ -489,7 +505,7 @@ impl ChannelModalDelegate {
 
     fn set_user_role(
         &mut self,
-        user_id: UserId,
+        user_id: LegacyUserId,
         new_role: ChannelRole,
         window: &mut Window,
         cx: &mut Context<Picker<Self>>,
@@ -501,7 +517,11 @@ impl ChannelModalDelegate {
             update.await?;
             picker.update_in(cx, |picker, window, cx| {
                 let this = &mut picker.delegate;
-                if let Some(member) = this.members.iter_mut().find(|m| m.user.id == user_id) {
+                if let Some(member) = this
+                    .members
+                    .iter_mut()
+                    .find(|m| m.user.legacy_id == user_id)
+                {
                     member.role = new_role;
                 }
                 cx.focus_self(window);
@@ -514,7 +534,7 @@ impl ChannelModalDelegate {
 
     fn remove_member(
         &mut self,
-        user_id: UserId,
+        user_id: LegacyUserId,
         window: &mut Window,
         cx: &mut Context<Picker<Self>>,
     ) -> Option<()> {
@@ -525,7 +545,11 @@ impl ChannelModalDelegate {
             update.await?;
             picker.update_in(cx, |picker, window, cx| {
                 let this = &mut picker.delegate;
-                if let Some(ix) = this.members.iter_mut().position(|m| m.user.id == user_id) {
+                if let Some(ix) = this
+                    .members
+                    .iter_mut()
+                    .position(|m| m.user.legacy_id == user_id)
+                {
                     this.members.remove(ix);
                     this.matching_member_indices.retain_mut(|member_ix| {
                         if *member_ix == ix {
@@ -556,7 +580,7 @@ impl ChannelModalDelegate {
         cx: &mut Context<Picker<Self>>,
     ) {
         let invite_member = self.channel_store.update(cx, |store, cx| {
-            store.invite_member(self.channel_id, user.id, ChannelRole::Member, cx)
+            store.invite_member(self.channel_id, user.legacy_id, ChannelRole::Member, cx)
         });
 
         cx.spawn_in(window, async move |this, cx| {
@@ -588,7 +612,7 @@ impl ChannelModalDelegate {
         let Some(membership) = self.member_at_index(ix) else {
             return;
         };
-        let user_id = membership.user.id;
+        let user_id = membership.user.legacy_id;
         let picker = cx.entity();
         let context_menu = ContextMenu::build(window, cx, |mut menu, _window, _cx| {
             let role = membership.role;

crates/collab_ui/src/collab_panel/contact_finder.rs 🔗

@@ -122,12 +122,12 @@ impl PickerDelegate for ContactFinderDelegate {
             match user_store.contact_request_status(user) {
                 ContactRequestStatus::None | ContactRequestStatus::RequestReceived => {
                     self.user_store
-                        .update(cx, |store, cx| store.request_contact(user.id, cx))
+                        .update(cx, |store, cx| store.request_contact(user.legacy_id, cx))
                         .detach();
                 }
                 ContactRequestStatus::RequestSent => {
                     self.user_store
-                        .update(cx, |store, cx| store.remove_contact(user.id, cx))
+                        .update(cx, |store, cx| store.remove_contact(user.legacy_id, cx))
                         .detach();
                 }
                 _ => {}

crates/collab_ui/src/notifications/incoming_call_notification.rs 🔗

@@ -71,7 +71,7 @@ impl IncomingCallNotificationState {
         let active_call = ActiveCall::global(cx);
         if accept {
             let join = active_call.update(cx, |active_call, cx| active_call.accept_incoming(cx));
-            let caller_user_id = self.call.calling_user.id;
+            let caller_user_id = self.call.calling_user.legacy_id;
             let initial_project_id = self.call.initial_project.as_ref().map(|project| project.id);
             let app_state = self.app_state.clone();
             let cx: &mut App = cx;

crates/collab_ui/src/notifications/project_shared_notification.rs 🔗

@@ -102,7 +102,7 @@ impl ProjectSharedNotification {
 
     fn join(&mut self, cx: &mut Context<Self>) {
         if let Some(app_state) = self.app_state.upgrade() {
-            workspace::join_in_room_project(self.project_id, self.owner.id, app_state, cx)
+            workspace::join_in_room_project(self.project_id, self.owner.legacy_id, app_state, cx)
                 .detach_and_log_err(cx);
         }
     }

crates/title_bar/src/collab.rs 🔗

@@ -214,7 +214,7 @@ impl TitleBar {
 
                         Some(
                             v_flex()
-                                .id(("collaborator", collaborator.user.id))
+                                .id(("collaborator", collaborator.user.legacy_id))
                                 .child(facepile)
                                 .child(render_color_ribbon(player_color.cursor))
                                 .cursor_pointer()
@@ -261,7 +261,7 @@ impl TitleBar {
         current_user: &Arc<User>,
         cx: &App,
     ) -> Option<Div> {
-        if room.role_for_user(user.id) == Some(proto::ChannelRole::Guest) {
+        if room.role_for_user(user.legacy_id) == Some(proto::ChannelRole::Guest) {
             return None;
         }
 

crates/title_bar/src/title_bar.rs 🔗

@@ -690,7 +690,7 @@ impl TitleBar {
             .user_store
             .read(cx)
             .participant_indices()
-            .get(&host_user.id)?;
+            .get(&host_user.legacy_id)?;
 
         Some(
             Button::new("project_owner_trigger", host_user.github_login.clone())

crates/workspace/src/pane_group.rs 🔗

@@ -408,7 +408,7 @@ impl PaneLeaderDecorator for PaneRenderContext<'_> {
                                 ))
                             })
                         } else {
-                            leader_join_data = Some((leader_project_id, leader.user.id));
+                            leader_join_data = Some((leader_project_id, leader.user.legacy_id));
                             Some(Label::new(format!(
                                 "Follow {} to their active project",
                                 leader.user.github_login,

crates/workspace/src/workspace.rs 🔗

@@ -5876,10 +5876,18 @@ impl Workspace {
             // if they are active in another project, follow there.
             if let Some(project_id) = other_project_id {
                 let app_state = self.app_state.clone();
-                crate::join_in_room_project(project_id, remote_participant.user.id, app_state, cx)
-                    .detach_and_prompt_err("Failed to join project", window, cx, |error, _, _| {
-                        Some(format!("{error:#}"))
-                    });
+                crate::join_in_room_project(
+                    project_id,
+                    remote_participant.user.legacy_id,
+                    app_state,
+                    cx,
+                )
+                .detach_and_prompt_err(
+                    "Failed to join project",
+                    window,
+                    cx,
+                    |error, _, _| Some(format!("{error:#}")),
+                );
             }
         }