Wire through LiveKit permissions

Conrad Irwin created

Change summary

crates/call/src/room.rs                      | 26 ++++++++++-----
crates/collab/src/rpc.rs                     | 35 +++++++++++++--------
crates/collab_ui/src/collab_titlebar_item.rs | 15 ++++++--
crates/rpc/proto/zed.proto                   |  1 
4 files changed, 51 insertions(+), 26 deletions(-)

Detailed changes

crates/call/src/room.rs 🔗

@@ -122,6 +122,10 @@ impl Room {
         }
     }
 
+    pub fn can_publish(&self) -> bool {
+        self.live_kit.as_ref().is_some_and(|room| room.can_publish)
+    }
+
     fn new(
         id: u64,
         channel_id: Option<u64>,
@@ -181,20 +185,23 @@ impl Room {
             });
 
             let connect = room.connect(&connection_info.server_url, &connection_info.token);
-            cx.spawn(|this, mut cx| async move {
-                connect.await?;
+            if connection_info.can_publish {
+                cx.spawn(|this, mut cx| async move {
+                    connect.await?;
 
-                if !cx.read(Self::mute_on_join) {
-                    this.update(&mut cx, |this, cx| this.share_microphone(cx))
-                        .await?;
-                }
+                    if !cx.read(Self::mute_on_join) {
+                        this.update(&mut cx, |this, cx| this.share_microphone(cx))
+                            .await?;
+                    }
 
-                anyhow::Ok(())
-            })
-            .detach_and_log_err(cx);
+                    anyhow::Ok(())
+                })
+                .detach_and_log_err(cx);
+            }
 
             Some(LiveKitRoom {
                 room,
+                can_publish: connection_info.can_publish,
                 screen_track: LocalTrack::None,
                 microphone_track: LocalTrack::None,
                 next_publish_id: 0,
@@ -1498,6 +1505,7 @@ struct LiveKitRoom {
     deafened: bool,
     speaking: bool,
     next_publish_id: usize,
+    can_publish: bool,
     _maintain_room: Task<()>,
     _maintain_tracks: [Task<()>; 2],
 }

crates/collab/src/rpc.rs 🔗

@@ -948,6 +948,7 @@ async fn create_room(
             Some(proto::LiveKitConnectionInfo {
                 server_url: live_kit.url().into(),
                 token,
+                can_publish: true,
             })
         })
     }
@@ -1028,6 +1029,7 @@ async fn join_room(
             Some(proto::LiveKitConnectionInfo {
                 server_url: live_kit.url().into(),
                 token,
+                can_publish: true,
             })
         } else {
             None
@@ -2598,25 +2600,32 @@ async fn join_channel_internal(
             .await?;
 
         let live_kit_connection_info = session.live_kit_client.as_ref().and_then(|live_kit| {
-            let token = if role == ChannelRole::Guest {
-                live_kit
-                    .guest_token(
-                        &joined_room.room.live_kit_room,
-                        &session.user_id.to_string(),
-                    )
-                    .trace_err()?
+            let (can_publish, token) = if role == ChannelRole::Guest {
+                (
+                    false,
+                    live_kit
+                        .guest_token(
+                            &joined_room.room.live_kit_room,
+                            &session.user_id.to_string(),
+                        )
+                        .trace_err()?,
+                )
             } else {
-                live_kit
-                    .room_token(
-                        &joined_room.room.live_kit_room,
-                        &session.user_id.to_string(),
-                    )
-                    .trace_err()?
+                (
+                    true,
+                    live_kit
+                        .room_token(
+                            &joined_room.room.live_kit_room,
+                            &session.user_id.to_string(),
+                        )
+                        .trace_err()?,
+                )
             };
 
             Some(LiveKitConnectionInfo {
                 server_url: live_kit.url().into(),
                 token,
+                can_publish,
             })
         });
 

crates/collab_ui/src/collab_titlebar_item.rs 🔗

@@ -88,8 +88,10 @@ impl View for CollabTitlebarItem {
             .zip(peer_id)
             .zip(ActiveCall::global(cx).read(cx).room().cloned())
         {
-            right_container
-                .add_children(self.render_in_call_share_unshare_button(&workspace, &theme, cx));
+            if room.read(cx).can_publish() {
+                right_container
+                    .add_children(self.render_in_call_share_unshare_button(&workspace, &theme, cx));
+            }
             right_container.add_child(self.render_leave_call(&theme, cx));
             let muted = room.read(cx).is_muted(cx);
             let speaking = room.read(cx).is_speaking();
@@ -97,9 +99,14 @@ impl View for CollabTitlebarItem {
                 self.render_current_user(&workspace, &theme, &user, peer_id, muted, speaking, cx),
             );
             left_container.add_children(self.render_collaborators(&workspace, &theme, &room, cx));
-            right_container.add_child(self.render_toggle_mute(&theme, &room, cx));
+            if room.read(cx).can_publish() {
+                right_container.add_child(self.render_toggle_mute(&theme, &room, cx));
+            }
             right_container.add_child(self.render_toggle_deafen(&theme, &room, cx));
-            right_container.add_child(self.render_toggle_screen_sharing_button(&theme, &room, cx));
+            if room.read(cx).can_publish() {
+                right_container
+                    .add_child(self.render_toggle_screen_sharing_button(&theme, &room, cx));
+            }
         }
 
         let status = workspace.read(cx).client().status();

crates/rpc/proto/zed.proto 🔗

@@ -335,6 +335,7 @@ message RoomUpdated {
 message LiveKitConnectionInfo {
     string server_url = 1;
     string token = 2;
+    bool can_publish = 3;
 }
 
 message ShareProject {