Assign unique color indices to room participants, use those instead of replica_ids
Co-authored-by: Conrad <conrad@zed.dev> Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
parent
7711530704
commit
545b5e0161
35 changed files with 707 additions and 639 deletions
|
@ -1,10 +1,12 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use call::ActiveCall;
|
||||
use channel::{Channel, ChannelBuffer, ChannelBufferEvent, ChannelId};
|
||||
use client::proto;
|
||||
use clock::ReplicaId;
|
||||
use client::{
|
||||
proto::{self, PeerId},
|
||||
Collaborator,
|
||||
};
|
||||
use collections::HashMap;
|
||||
use editor::Editor;
|
||||
use editor::{CollaborationHub, Editor};
|
||||
use gpui::{
|
||||
actions,
|
||||
elements::{ChildView, Label},
|
||||
|
@ -109,97 +111,44 @@ impl ChannelView {
|
|||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let buffer = channel_buffer.read(cx).buffer();
|
||||
let editor = cx.add_view(|cx| Editor::for_buffer(buffer, None, cx));
|
||||
let editor = cx.add_view(|cx| {
|
||||
let mut editor = Editor::for_buffer(buffer, None, cx);
|
||||
editor.set_collaboration_hub(Box::new(ChannelBufferCollaborationHub(
|
||||
channel_buffer.clone(),
|
||||
)));
|
||||
editor
|
||||
});
|
||||
let _editor_event_subscription = cx.subscribe(&editor, |_, _, e, cx| cx.emit(e.clone()));
|
||||
|
||||
cx.subscribe(&project, Self::handle_project_event).detach();
|
||||
cx.subscribe(&channel_buffer, Self::handle_channel_buffer_event)
|
||||
.detach();
|
||||
|
||||
let this = Self {
|
||||
Self {
|
||||
editor,
|
||||
project,
|
||||
channel_buffer,
|
||||
remote_id: None,
|
||||
_editor_event_subscription,
|
||||
};
|
||||
this.refresh_replica_id_map(cx);
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
pub fn channel(&self, cx: &AppContext) -> Arc<Channel> {
|
||||
self.channel_buffer.read(cx).channel()
|
||||
}
|
||||
|
||||
fn handle_project_event(
|
||||
&mut self,
|
||||
_: ModelHandle<Project>,
|
||||
event: &project::Event,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
match event {
|
||||
project::Event::RemoteIdChanged(_) => {}
|
||||
project::Event::DisconnectedFromHost => {}
|
||||
project::Event::Closed => {}
|
||||
project::Event::CollaboratorUpdated { .. } => {}
|
||||
project::Event::CollaboratorLeft(_) => {}
|
||||
project::Event::CollaboratorJoined(_) => {}
|
||||
_ => return,
|
||||
}
|
||||
self.refresh_replica_id_map(cx);
|
||||
}
|
||||
|
||||
fn handle_channel_buffer_event(
|
||||
&mut self,
|
||||
_: ModelHandle<ChannelBuffer>,
|
||||
event: &ChannelBufferEvent,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
match event {
|
||||
ChannelBufferEvent::CollaboratorsChanged => {
|
||||
self.refresh_replica_id_map(cx);
|
||||
}
|
||||
ChannelBufferEvent::Disconnected => self.editor.update(cx, |editor, cx| {
|
||||
if let ChannelBufferEvent::Disconnected = event {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.set_read_only(true);
|
||||
cx.notify();
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a mapping of channel buffer replica ids to the corresponding
|
||||
/// replica ids in the current project.
|
||||
///
|
||||
/// Using this mapping, a given user can be displayed with the same color
|
||||
/// in the channel buffer as in other files in the project. Users who are
|
||||
/// in the channel buffer but not the project will not have a color.
|
||||
fn refresh_replica_id_map(&self, cx: &mut ViewContext<Self>) {
|
||||
let mut project_replica_ids_by_channel_buffer_replica_id = HashMap::default();
|
||||
let project = self.project.read(cx);
|
||||
let channel_buffer = self.channel_buffer.read(cx);
|
||||
project_replica_ids_by_channel_buffer_replica_id
|
||||
.insert(channel_buffer.replica_id(cx), project.replica_id());
|
||||
project_replica_ids_by_channel_buffer_replica_id.extend(
|
||||
channel_buffer
|
||||
.collaborators()
|
||||
.iter()
|
||||
.filter_map(|channel_buffer_collaborator| {
|
||||
project
|
||||
.collaborators()
|
||||
.values()
|
||||
.find_map(|project_collaborator| {
|
||||
(project_collaborator.user_id == channel_buffer_collaborator.user_id)
|
||||
.then_some((
|
||||
channel_buffer_collaborator.replica_id as ReplicaId,
|
||||
project_collaborator.replica_id,
|
||||
))
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.set_replica_id_map(Some(project_replica_ids_by_channel_buffer_replica_id), cx)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for ChannelView {
|
||||
|
@ -388,13 +337,9 @@ impl FollowableItem for ChannelView {
|
|||
})
|
||||
}
|
||||
|
||||
fn set_leader_replica_id(
|
||||
&mut self,
|
||||
leader_replica_id: Option<u16>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
fn set_leader_peer_id(&mut self, leader_peer_id: Option<PeerId>, cx: &mut ViewContext<Self>) {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.set_leader_replica_id(leader_replica_id, cx)
|
||||
editor.set_leader_peer_id(leader_peer_id, cx)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -406,3 +351,15 @@ impl FollowableItem for ChannelView {
|
|||
false
|
||||
}
|
||||
}
|
||||
|
||||
struct ChannelBufferCollaborationHub(ModelHandle<ChannelBuffer>);
|
||||
|
||||
impl CollaborationHub for ChannelBufferCollaborationHub {
|
||||
fn collaborators<'a>(&self, cx: &'a AppContext) -> &'a HashMap<PeerId, Collaborator> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -923,9 +923,15 @@ impl CollabTitlebarItem {
|
|||
.background_color
|
||||
.unwrap_or_default();
|
||||
|
||||
if let Some(replica_id) = replica_id {
|
||||
let color_index = self
|
||||
.user_store
|
||||
.read(cx)
|
||||
.color_indices()
|
||||
.get(&user_id)
|
||||
.copied();
|
||||
if let Some(color_index) = color_index {
|
||||
if followed_by_self {
|
||||
let selection = theme.editor.replica_selection_style(replica_id).selection;
|
||||
let selection = theme.editor.replica_selection_style(color_index).selection;
|
||||
background_color = Color::blend(selection, background_color);
|
||||
background_color.a = 255;
|
||||
}
|
||||
|
@ -990,10 +996,10 @@ impl CollabTitlebarItem {
|
|||
.contained()
|
||||
.with_style(theme.titlebar.leader_selection);
|
||||
|
||||
if let Some(replica_id) = replica_id {
|
||||
if let Some(color_index) = color_index {
|
||||
if followed_by_self {
|
||||
let color =
|
||||
theme.editor.replica_selection_style(replica_id).selection;
|
||||
theme.editor.replica_selection_style(color_index).selection;
|
||||
container = container.with_background_color(color);
|
||||
}
|
||||
}
|
||||
|
@ -1001,8 +1007,8 @@ impl CollabTitlebarItem {
|
|||
container
|
||||
}))
|
||||
.with_children((|| {
|
||||
let replica_id = replica_id?;
|
||||
let color = theme.editor.replica_selection_style(replica_id).cursor;
|
||||
let color_index = color_index?;
|
||||
let color = theme.editor.replica_selection_style(color_index).cursor;
|
||||
Some(
|
||||
AvatarRibbon::new(color)
|
||||
.constrained()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue