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
|
@ -2,6 +2,12 @@ use super::*;
|
|||
use prost::Message;
|
||||
use text::{EditOperation, UndoOperation};
|
||||
|
||||
pub struct LeftChannelBuffer {
|
||||
pub channel_id: ChannelId,
|
||||
pub collaborators: Vec<proto::Collaborator>,
|
||||
pub connections: Vec<ConnectionId>,
|
||||
}
|
||||
|
||||
impl Database {
|
||||
pub async fn join_channel_buffer(
|
||||
&self,
|
||||
|
@ -204,23 +210,26 @@ impl Database {
|
|||
server_id: ServerId,
|
||||
) -> Result<RefreshedChannelBuffer> {
|
||||
self.transaction(|tx| async move {
|
||||
let collaborators = channel_buffer_collaborator::Entity::find()
|
||||
let db_collaborators = channel_buffer_collaborator::Entity::find()
|
||||
.filter(channel_buffer_collaborator::Column::ChannelId.eq(channel_id))
|
||||
.all(&*tx)
|
||||
.await?;
|
||||
|
||||
let mut connection_ids = Vec::new();
|
||||
let mut removed_collaborators = Vec::new();
|
||||
let mut collaborators = Vec::new();
|
||||
let mut collaborator_ids_to_remove = Vec::new();
|
||||
for collaborator in &collaborators {
|
||||
if !collaborator.connection_lost && collaborator.connection_server_id == server_id {
|
||||
connection_ids.push(collaborator.connection());
|
||||
for db_collaborator in &db_collaborators {
|
||||
if !db_collaborator.connection_lost
|
||||
&& db_collaborator.connection_server_id == server_id
|
||||
{
|
||||
connection_ids.push(db_collaborator.connection());
|
||||
collaborators.push(proto::Collaborator {
|
||||
peer_id: Some(db_collaborator.connection().into()),
|
||||
replica_id: db_collaborator.replica_id.0 as u32,
|
||||
user_id: db_collaborator.user_id.to_proto(),
|
||||
})
|
||||
} else {
|
||||
removed_collaborators.push(proto::RemoveChannelBufferCollaborator {
|
||||
channel_id: channel_id.to_proto(),
|
||||
peer_id: Some(collaborator.connection().into()),
|
||||
});
|
||||
collaborator_ids_to_remove.push(collaborator.id);
|
||||
collaborator_ids_to_remove.push(db_collaborator.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,7 +240,7 @@ impl Database {
|
|||
|
||||
Ok(RefreshedChannelBuffer {
|
||||
connection_ids,
|
||||
removed_collaborators,
|
||||
collaborators,
|
||||
})
|
||||
})
|
||||
.await
|
||||
|
@ -241,7 +250,7 @@ impl Database {
|
|||
&self,
|
||||
channel_id: ChannelId,
|
||||
connection: ConnectionId,
|
||||
) -> Result<Vec<ConnectionId>> {
|
||||
) -> Result<LeftChannelBuffer> {
|
||||
self.transaction(|tx| async move {
|
||||
self.leave_channel_buffer_internal(channel_id, connection, &*tx)
|
||||
.await
|
||||
|
@ -275,7 +284,7 @@ impl Database {
|
|||
pub async fn leave_channel_buffers(
|
||||
&self,
|
||||
connection: ConnectionId,
|
||||
) -> Result<Vec<(ChannelId, Vec<ConnectionId>)>> {
|
||||
) -> Result<Vec<LeftChannelBuffer>> {
|
||||
self.transaction(|tx| async move {
|
||||
#[derive(Debug, Clone, Copy, EnumIter, DeriveColumn)]
|
||||
enum QueryChannelIds {
|
||||
|
@ -294,10 +303,10 @@ impl Database {
|
|||
|
||||
let mut result = Vec::new();
|
||||
for channel_id in channel_ids {
|
||||
let collaborators = self
|
||||
let left_channel_buffer = self
|
||||
.leave_channel_buffer_internal(channel_id, connection, &*tx)
|
||||
.await?;
|
||||
result.push((channel_id, collaborators));
|
||||
result.push(left_channel_buffer);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
|
@ -310,7 +319,7 @@ impl Database {
|
|||
channel_id: ChannelId,
|
||||
connection: ConnectionId,
|
||||
tx: &DatabaseTransaction,
|
||||
) -> Result<Vec<ConnectionId>> {
|
||||
) -> Result<LeftChannelBuffer> {
|
||||
let result = channel_buffer_collaborator::Entity::delete_many()
|
||||
.filter(
|
||||
Condition::all()
|
||||
|
@ -327,6 +336,7 @@ impl Database {
|
|||
Err(anyhow!("not a collaborator on this project"))?;
|
||||
}
|
||||
|
||||
let mut collaborators = Vec::new();
|
||||
let mut connections = Vec::new();
|
||||
let mut rows = channel_buffer_collaborator::Entity::find()
|
||||
.filter(
|
||||
|
@ -336,19 +346,26 @@ impl Database {
|
|||
.await?;
|
||||
while let Some(row) = rows.next().await {
|
||||
let row = row?;
|
||||
connections.push(ConnectionId {
|
||||
id: row.connection_id as u32,
|
||||
owner_id: row.connection_server_id.0 as u32,
|
||||
let connection = row.connection();
|
||||
connections.push(connection);
|
||||
collaborators.push(proto::Collaborator {
|
||||
peer_id: Some(connection.into()),
|
||||
replica_id: row.replica_id.0 as u32,
|
||||
user_id: row.user_id.to_proto(),
|
||||
});
|
||||
}
|
||||
|
||||
drop(rows);
|
||||
|
||||
if connections.is_empty() {
|
||||
if collaborators.is_empty() {
|
||||
self.snapshot_channel_buffer(channel_id, &tx).await?;
|
||||
}
|
||||
|
||||
Ok(connections)
|
||||
Ok(LeftChannelBuffer {
|
||||
channel_id,
|
||||
collaborators,
|
||||
connections,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn get_channel_buffer_collaborators(
|
||||
|
|
|
@ -152,6 +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,
|
||||
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(
|
||||
|
@ -283,6 +284,22 @@ impl Database {
|
|||
.await?
|
||||
.ok_or_else(|| anyhow!("no such room"))?;
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||
enum QueryColorIndices {
|
||||
ColorIndex,
|
||||
}
|
||||
let existing_color_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>()
|
||||
.all(&*tx)
|
||||
.await?;
|
||||
let mut color_index = 0;
|
||||
while existing_color_indices.contains(&color_index) {
|
||||
color_index += 1;
|
||||
}
|
||||
|
||||
if let Some(channel_id) = channel_id {
|
||||
self.check_user_is_channel_member(channel_id, user_id, &*tx)
|
||||
.await?;
|
||||
|
@ -300,6 +317,7 @@ impl Database {
|
|||
calling_connection_server_id: ActiveValue::set(Some(ServerId(
|
||||
connection.owner_id as i32,
|
||||
))),
|
||||
color_index: ActiveValue::Set(color_index),
|
||||
..Default::default()
|
||||
}])
|
||||
.on_conflict(
|
||||
|
@ -322,6 +340,7 @@ impl Database {
|
|||
.add(room_participant::Column::AnsweringConnectionId.is_null()),
|
||||
)
|
||||
.set(room_participant::ActiveModel {
|
||||
color_index: ActiveValue::Set(color_index),
|
||||
answering_connection_id: ActiveValue::set(Some(connection.id as i32)),
|
||||
answering_connection_server_id: ActiveValue::set(Some(ServerId(
|
||||
connection.owner_id as i32,
|
||||
|
@ -1071,6 +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,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue