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:
Max Brunsfeld 2023-09-26 15:19:38 -06:00
parent 7711530704
commit 545b5e0161
35 changed files with 707 additions and 639 deletions

View file

@ -1,22 +1,25 @@
use crate::Channel;
use anyhow::Result;
use client::Client;
use client::{Client, Collaborator, UserStore};
use collections::HashMap;
use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle};
use rpc::{proto, TypedEnvelope};
use rpc::{
proto::{self, PeerId},
TypedEnvelope,
};
use std::sync::Arc;
use util::ResultExt;
pub(crate) fn init(client: &Arc<Client>) {
client.add_model_message_handler(ChannelBuffer::handle_update_channel_buffer);
client.add_model_message_handler(ChannelBuffer::handle_add_channel_buffer_collaborator);
client.add_model_message_handler(ChannelBuffer::handle_remove_channel_buffer_collaborator);
client.add_model_message_handler(ChannelBuffer::handle_update_channel_buffer_collaborator);
client.add_model_message_handler(ChannelBuffer::handle_update_channel_buffer_collaborators);
}
pub struct ChannelBuffer {
pub(crate) channel: Arc<Channel>,
connected: bool,
collaborators: Vec<proto::Collaborator>,
collaborators: HashMap<PeerId, Collaborator>,
user_store: ModelHandle<UserStore>,
buffer: ModelHandle<language::Buffer>,
buffer_epoch: u64,
client: Arc<Client>,
@ -46,6 +49,7 @@ impl ChannelBuffer {
pub(crate) async fn new(
channel: Arc<Channel>,
client: Arc<Client>,
user_store: ModelHandle<UserStore>,
mut cx: AsyncAppContext,
) -> Result<ModelHandle<Self>> {
let response = client
@ -61,8 +65,6 @@ impl ChannelBuffer {
.map(language::proto::deserialize_operation)
.collect::<Result<Vec<_>, _>>()?;
let collaborators = response.collaborators;
let buffer = cx.add_model(|_| {
language::Buffer::remote(response.buffer_id, response.replica_id as u16, base_text)
});
@ -73,34 +75,45 @@ impl ChannelBuffer {
anyhow::Ok(cx.add_model(|cx| {
cx.subscribe(&buffer, Self::on_buffer_update).detach();
Self {
let mut this = Self {
buffer,
buffer_epoch: response.epoch,
client,
connected: true,
collaborators,
collaborators: Default::default(),
channel,
subscription: Some(subscription.set_model(&cx.handle(), &mut cx.to_async())),
}
user_store,
};
this.replace_collaborators(response.collaborators, cx);
this
}))
}
pub fn user_store(&self) -> &ModelHandle<UserStore> {
&self.user_store
}
pub(crate) fn replace_collaborators(
&mut self,
collaborators: Vec<proto::Collaborator>,
cx: &mut ModelContext<Self>,
) {
for old_collaborator in &self.collaborators {
if collaborators
.iter()
.any(|c| c.replica_id == old_collaborator.replica_id)
{
let mut new_collaborators = HashMap::default();
for collaborator in collaborators {
if let Ok(collaborator) = Collaborator::from_proto(collaborator) {
new_collaborators.insert(collaborator.peer_id, collaborator);
}
}
for (_, old_collaborator) in &self.collaborators {
if !new_collaborators.contains_key(&old_collaborator.peer_id) {
self.buffer.update(cx, |buffer, cx| {
buffer.remove_peer(old_collaborator.replica_id as u16, cx)
});
}
}
self.collaborators = collaborators;
self.collaborators = new_collaborators;
cx.emit(ChannelBufferEvent::CollaboratorsChanged);
cx.notify();
}
@ -127,64 +140,14 @@ impl ChannelBuffer {
Ok(())
}
async fn handle_add_channel_buffer_collaborator(
async fn handle_update_channel_buffer_collaborators(
this: ModelHandle<Self>,
envelope: TypedEnvelope<proto::AddChannelBufferCollaborator>,
_: Arc<Client>,
mut cx: AsyncAppContext,
) -> Result<()> {
let collaborator = envelope.payload.collaborator.ok_or_else(|| {
anyhow::anyhow!(
"Should have gotten a collaborator in the AddChannelBufferCollaborator message"
)
})?;
this.update(&mut cx, |this, cx| {
this.collaborators.push(collaborator);
cx.emit(ChannelBufferEvent::CollaboratorsChanged);
cx.notify();
});
Ok(())
}
async fn handle_remove_channel_buffer_collaborator(
this: ModelHandle<Self>,
message: TypedEnvelope<proto::RemoveChannelBufferCollaborator>,
message: TypedEnvelope<proto::UpdateChannelBufferCollaborators>,
_: Arc<Client>,
mut cx: AsyncAppContext,
) -> Result<()> {
this.update(&mut cx, |this, cx| {
this.collaborators.retain(|collaborator| {
if collaborator.peer_id == message.payload.peer_id {
this.buffer.update(cx, |buffer, cx| {
buffer.remove_peer(collaborator.replica_id as u16, cx)
});
false
} else {
true
}
});
cx.emit(ChannelBufferEvent::CollaboratorsChanged);
cx.notify();
});
Ok(())
}
async fn handle_update_channel_buffer_collaborator(
this: ModelHandle<Self>,
message: TypedEnvelope<proto::UpdateChannelBufferCollaborator>,
_: Arc<Client>,
mut cx: AsyncAppContext,
) -> Result<()> {
this.update(&mut cx, |this, cx| {
for collaborator in &mut this.collaborators {
if collaborator.peer_id == message.payload.old_peer_id {
collaborator.peer_id = message.payload.new_peer_id;
break;
}
}
this.replace_collaborators(message.payload.collaborators, cx);
cx.emit(ChannelBufferEvent::CollaboratorsChanged);
cx.notify();
});
@ -217,7 +180,7 @@ impl ChannelBuffer {
self.buffer.clone()
}
pub fn collaborators(&self) -> &[proto::Collaborator] {
pub fn collaborators(&self) -> &HashMap<PeerId, Collaborator> {
&self.collaborators
}