From af85db9ea56af09856181b957b53d612a8411aaf Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 16 Dec 2022 17:33:30 -0800 Subject: [PATCH] WIP - Retain hosts' project state when they disconnect --- crates/call/src/room.rs | 18 ++++++++++++--- crates/collab/src/db.rs | 51 +++++++++++++++++++---------------------- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/crates/call/src/room.rs b/crates/call/src/room.rs index 8e2c38b3f8..1d279717f7 100644 --- a/crates/call/src/room.rs +++ b/crates/call/src/room.rs @@ -43,6 +43,7 @@ pub struct Room { id: u64, live_kit: Option, status: RoomStatus, + shared_projects: HashSet>, local_participant: LocalParticipant, remote_participants: BTreeMap, pending_participants: Vec>, @@ -132,6 +133,7 @@ impl Room { id, live_kit: live_kit_room, status: RoomStatus::Online, + shared_projects: Default::default(), participant_user_ids: Default::default(), local_participant: Default::default(), remote_participants: Default::default(), @@ -291,9 +293,18 @@ impl Room { .ok_or_else(|| anyhow!("room was dropped"))? .update(&mut cx, |this, cx| { this.status = RoomStatus::Online; - this.apply_room_update(room_proto, cx) - })?; - anyhow::Ok(()) + this.apply_room_update(room_proto, cx)?; + this.shared_projects.retain(|project| { + let Some(project) = project.upgrade(cx) else { return false }; + project.update(cx, |project, cx| { + if let Some(remote_id) = project.remote_id() { + project.shared(remote_id, cx).detach() + } + }); + true + }); + anyhow::Ok(()) + }) }; if rejoin_room.await.log_err().is_some() { @@ -666,6 +677,7 @@ impl Room { // If the user's location is in this project, it changes from UnsharedProject to SharedProject. this.update(&mut cx, |this, cx| { + this.shared_projects.insert(project.downgrade()); let active_project = this.local_participant.active_project.as_ref(); if active_project.map_or(false, |location| *location == project) { this.set_location(Some(&project), cx) diff --git a/crates/collab/src/db.rs b/crates/collab/src/db.rs index b1cbddc77e..6e9c365f0f 100644 --- a/crates/collab/src/db.rs +++ b/crates/collab/src/db.rs @@ -1601,10 +1601,11 @@ impl Database { .exec(&*tx) .await?; - let collaborator_on_projects = project_collaborator::Entity::find() + let guest_collaborators_and_projects = project_collaborator::Entity::find() .find_also_related(project::Entity) .filter( Condition::all() + .add(project_collaborator::Column::IsHost.eq(false)) .add(project_collaborator::Column::ConnectionId.eq(connection.id as i32)) .add( project_collaborator::Column::ConnectionServerId @@ -1613,40 +1614,36 @@ impl Database { ) .all(&*tx) .await?; + project_collaborator::Entity::delete_many() .filter( - Condition::all() - .add(project_collaborator::Column::ConnectionId.eq(connection.id as i32)) - .add( - project_collaborator::Column::ConnectionServerId - .eq(connection.owner_id as i32), - ), + project_collaborator::Column::Id + .is_in(guest_collaborators_and_projects.iter().map(|e| e.0.id)), ) .exec(&*tx) .await?; let mut left_projects = Vec::new(); - for (_, project) in collaborator_on_projects { - if let Some(project) = project { - let collaborators = project - .find_related(project_collaborator::Entity) - .all(&*tx) - .await?; - let connection_ids = collaborators - .into_iter() - .map(|collaborator| ConnectionId { - id: collaborator.connection_id as u32, - owner_id: collaborator.connection_server_id.0 as u32, - }) - .collect(); + for (_, project) in guest_collaborators_and_projects { + let Some(project) = project else { continue }; + let collaborators = project + .find_related(project_collaborator::Entity) + .all(&*tx) + .await?; + let connection_ids = collaborators + .into_iter() + .map(|collaborator| ConnectionId { + id: collaborator.connection_id as u32, + owner_id: collaborator.connection_server_id.0 as u32, + }) + .collect(); - left_projects.push(LeftProject { - id: project.id, - host_user_id: project.host_user_id, - host_connection_id: project.host_connection()?, - connection_ids, - }); - } + left_projects.push(LeftProject { + id: project.id, + host_user_id: project.host_user_id, + host_connection_id: project.host_connection()?, + connection_ids, + }); } project::Entity::delete_many()