diff --git a/crates/collab/src/db.rs b/crates/collab/src/db.rs index e60cc99145..ec89a3dfac 100644 --- a/crates/collab/src/db.rs +++ b/crates/collab/src/db.rs @@ -1747,6 +1747,47 @@ impl Database { .await } + pub async fn unfollow( + &self, + room_id: RoomId, + project_id: ProjectId, + leader_connection: ConnectionId, + follower_connection: ConnectionId, + ) -> Result> { + self.room_transaction(|tx| async move { + follower::Entity::delete_many() + .filter( + Condition::all() + .add(follower::Column::RoomId.eq(room_id)) + .add(follower::Column::ProjectId.eq(project_id)) + .add( + Condition::any() + .add( + follower::Column::LeaderConnectionServerId + .eq(leader_connection.owner_id) + .and( + follower::Column::LeaderConnectionId + .eq(leader_connection.id), + ), + ) + .add( + follower::Column::FollowerConnectionServerId + .eq(follower_connection.owner_id) + .and( + follower::Column::FollowerConnectionId + .eq(follower_connection.id), + ), + ), + ), + ) + .exec(&*tx) + .await?; + + Ok((room_id, self.get_room(room_id, &*tx).await?)) + }) + .await + } + pub async fn update_room_participant_location( &self, room_id: RoomId, diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index fad34497eb..2260c10605 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -1719,13 +1719,14 @@ async fn follow( response: Response, session: Session, ) -> Result<()> { - let project_id = ProjectId::from_proto(request.project_id); let room_id = RoomId::from_proto(request.project_id); + let project_id = ProjectId::from_proto(request.project_id); let leader_id = request .leader_id .ok_or_else(|| anyhow!("invalid leader id"))? .into(); let follower_id = session.connection_id; + { let project_connection_ids = session .db() @@ -1758,22 +1759,35 @@ async fn follow( } async fn unfollow(request: proto::Unfollow, session: Session) -> Result<()> { + let room_id = RoomId::from_proto(request.project_id); let project_id = ProjectId::from_proto(request.project_id); let leader_id = request .leader_id .ok_or_else(|| anyhow!("invalid leader id"))? .into(); - let project_connection_ids = session + let follower_id = session.connection_id; + + if !session .db() .await .project_connection_ids(project_id, session.connection_id) - .await?; - if !project_connection_ids.contains(&leader_id) { + .await? + .contains(&leader_id) + { Err(anyhow!("no such peer"))?; } + session .peer .forward_send(session.connection_id, leader_id, request)?; + + let room = session + .db() + .await + .unfollow(room_id, project_id, leader_id, follower_id) + .await?; + room_updated(&room, &session.peer); + Ok(()) }