Add mute handling

This commit is contained in:
Piotr Osiewicz 2023-11-24 15:16:03 +01:00
parent f2b62c3946
commit 6ebe5d5053
5 changed files with 122 additions and 21 deletions

View file

@ -17,6 +17,7 @@ use gpui::{
Subscription, Task, View, ViewContext, WeakModel, WeakView, Subscription, Task, View, ViewContext, WeakModel, WeakView,
}; };
pub use participant::ParticipantLocation; pub use participant::ParticipantLocation;
use participant::RemoteParticipant;
use postage::watch; use postage::watch;
use project::Project; use project::Project;
use room::Event; use room::Event;
@ -628,6 +629,42 @@ impl CallHandler for Call {
this.invite(called_user_id, initial_project, cx) this.invite(called_user_id, initial_project, cx)
}) })
} }
fn remote_participants(&self, cx: &AppContext) -> Option<Vec<Arc<User>>> {
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<bool> {
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)] #[cfg(test)]

View file

@ -333,7 +333,8 @@ impl Room {
} }
pub fn mute_on_join(cx: &AppContext) -> bool { 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( fn from_join_response(

View file

@ -551,7 +551,6 @@ impl Client {
F: 'static + Future<Output = Result<()>>, F: 'static + Future<Output = Result<()>>,
{ {
let message_type_id = TypeId::of::<M>(); let message_type_id = TypeId::of::<M>();
let mut state = self.state.write(); let mut state = self.state.write();
state state
.models_by_message_type .models_by_message_type

View file

@ -37,7 +37,8 @@ use gpui::{
}; };
use project::Project; use project::Project;
use theme::ActiveTheme; 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; use workspace::Workspace;
// const MAX_PROJECT_NAME_LENGTH: usize = 40; // 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 is_shared = is_in_room && self.project.read(cx).is_shared();
let current_user = self.user_store.read(cx).current_user(); let current_user = self.user_store.read(cx).current_user();
let client = self.client.clone(); 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() h_stack()
.id("titlebar") .id("titlebar")
.justify_between() .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| { .map(|this| {
if let Some(user) = current_user { if let Some(user) = current_user {
this.when_some(user.avatar.clone(), |this, avatar| { 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(),
),
)
})
} }
} }

View file

@ -19,7 +19,7 @@ use anyhow::{anyhow, Context as _, Result};
use async_trait::async_trait; use async_trait::async_trait;
use client2::{ use client2::{
proto::{self, PeerId}, proto::{self, PeerId},
Client, TypedEnvelope, UserStore, Client, TypedEnvelope, User, UserStore,
}; };
use collections::{hash_map, HashMap, HashSet}; use collections::{hash_map, HashMap, HashSet};
use dock::{Dock, DockPosition, Panel, PanelButtons, PanelHandle}; use dock::{Dock, DockPosition, Panel, PanelButtons, PanelHandle};
@ -351,7 +351,27 @@ impl CallHandler for TestCallHandler {
fn active_project(&self, cx: &AppContext) -> Option<WeakModel<Project>> { fn active_project(&self, cx: &AppContext) -> Option<WeakModel<Project>> {
None None
} }
fn invite(
&mut self,
called_user_id: u64,
initial_project: Option<Model<Project>>,
cx: &mut AppContext,
) -> Task<Result<()>> {
unimplemented!()
}
fn remote_participants(&self, cx: &AppContext) -> Option<Vec<User>> {
None
}
fn is_muted(&self, cx: &AppContext) -> Option<bool> {
None
}
fn toggle_mute(&self, cx: &mut AppContext) {}
} }
impl AppState { impl AppState {
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
pub fn test(cx: &mut AppContext) -> Arc<Self> { pub fn test(cx: &mut AppContext) -> Arc<Self> {
@ -460,6 +480,9 @@ pub trait CallHandler {
initial_project: Option<Model<Project>>, initial_project: Option<Model<Project>>,
cx: &mut AppContext, cx: &mut AppContext,
) -> Task<Result<()>>; ) -> Task<Result<()>>;
fn remote_participants(&self, cx: &AppContext) -> Option<Vec<Arc<User>>>;
fn is_muted(&self, cx: &AppContext) -> Option<bool>;
fn toggle_mute(&self, cx: &mut AppContext);
} }
pub struct Workspace { pub struct Workspace {