Rename color_index to participant_index

Max Brunsfeld and Conrad created

Co-authored-by: Conrad <conrad@zed.dev>

Change summary

crates/call/src/participant.rs                                                         |  4 
crates/call/src/room.rs                                                                | 13 
crates/client/src/user.rs                                                              | 24 
crates/collab/migrations.sqlite/20221109000000_test_schema.sql                         |  2 
crates/collab/migrations/20230926102500_add_color_index_to_room_participants.sql       |  1 
crates/collab/migrations/20230926102500_add_participant_index_to_room_participants.sql |  1 
crates/collab/src/db/queries/rooms.rs                                                  | 24 
crates/collab/src/db/tables/room_participant.rs                                        |  2 
crates/collab/src/tests/channel_buffer_tests.rs                                        | 24 
crates/collab_ui/src/channel_view.rs                                                   |  9 
crates/collab_ui/src/collab_titlebar_item.rs                                           | 26 
crates/editor/src/editor.rs                                                            | 24 
crates/editor/src/element.rs                                                           |  4 
crates/project/src/project.rs                                                          |  8 
crates/rpc/proto/zed.proto                                                             |  2 
crates/theme/src/theme.rs                                                              |  7 
crates/workspace/src/pane_group.rs                                                     |  2 
17 files changed, 97 insertions(+), 80 deletions(-)

Detailed changes

crates/call/src/participant.rs 🔗

@@ -1,4 +1,5 @@
 use anyhow::{anyhow, Result};
+use client::ParticipantIndex;
 use client::{proto, User};
 use collections::HashMap;
 use gpui::WeakModelHandle;
@@ -6,7 +7,6 @@ pub use live_kit_client::Frame;
 use live_kit_client::RemoteAudioTrack;
 use project::Project;
 use std::{fmt, sync::Arc};
