diff --git a/crates/call2/src/call2.rs b/crates/call2/src/call2.rs index 9aa8c11428..e778316d59 100644 --- a/crates/call2/src/call2.rs +++ b/crates/call2/src/call2.rs @@ -17,6 +17,7 @@ use gpui::{ Subscription, Task, View, ViewContext, WeakModel, WeakView, }; pub use participant::ParticipantLocation; +use participant::RemoteParticipant; use postage::watch; use project::Project; use room::Event; @@ -628,6 +629,42 @@ impl CallHandler for Call { this.invite(called_user_id, initial_project, cx) }) } + fn remote_participants(&self, cx: &AppContext) -> Option>> { + self.active_call + .as_ref() + .map(|call| { + call.0.read(cx).room().map(|room| { + room.read(cx) + .remote_participants() + .iter() + .map(|participant| participant.1.user.clone()) + .collect() + }) + }) + .flatten() + } + fn is_muted(&self, cx: &AppContext) -> Option { + self.active_call + .as_ref() + .map(|call| { + call.0 + .read(cx) + .room() + .map(|room| room.read(cx).is_muted(cx)) + }) + .flatten() + } + fn toggle_mute(&self, cx: &mut AppContext) { + self.active_call.as_ref().map(|call| { + call.0.update(cx, |this, cx| { + this.room().map(|room| { + room.update(cx, |this, cx| { + this.toggle_mute(cx); + }) + }) + }) + }); + } } #[cfg(test)] diff --git a/crates/call2/src/room.rs b/crates/call2/src/room.rs index 87118764fd..d73a522937 100644 --- a/crates/call2/src/room.rs +++ b/crates/call2/src/room.rs @@ -333,7 +333,8 @@ impl Room { } pub fn mute_on_join(cx: &AppContext) -> bool { - CallSettings::get_global(cx).mute_on_join || client::IMPERSONATE_LOGIN.is_some() + false + //CallSettings::get_global(cx).mute_on_join || client::IMPERSONATE_LOGIN.is_some() } fn from_join_response( diff --git a/crates/client2/src/client2.rs b/crates/client2/src/client2.rs index 4ad354f2f9..b31451aa87 100644 --- a/crates/client2/src/client2.rs +++ b/crates/client2/src/client2.rs @@ -551,7 +551,6 @@ impl Client { F: 'static + Future>, { let message_type_id = TypeId::of::(); - let mut state = self.state.write(); state .models_by_message_type diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 7c9cb9f453..bcb43d4972 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -37,7 +37,8 @@ use gpui::{ }; use project::Project; use theme::ActiveTheme; -use ui::{h_stack, Button, ButtonVariant, Color, IconButton, KeyBinding, Tooltip}; +use ui::{h_stack, Avatar, Button, ButtonVariant, Color, IconButton, KeyBinding, Label, Tooltip}; +use util::ResultExt; use workspace::Workspace; // const MAX_PROJECT_NAME_LENGTH: usize = 40; @@ -92,6 +93,23 @@ impl Render for CollabTitlebarItem { let is_shared = is_in_room && self.project.read(cx).is_shared(); let current_user = self.user_store.read(cx).current_user(); let client = self.client.clone(); + let users = self + .workspace + .update(cx, |this, cx| this.call_state().remote_participants(cx)) + .log_err() + .flatten(); + let mic_icon = if self + .workspace + .update(cx, |this, cx| this.call_state().is_muted(cx)) + .log_err() + .flatten() + .unwrap_or_default() + { + ui::Icon::MicMute + } else { + ui::Icon::Mic + }; + let workspace = self.workspace.clone(); h_stack() .id("titlebar") .justify_between() @@ -157,6 +175,46 @@ impl Render for CollabTitlebarItem { }), ), ) + .when_some( + users.zip(current_user.clone()), + |this, (remote_participants, current_user)| { + this.children( + current_user + .avatar + .clone() + .map(|avatar| Avatar::new(avatar.clone())) + .into_iter() + .chain(remote_participants.into_iter().flat_map(|user| { + user.avatar + .as_ref() + .map(|avatar| Avatar::new(avatar.clone())) + })), + ) + }, + ) + .when(is_in_room, |this| { + this.child( + h_stack() + .child( + h_stack() + .child(Button::new(if is_shared { "Unshare" } else { "Share" })) + .child(IconButton::new("leave-call", ui::Icon::Exit)), + ) + .child( + h_stack() + .child(IconButton::new("mute-microphone", mic_icon).on_click( + move |_, cx| { + workspace.update(cx, |this, cx| { + this.call_state().toggle_mute(cx); + }); + }, + )) + .child(IconButton::new("mute-sound", ui::Icon::AudioOn)) + .child(IconButton::new("screen-share", ui::Icon::Screen)) + .pl_2(), + ), + ) + }) .map(|this| { if let Some(user) = current_user { this.when_some(user.avatar.clone(), |this, avatar| { @@ -173,23 +231,6 @@ impl Render for CollabTitlebarItem { })) } }) - .when(is_in_room, |this| { - this.child( - h_stack() - .child( - h_stack() - .child(Button::new(if is_shared { "Unshare" } else { "Share" })) - .child(IconButton::new("leave-call", ui::Icon::Exit)), - ) - .child( - h_stack() - .child(IconButton::new("mute-microphone", ui::Icon::Mic)) - .child(IconButton::new("mute-sound", ui::Icon::AudioOn)) - .child(IconButton::new("screen-share", ui::Icon::Screen)) - .pl_2(), - ), - ) - }) } } diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 8c687becd0..bccb25b64d 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -19,7 +19,7 @@ use anyhow::{anyhow, Context as _, Result}; use async_trait::async_trait; use client2::{ proto::{self, PeerId}, - Client, TypedEnvelope, UserStore, + Client, TypedEnvelope, User, UserStore, }; use collections::{hash_map, HashMap, HashSet}; use dock::{Dock, DockPosition, Panel, PanelButtons, PanelHandle}; @@ -351,7 +351,27 @@ impl CallHandler for TestCallHandler { fn active_project(&self, cx: &AppContext) -> Option> { None } + + fn invite( + &mut self, + called_user_id: u64, + initial_project: Option>, + cx: &mut AppContext, + ) -> Task> { + unimplemented!() + } + + fn remote_participants(&self, cx: &AppContext) -> Option> { + None + } + + fn is_muted(&self, cx: &AppContext) -> Option { + None + } + + fn toggle_mute(&self, cx: &mut AppContext) {} } + impl AppState { #[cfg(any(test, feature = "test-support"))] pub fn test(cx: &mut AppContext) -> Arc { @@ -460,6 +480,9 @@ pub trait CallHandler { initial_project: Option>, cx: &mut AppContext, ) -> Task>; + fn remote_participants(&self, cx: &AppContext) -> Option>>; + fn is_muted(&self, cx: &AppContext) -> Option; + fn toggle_mute(&self, cx: &mut AppContext); } pub struct Workspace {