WIP - Retain hosts' project state when they disconnect

This commit is contained in:
Max Brunsfeld 2022-12-16 17:33:30 -08:00
parent 67b265b3d5
commit af85db9ea5
2 changed files with 39 additions and 30 deletions

View file

@ -43,6 +43,7 @@ pub struct Room {
id: u64, id: u64,
live_kit: Option<LiveKitRoom>, live_kit: Option<LiveKitRoom>,
status: RoomStatus, status: RoomStatus,
shared_projects: HashSet<WeakModelHandle<Project>>,
local_participant: LocalParticipant, local_participant: LocalParticipant,
remote_participants: BTreeMap<u64, RemoteParticipant>, remote_participants: BTreeMap<u64, RemoteParticipant>,
pending_participants: Vec<Arc<User>>, pending_participants: Vec<Arc<User>>,
@ -132,6 +133,7 @@ impl Room {
id, id,
live_kit: live_kit_room, live_kit: live_kit_room,
status: RoomStatus::Online, status: RoomStatus::Online,
shared_projects: Default::default(),
participant_user_ids: Default::default(), participant_user_ids: Default::default(),
local_participant: Default::default(), local_participant: Default::default(),
remote_participants: Default::default(), remote_participants: Default::default(),
@ -291,9 +293,18 @@ impl Room {
.ok_or_else(|| anyhow!("room was dropped"))? .ok_or_else(|| anyhow!("room was dropped"))?
.update(&mut cx, |this, cx| { .update(&mut cx, |this, cx| {
this.status = RoomStatus::Online; this.status = RoomStatus::Online;
this.apply_room_update(room_proto, cx) this.apply_room_update(room_proto, cx)?;
})?; this.shared_projects.retain(|project| {
anyhow::Ok(()) 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() { 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. // If the user's location is in this project, it changes from UnsharedProject to SharedProject.
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {
this.shared_projects.insert(project.downgrade());
let active_project = this.local_participant.active_project.as_ref(); let active_project = this.local_participant.active_project.as_ref();
if active_project.map_or(false, |location| *location == project) { if active_project.map_or(false, |location| *location == project) {
this.set_location(Some(&project), cx) this.set_location(Some(&project), cx)

View file

@ -1601,10 +1601,11 @@ impl Database {
.exec(&*tx) .exec(&*tx)
.await?; .await?;
let collaborator_on_projects = project_collaborator::Entity::find() let guest_collaborators_and_projects = project_collaborator::Entity::find()
.find_also_related(project::Entity) .find_also_related(project::Entity)
.filter( .filter(
Condition::all() Condition::all()
.add(project_collaborator::Column::IsHost.eq(false))
.add(project_collaborator::Column::ConnectionId.eq(connection.id as i32)) .add(project_collaborator::Column::ConnectionId.eq(connection.id as i32))
.add( .add(
project_collaborator::Column::ConnectionServerId project_collaborator::Column::ConnectionServerId
@ -1613,40 +1614,36 @@ impl Database {
) )
.all(&*tx) .all(&*tx)
.await?; .await?;
project_collaborator::Entity::delete_many() project_collaborator::Entity::delete_many()
.filter( .filter(
Condition::all() project_collaborator::Column::Id
.add(project_collaborator::Column::ConnectionId.eq(connection.id as i32)) .is_in(guest_collaborators_and_projects.iter().map(|e| e.0.id)),
.add(
project_collaborator::Column::ConnectionServerId
.eq(connection.owner_id as i32),
),
) )
.exec(&*tx) .exec(&*tx)
.await?; .await?;
let mut left_projects = Vec::new(); let mut left_projects = Vec::new();
for (_, project) in collaborator_on_projects { for (_, project) in guest_collaborators_and_projects {
if let Some(project) = project { let Some(project) = project else { continue };
let collaborators = project let collaborators = project
.find_related(project_collaborator::Entity) .find_related(project_collaborator::Entity)
.all(&*tx) .all(&*tx)
.await?; .await?;
let connection_ids = collaborators let connection_ids = collaborators
.into_iter() .into_iter()
.map(|collaborator| ConnectionId { .map(|collaborator| ConnectionId {
id: collaborator.connection_id as u32, id: collaborator.connection_id as u32,
owner_id: collaborator.connection_server_id.0 as u32, owner_id: collaborator.connection_server_id.0 as u32,
}) })
.collect(); .collect();
left_projects.push(LeftProject { left_projects.push(LeftProject {
id: project.id, id: project.id,
host_user_id: project.host_user_id, host_user_id: project.host_user_id,
host_connection_id: project.host_connection()?, host_connection_id: project.host_connection()?,
connection_ids, connection_ids,
}); });
}
} }
project::Entity::delete_many() project::Entity::delete_many()