-use theme::ColorIndex;
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum ParticipantLocation {
@@ -44,7 +44,7 @@ pub struct RemoteParticipant {
     pub peer_id: proto::PeerId,
     pub projects: Vec<proto::ParticipantProject>,
     pub location: ParticipantLocation,
-    pub color_index: ColorIndex,
+    pub participant_index: ParticipantIndex,
     pub muted: bool,
     pub speaking: bool,
     pub video_tracks: HashMap<live_kit_client::Sid, Arc<RemoteVideoTrack>>,

crates/call/src/room.rs 🔗

@@ -7,7 +7,7 @@ use anyhow::{anyhow, Result};
 use audio::{Audio, Sound};
 use client::{
     proto::{self, PeerId},
-    Client, TypedEnvelope, User, UserStore,
+    Client, ParticipantIndex, TypedEnvelope, User, UserStore,
 };
 use collections::{BTreeMap, HashMap, HashSet};
 use fs::Fs;
@@ -21,7 +21,6 @@ use live_kit_client::{
 use postage::stream::Stream;
 use project::Project;
 use std::{future::Future, mem, pin::Pin, sync::Arc, time::Duration};
-use theme::ColorIndex;
 use util::{post_inc, ResultExt, TryFutureExt};
 
 pub const RECONNECT_TIMEOUT: Duration = Duration::from_secs(30);
@@ -715,7 +714,9 @@ impl Room {
                                 participant.user_id,
                                 RemoteParticipant {
                                     user: user.clone(),
-                                    color_index: ColorIndex(participant.color_index),
+                                    participant_index: ParticipantIndex(
+                                        participant.participant_index,
+                                    ),
                                     peer_id,
                                     projects: participant.projects,
                                     location,
@@ -810,12 +811,12 @@ impl Room {
                 }
 
                 this.user_store.update(cx, |user_store, cx| {
-                    let color_indices_by_user_id = this
+                    let participant_indices_by_user_id = this
                         .remote_participants
                         .iter()
-                        .map(|(user_id, participant)| (*user_id, participant.color_index))
+                        .map(|(user_id, participant)| (*user_id, participant.participant_index))
                         .collect();
-                    user_store.set_color_indices(color_indices_by_user_id, cx);
+                    user_store.set_participant_indices(participant_indices_by_user_id, cx);
                 });
 
                 this.check_invariants();

crates/client/src/user.rs 🔗

@@ -8,12 +8,14 @@ use postage::{sink::Sink, watch};
 use rpc::proto::{RequestMessage, UsersResponse};
 use std::sync::{Arc, Weak};
 use text::ReplicaId;
-use theme::ColorIndex;
 use util::http::HttpClient;
 use util::TryFutureExt as _;
 
 pub type UserId = u64;
 
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct ParticipantIndex(pub u32);
+
 #[derive(Default, Debug)]
 pub struct User {
     pub id: UserId,
@@ -65,7 +67,7 @@ pub enum ContactRequestStatus {
 
 pub struct UserStore {
     users: HashMap<u64, Arc<User>>,
-    color_indices: HashMap<u64, ColorIndex>,
+    participant_indices: HashMap<u64, ParticipantIndex>,
     update_contacts_tx: mpsc::UnboundedSender<UpdateContacts>,
     current_user: watch::Receiver<Option<Arc<User>>>,
     contacts: Vec<Arc<Contact>>,
@@ -91,7 +93,7 @@ pub enum Event {
         kind: ContactEventKind,
     },
     ShowContacts,
-    ColorIndicesChanged,
+    ParticipantIndicesChanged,
 }
 
 #[derive(Clone, Copy)]
@@ -129,7 +131,7 @@ impl UserStore {
             current_user: current_user_rx,
             contacts: Default::default(),
             incoming_contact_requests: Default::default(),
-            color_indices: Default::default(),
+            participant_indices: Default::default(),
             outgoing_contact_requests: Default::default(),
             invite_info: None,
             client: Arc::downgrade(&client),
@@ -654,19 +656,19 @@ impl UserStore {
         })
     }
 
-    pub fn set_color_indices(
+    pub fn set_participant_indices(
         &mut self,
-        color_indices: HashMap<u64, ColorIndex>,
+        participant_indices: HashMap<u64, ParticipantIndex>,
         cx: &mut ModelContext<Self>,
     ) {
-        if color_indices != self.color_indices {
-            self.color_indices = color_indices;
-            cx.emit(Event::ColorIndicesChanged);
+        if participant_indices != self.participant_indices {
+            self.participant_indices = participant_indices;
+            cx.emit(Event::ParticipantIndicesChanged);
         }
     }
 
-    pub fn color_indices(&self) -> &HashMap<u64, ColorIndex> {
-        &self.color_indices
+    pub fn participant_indices(&self) -> &HashMap<u64, ParticipantIndex> {
+        &self.participant_indices
     }
 }
 

crates/collab/migrations.sqlite/20221109000000_test_schema.sql 🔗

@@ -159,7 +159,7 @@ CREATE TABLE "room_participants" (
     "calling_user_id" INTEGER NOT NULL REFERENCES users (id),
     "calling_connection_id" INTEGER NOT NULL,
     "calling_connection_server_id" INTEGER REFERENCES servers (id) ON DELETE SET NULL,
-    "color_index" INTEGER
+    "participant_index" INTEGER
 );
 CREATE UNIQUE INDEX "index_room_participants_on_user_id" ON "room_participants" ("user_id");
 CREATE INDEX "index_room_participants_on_room_id" ON "room_participants" ("room_id");

crates/collab/src/db/queries/rooms.rs 🔗

@@ -152,7 +152,7 @@ impl Database {
                 room_id: ActiveValue::set(room_id),
                 user_id: ActiveValue::set(called_user_id),
                 answering_connection_lost: ActiveValue::set(false),
-                color_index: ActiveValue::NotSet,
+                participant_index: ActiveValue::NotSet,
                 calling_user_id: ActiveValue::set(calling_user_id),
                 calling_connection_id: ActiveValue::set(calling_connection.id as i32),
                 calling_connection_server_id: ActiveValue::set(Some(ServerId(
@@ -285,19 +285,19 @@ impl Database {
                 .ok_or_else(|| anyhow!("no such room"))?;
 
             #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
-            enum QueryColorIndices {
-                ColorIndex,
+            enum QueryParticipantIndices {
+                ParticipantIndex,
             }
-            let existing_color_indices: Vec<i32> = room_participant::Entity::find()
+            let existing_participant_indices: Vec<i32> = room_participant::Entity::find()
                 .filter(room_participant::Column::RoomId.eq(room_id))
                 .select_only()
-                .column(room_participant::Column::ColorIndex)
-                .into_values::<_, QueryColorIndices>()
+                .column(room_participant::Column::ParticipantIndex)
+                .into_values::<_, QueryParticipantIndices>()
                 .all(&*tx)
                 .await?;
-            let mut color_index = 0;
-            while existing_color_indices.contains(&color_index) {
-                color_index += 1;
+            let mut participant_index = 0;
+            while existing_participant_indices.contains(&participant_index) {
+                participant_index += 1;
             }
 
             if let Some(channel_id) = channel_id {
@@ -317,7 +317,7 @@ impl Database {
                     calling_connection_server_id: ActiveValue::set(Some(ServerId(
                         connection.owner_id as i32,
                     ))),
-                    color_index: ActiveValue::Set(color_index),
+                    participant_index: ActiveValue::Set(participant_index),
                     ..Default::default()
                 }])
                 .on_conflict(
@@ -340,7 +340,7 @@ impl Database {
                             .add(room_participant::Column::AnsweringConnectionId.is_null()),
                     )
                     .set(room_participant::ActiveModel {
-                        color_index: ActiveValue::Set(color_index),
+                        participant_index: ActiveValue::Set(participant_index),
                         answering_connection_id: ActiveValue::set(Some(connection.id as i32)),
                         answering_connection_server_id: ActiveValue::set(Some(ServerId(
                             connection.owner_id as i32,
@@ -1090,7 +1090,7 @@ impl Database {
                         peer_id: Some(answering_connection.into()),
                         projects: Default::default(),
                         location: Some(proto::ParticipantLocation { variant: location }),
-                        color_index: db_participant.color_index as u32,
+                        participant_index: db_participant.participant_index as u32,
                     },
                 );
             } else {

crates/collab/src/db/tables/room_participant.rs 🔗

@@ -18,7 +18,7 @@ pub struct Model {
     pub calling_user_id: UserId,
     pub calling_connection_id: i32,
     pub calling_connection_server_id: Option<ServerId>,
-    pub color_index: i32,
+    pub participant_index: i32,
 }
 
 impl Model {

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

@@ -4,6 +4,7 @@ use crate::{
 };
 use call::ActiveCall;
 use channel::Channel;
+use client::ParticipantIndex;
 use client::{Collaborator, UserId};
 use collab_ui::channel_view::ChannelView;
 use collections::HashMap;
@@ -13,7 +14,6 @@ use gpui::{executor::Deterministic, ModelHandle, TestAppContext, ViewContext};
 use rpc::{proto::PeerId, RECEIVE_TIMEOUT};
 use serde_json::json;
 use std::{ops::Range, sync::Arc};
-use theme::ColorIndex;
 
 #[gpui::test]
 async fn test_core_channel_buffers(
@@ -122,7 +122,7 @@ async fn test_core_channel_buffers(
 }
 
 #[gpui::test]
-async fn test_channel_notes_color_indices(
+async fn test_channel_notes_participant_indices(
     deterministic: Arc<Deterministic>,
     mut cx_a: &mut TestAppContext,
     mut cx_b: &mut TestAppContext,
@@ -226,12 +226,20 @@ async fn test_channel_notes_color_indices(
     deterministic.run_until_parked();
     channel_view_a.update(cx_a, |notes, cx| {
         notes.editor.update(cx, |editor, cx| {
-            assert_remote_selections(editor, &[(Some(ColorIndex(1)), 1..2), (None, 2..3)], cx);
+            assert_remote_selections(
+                editor,
+                &[(Some(ParticipantIndex(1)), 1..2), (None, 2..3)],
+                cx,
+            );
         });
     });
     channel_view_b.update(cx_b, |notes, cx| {
         notes.editor.update(cx, |editor, cx| {
-            assert_remote_selections(editor, &[(Some(ColorIndex(0)), 0..1), (None, 2..3)], cx);
+            assert_remote_selections(
+                editor,
+                &[(Some(ParticipantIndex(0)), 0..1), (None, 2..3)],
+                cx,
+            );
         });
     });
 
@@ -275,17 +283,17 @@ async fn test_channel_notes_color_indices(
 
     // Clients A and B see each other with the same colors as in the channel notes.
     editor_a.update(cx_a, |editor, cx| {
-        assert_remote_selections(editor, &[(Some(ColorIndex(1)), 2..3)], cx);
+        assert_remote_selections(editor, &[(Some(ParticipantIndex(1)), 2..3)], cx);
     });
     editor_b.update(cx_b, |editor, cx| {
-        assert_remote_selections(editor, &[(Some(ColorIndex(0)), 0..1)], cx);
+        assert_remote_selections(editor, &[(Some(ParticipantIndex(0)), 0..1)], cx);
     });
 }
 
 #[track_caller]
 fn assert_remote_selections(
     editor: &mut Editor,
-    expected_selections: &[(Option<ColorIndex>, Range<usize>)],
+    expected_selections: &[(Option<ParticipantIndex>, Range<usize>)],
     cx: &mut ViewContext<Editor>,
 ) {
     let snapshot = editor.snapshot(cx);
@@ -295,7 +303,7 @@ fn assert_remote_selections(
         .map(|s| {
             let start = s.selection.start.to_offset(&snapshot.buffer_snapshot);
             let end = s.selection.end.to_offset(&snapshot.buffer_snapshot);
-            (s.color_index, start..end)
+            (s.participant_index, start..end)
         })
         .collect::<Vec<_>>();
     assert_eq!(

crates/collab_ui/src/channel_view.rs 🔗

@@ -3,7 +3,7 @@ use call::ActiveCall;
 use channel::{Channel, ChannelBuffer, ChannelBufferEvent, ChannelId};
 use client::{
     proto::{self, PeerId},
-    Collaborator,
+    Collaborator, ParticipantIndex,
 };
 use collections::HashMap;
 use editor::{CollaborationHub, Editor};
@@ -359,7 +359,10 @@ impl CollaborationHub for ChannelBufferCollaborationHub {
         self.0.read(cx).collaborators()
     }
 
-    fn user_color_indices<'a>(&self, cx: &'a AppContext) -> &'a HashMap<u64, theme::ColorIndex> {
-        self.0.read(cx).user_store().read(cx).color_indices()
+    fn user_participant_indices<'a>(
+        &self,
+        cx: &'a AppContext,
+    ) -> &'a HashMap<u64, ParticipantIndex> {
+        self.0.read(cx).user_store().read(cx).participant_indices()
     }
 }

crates/collab_ui/src/collab_titlebar_item.rs 🔗

@@ -923,15 +923,18 @@ impl CollabTitlebarItem {
             .background_color
             .unwrap_or_default();
 
-        let color_index = self
+        let participant_index = self
             .user_store
             .read(cx)
-            .color_indices()
+            .participant_indices()
             .get(&user_id)
             .copied();
-        if let Some(color_index) = color_index {
+        if let Some(participant_index) = participant_index {
             if followed_by_self {
-                let selection = theme.editor.replica_selection_style(color_index).selection;
+                let selection = theme
+                    .editor
+                    .selection_style_for_room_participant(participant_index.0)
+                    .selection;
                 background_color = Color::blend(selection, background_color);
                 background_color.a = 255;
             }
@@ -996,10 +999,12 @@ impl CollabTitlebarItem {
                             .contained()
                             .with_style(theme.titlebar.leader_selection);
 
-                        if let Some(color_index) = color_index {
+                        if let Some(participant_index) = participant_index {
                             if followed_by_self {
-                                let color =
-                                    theme.editor.replica_selection_style(color_index).selection;
+                                let color = theme
+                                    .editor
+                                    .selection_style_for_room_participant(participant_index.0)
+                                    .selection;
                                 container = container.with_background_color(color);
                             }
                         }
@@ -1007,8 +1012,11 @@ impl CollabTitlebarItem {
                         container
                     }))
                     .with_children((|| {
-                        let color_index = color_index?;
-                        let color = theme.editor.replica_selection_style(color_index).cursor;
+                        let participant_index = participant_index?;
+                        let color = theme
+                            .editor
+                            .selection_style_for_room_participant(participant_index.0)
+                            .cursor;
                         Some(
                             AvatarRibbon::new(color)
                                 .constrained()

crates/editor/src/editor.rs 🔗

@@ -25,7 +25,7 @@ use ::git::diff::DiffHunk;
 use aho_corasick::AhoCorasick;
 use anyhow::{anyhow, Context, Result};
 use blink_manager::BlinkManager;
-use client::{ClickhouseEvent, Collaborator, TelemetrySettings};
+use client::{ClickhouseEvent, Collaborator, ParticipantIndex, TelemetrySettings};
 use clock::{Global, ReplicaId};
 use collections::{BTreeMap, Bound, HashMap, HashSet, VecDeque};
 use convert_case::{Case, Casing};
@@ -102,7 +102,7 @@ use std::{
 pub use sum_tree::Bias;
 use sum_tree::TreeMap;
 use text::Rope;
-use theme::{ColorIndex, DiagnosticStyle, Theme, ThemeSettings};
+use theme::{DiagnosticStyle, Theme, ThemeSettings};
 use util::{post_inc, RangeExt, ResultExt, TryFutureExt};
 use workspace::{ItemNavHistory, ViewId, Workspace};
 
@@ -637,7 +637,7 @@ pub struct RemoteSelection {
     pub cursor_shape: CursorShape,
     pub peer_id: PeerId,
     pub line_mode: bool,
-    pub color_index: Option<ColorIndex>,
+    pub participant_index: Option<ParticipantIndex>,
 }
 
 #[derive(Clone, Debug)]
@@ -8570,7 +8570,10 @@ impl Editor {
 
 pub trait CollaborationHub {
     fn collaborators<'a>(&self, cx: &'a AppContext) -> &'a HashMap<PeerId, Collaborator>;
-    fn user_color_indices<'a>(&self, cx: &'a AppContext) -> &'a HashMap<u64, ColorIndex>;
+    fn user_participant_indices<'a>(
+        &self,
+        cx: &'a AppContext,
+    ) -> &'a HashMap<u64, ParticipantIndex>;
 }
 
 impl CollaborationHub for ModelHandle<Project> {
@@ -8578,8 +8581,11 @@ impl CollaborationHub for ModelHandle<Project> {
         self.read(cx).collaborators()
     }
 
-    fn user_color_indices<'a>(&self, cx: &'a AppContext) -> &'a HashMap<u64, ColorIndex> {
-        self.read(cx).user_store().read(cx).color_indices()
+    fn user_participant_indices<'a>(
+        &self,
+        cx: &'a AppContext,
+    ) -> &'a HashMap<u64, ParticipantIndex> {
+        self.read(cx).user_store().read(cx).participant_indices()
     }
 }
 
@@ -8632,7 +8638,7 @@ impl EditorSnapshot {
         collaboration_hub: &dyn CollaborationHub,
         cx: &'a AppContext,
     ) -> impl 'a + Iterator<Item = RemoteSelection> {
-        let color_indices = collaboration_hub.user_color_indices(cx);
+        let participant_indices = collaboration_hub.user_participant_indices(cx);
         let collaborators_by_peer_id = collaboration_hub.collaborators(cx);
         let collaborators_by_replica_id = collaborators_by_peer_id
             .iter()
@@ -8642,13 +8648,13 @@ impl EditorSnapshot {
             .remote_selections_in_range(range)
             .filter_map(move |(replica_id, line_mode, cursor_shape, selection)| {
                 let collaborator = collaborators_by_replica_id.get(&replica_id)?;
-                let color_index = color_indices.get(&collaborator.user_id).copied();
+                let participant_index = participant_indices.get(&collaborator.user_id).copied();
                 Some(RemoteSelection {
                     replica_id,
                     selection,
                     cursor_shape,
                     line_mode,
-                    color_index,
+                    participant_index,
                     peer_id: collaborator.peer_id,
                 })
             })

crates/editor/src/element.rs 🔗

@@ -2256,8 +2256,8 @@ impl Element<Editor> for EditorElement {
                 collaboration_hub.as_ref(),
                 cx,
             ) {
-                let selection_style = if let Some(color_index) = selection.color_index {
-                    style.replica_selection_style(color_index)
+                let selection_style = if let Some(participant_index) = selection.participant_index {
+                    style.selection_style_for_room_participant(participant_index.0)
                 } else {
                     style.absent_selection
                 };

crates/project/src/project.rs 🔗

@@ -76,7 +76,6 @@ use std::{
 };
 use terminals::Terminals;
 use text::Anchor;
-use theme::ColorIndex;
 use util::{
     debug_panic, defer, http::HttpClient, merge_json_value_into,
     paths::LOCAL_SETTINGS_RELATIVE_PATH, post_inc, ResultExt, TryFutureExt as _,
@@ -120,7 +119,6 @@ pub struct Project {
     join_project_response_message_id: u32,
     next_diagnostic_group_id: usize,
     user_store: ModelHandle<UserStore>,
-    user_color_indices: HashMap<ReplicaId, ColorIndex>,
     fs: Arc<dyn Fs>,
     client_state: Option<ProjectClientState>,
     collaborators: HashMap<proto::PeerId, Collaborator>,
@@ -644,7 +642,6 @@ impl Project {
                 languages,
                 client,
                 user_store,
-                user_color_indices: Default::default(),
                 fs,
                 next_entry_id: Default::default(),
                 next_diagnostic_group_id: Default::default(),
@@ -717,7 +714,6 @@ impl Project {
                 _maintain_workspace_config: Self::maintain_workspace_config(cx),
                 languages,
                 user_store: user_store.clone(),
-                user_color_indices: Default::default(),
                 fs,
                 next_entry_id: Default::default(),
                 next_diagnostic_group_id: Default::default(),
@@ -922,10 +918,6 @@ impl Project {
         self.user_store.clone()
     }
 
-    pub fn user_color_indices(&self) -> &HashMap<ReplicaId, ColorIndex> {
-        &self.user_color_indices
-    }
-
     pub fn opened_buffers(&self, cx: &AppContext) -> Vec<ModelHandle<Buffer>> {
         self.opened_buffers
             .values()

crates/rpc/proto/zed.proto 🔗

@@ -256,7 +256,7 @@ message Participant {
     PeerId peer_id = 2;
     repeated ParticipantProject projects = 3;
     ParticipantLocation location = 4;
-    uint32 color_index = 5;
+    uint32 participant_index = 5;
 }
 
 message PendingParticipant {

crates/theme/src/theme.rs 🔗

@@ -1064,15 +1064,12 @@ impl<'de, T: DeserializeOwned> Deserialize<'de> for Interactive<T> {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub struct ColorIndex(pub u32);
-
 impl Editor {
-    pub fn replica_selection_style(&self, color_index: ColorIndex) -> SelectionStyle {
+    pub fn selection_style_for_room_participant(&self, participant_index: u32) -> SelectionStyle {
         if self.guest_selections.is_empty() {
             return SelectionStyle::default();
         }
-        let style_ix = color_index.0 as usize % self.guest_selections.len();
+        let style_ix = participant_index as usize % self.guest_selections.len();
         self.guest_selections[style_ix]
     }
 }

crates/workspace/src/pane_group.rs 🔗

@@ -191,7 +191,7 @@ impl Member {
                 if let Some(leader) = &leader {
                     let leader_color = theme
                         .editor
-                        .replica_selection_style(leader.color_index)
+                        .selection_style_for_room_participant(leader.participant_index.0)
                         .cursor;
                     leader_border = Border::all(theme.workspace.leader_border_width, leader_color);
                     leader_border