Prototype cursor sharing (the inefficient way) (#3970)

Conrad Irwin created

Release Notes:

- Sync guest users' cursor positions

Change summary

crates/collab/src/db/queries/projects.rs |  8 +++++---
crates/collab/src/rpc.rs                 | 15 ++++++++++++++-
2 files changed, 19 insertions(+), 4 deletions(-)

Detailed changes

crates/collab/src/db/queries/projects.rs 🔗

@@ -883,6 +883,7 @@ impl Database {
         &self,
         project_id: ProjectId,
         connection_id: ConnectionId,
+        requires_write: bool,
     ) -> Result<RoomGuard<Vec<ProjectCollaborator>>> {
         let room_id = self.room_id_for_project(project_id).await?;
         self.room_transaction(room_id, |tx| async move {
@@ -893,9 +894,10 @@ impl Database {
                 .await?
                 .ok_or_else(|| anyhow!("no such room"))?;
 
-            if !current_participant
-                .role
-                .map_or(false, |role| role.can_edit_projects())
+            if requires_write
+                && !current_participant
+                    .role
+                    .map_or(false, |role| role.can_edit_projects())
             {
                 Err(anyhow!("not authorized to edit projects"))?;
             }

crates/collab/src/rpc.rs 🔗

@@ -1859,11 +1859,24 @@ async fn update_buffer(
     let mut guest_connection_ids;
     let mut host_connection_id = None;
 
+    let mut requires_write_permission = false;
+
+    for op in request.operations.iter() {
+        match op.variant {
+            None | Some(proto::operation::Variant::UpdateSelections(_)) => {}
+            Some(_) => requires_write_permission = true,
+        }
+    }
+
     {
         let collaborators = session
             .db()
             .await
-            .project_collaborators_for_buffer_update(project_id, session.connection_id)
+            .project_collaborators_for_buffer_update(
+                project_id,
+                session.connection_id,
+                requires_write_permission,
+            )
             .await?;
         guest_connection_ids = Vec::with_capacity(collaborators.len() - 1);
         for collaborator in collaborators.iter() {