single click channel (#7596)
- Open channel notes and chat on channel click - WIP - Fix compile error - Don't join live kit until requested - Track in_call state separately from in_room Release Notes: - Improved channels: you can now be in a channel without joining the audio call automatically **or** - N/A --------- Co-authored-by: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
2b39a9512a
commit
efe23ebfcd
26 changed files with 659 additions and 489 deletions
|
@ -40,7 +40,7 @@ use util::{maybe, ResultExt, TryFutureExt};
|
|||
use workspace::{
|
||||
dock::{DockPosition, Panel, PanelEvent},
|
||||
notifications::{DetachAndPromptErr, NotifyResultExt, NotifyTaskExt},
|
||||
OpenChannelNotes, Workspace,
|
||||
Workspace,
|
||||
};
|
||||
|
||||
actions!(
|
||||
|
@ -69,19 +69,6 @@ pub fn init(cx: &mut AppContext) {
|
|||
workspace.register_action(|workspace, _: &ToggleFocus, cx| {
|
||||
workspace.toggle_panel_focus::<CollabPanel>(cx);
|
||||
});
|
||||
workspace.register_action(|_, _: &OpenChannelNotes, cx| {
|
||||
let channel_id = ActiveCall::global(cx)
|
||||
.read(cx)
|
||||
.room()
|
||||
.and_then(|room| room.read(cx).channel_id());
|
||||
|
||||
if let Some(channel_id) = channel_id {
|
||||
let workspace = cx.view().clone();
|
||||
cx.window_context().defer(move |cx| {
|
||||
ChannelView::open(channel_id, None, workspace, cx).detach_and_log_err(cx)
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
@ -175,6 +162,9 @@ enum ListEntry {
|
|||
depth: usize,
|
||||
has_children: bool,
|
||||
},
|
||||
ChannelCall {
|
||||
channel_id: ChannelId,
|
||||
},
|
||||
ChannelNotes {
|
||||
channel_id: ChannelId,
|
||||
},
|
||||
|
@ -382,6 +372,7 @@ impl CollabPanel {
|
|||
|
||||
if query.is_empty() {
|
||||
if let Some(channel_id) = room.channel_id() {
|
||||
self.entries.push(ListEntry::ChannelCall { channel_id });
|
||||
self.entries.push(ListEntry::ChannelNotes { channel_id });
|
||||
self.entries.push(ListEntry::ChannelChat { channel_id });
|
||||
}
|
||||
|
@ -479,7 +470,7 @@ impl CollabPanel {
|
|||
&& participant.video_tracks.is_empty(),
|
||||
});
|
||||
}
|
||||
if !participant.video_tracks.is_empty() {
|
||||
if room.in_call() && !participant.video_tracks.is_empty() {
|
||||
self.entries.push(ListEntry::ParticipantScreen {
|
||||
peer_id: Some(participant.peer_id),
|
||||
is_last: true,
|
||||
|
@ -832,8 +823,6 @@ impl CollabPanel {
|
|||
cx: &mut ViewContext<Self>,
|
||||
) -> ListItem {
|
||||
let user_id = user.id;
|
||||
let is_current_user =
|
||||
self.user_store.read(cx).current_user().map(|user| user.id) == Some(user_id);
|
||||
let tooltip = format!("Follow {}", user.github_login);
|
||||
|
||||
let is_call_admin = ActiveCall::global(cx).read(cx).room().is_some_and(|room| {
|
||||
|
@ -846,12 +835,6 @@ impl CollabPanel {
|
|||
.selected(is_selected)
|
||||
.end_slot(if is_pending {
|
||||
Label::new("Calling").color(Color::Muted).into_any_element()
|
||||
} else if is_current_user {
|
||||
IconButton::new("leave-call", IconName::Exit)
|
||||
.style(ButtonStyle::Subtle)
|
||||
.on_click(move |_, cx| Self::leave_call(cx))
|
||||
.tooltip(|cx| Tooltip::text("Leave Call", cx))
|
||||
.into_any_element()
|
||||
} else if role == proto::ChannelRole::Guest {
|
||||
Label::new("Guest").color(Color::Muted).into_any_element()
|
||||
} else {
|
||||
|
@ -953,12 +936,88 @@ impl CollabPanel {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_channel_call(
|
||||
&self,
|
||||
channel_id: ChannelId,
|
||||
is_selected: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> impl IntoElement {
|
||||
let (is_in_call, call_participants) = ActiveCall::global(cx)
|
||||
.read(cx)
|
||||
.room()
|
||||
.map(|room| (room.read(cx).in_call(), room.read(cx).call_participants(cx)))
|
||||
.unwrap_or_default();
|
||||
|
||||
const FACEPILE_LIMIT: usize = 3;
|
||||
|
||||
let face_pile = if !call_participants.is_empty() {
|
||||
let extra_count = call_participants.len().saturating_sub(FACEPILE_LIMIT);
|
||||
let result = FacePile::new(
|
||||
call_participants
|
||||
.iter()
|
||||
.map(|user| Avatar::new(user.avatar_uri.clone()).into_any_element())
|
||||
.take(FACEPILE_LIMIT)
|
||||
.chain(if extra_count > 0 {
|
||||
Some(
|
||||
div()
|
||||
.ml_2()
|
||||
.child(Label::new(format!("+{extra_count}")))
|
||||
.into_any_element(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.collect::<SmallVec<_>>(),
|
||||
);
|
||||
|
||||
Some(result)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
ListItem::new("channel-call")
|
||||
.selected(is_selected)
|
||||
.start_slot(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(render_tree_branch(false, true, cx))
|
||||
.child(IconButton::new(0, IconName::AudioOn)),
|
||||
)
|
||||
.when(is_in_call, |el| {
|
||||
el.end_slot(
|
||||
IconButton::new(1, IconName::Exit)
|
||||
.style(ButtonStyle::Filled)
|
||||
.shape(ui::IconButtonShape::Square)
|
||||
.tooltip(|cx| Tooltip::text("Leave call", cx))
|
||||
.on_click(cx.listener(|this, _, cx| this.leave_channel_call(cx))),
|
||||
)
|
||||
})
|
||||
.when(!is_in_call, |el| {
|
||||
el.tooltip(move |cx| Tooltip::text("Join audio call", cx))
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
this.join_channel_call(channel_id, cx);
|
||||
}))
|
||||
})
|
||||
.child(
|
||||
div()
|
||||
.text_ui()
|
||||
.when(!call_participants.is_empty(), |el| {
|
||||
el.font_weight(FontWeight::SEMIBOLD)
|
||||
})
|
||||
.child("call"),
|
||||
)
|
||||
.children(face_pile)
|
||||
}
|
||||
|
||||
fn render_channel_notes(
|
||||
&self,
|
||||
channel_id: ChannelId,
|
||||
is_selected: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> impl IntoElement {
|
||||
let channel_store = self.channel_store.read(cx);
|
||||
let has_notes_notification = channel_store.has_channel_buffer_changed(channel_id);
|
||||
|
||||
ListItem::new("channel-notes")
|
||||
.selected(is_selected)
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
|
@ -970,7 +1029,14 @@ impl CollabPanel {
|
|||
.child(render_tree_branch(false, true, cx))
|
||||
.child(IconButton::new(0, IconName::File)),
|
||||
)
|
||||
.child(Label::new("notes"))
|
||||
.child(
|
||||
div()
|
||||
.text_ui()
|
||||
.when(has_notes_notification, |el| {
|
||||
el.font_weight(FontWeight::SEMIBOLD)
|
||||
})
|
||||
.child("notes"),
|
||||
)
|
||||
.tooltip(move |cx| Tooltip::text("Open Channel Notes", cx))
|
||||
}
|
||||
|
||||
|
@ -980,6 +1046,8 @@ impl CollabPanel {
|
|||
is_selected: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> impl IntoElement {
|
||||
let channel_store = self.channel_store.read(cx);
|
||||
let has_messages_notification = channel_store.has_new_messages(channel_id);
|
||||
ListItem::new("channel-chat")
|
||||
.selected(is_selected)
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
|
@ -991,7 +1059,14 @@ impl CollabPanel {
|
|||
.child(render_tree_branch(false, false, cx))
|
||||
.child(IconButton::new(0, IconName::MessageBubbles)),
|
||||
)
|
||||
.child(Label::new("chat"))
|
||||
.child(
|
||||
div()
|
||||
.text_ui()
|
||||
.when(has_messages_notification, |el| {
|
||||
el.font_weight(FontWeight::SEMIBOLD)
|
||||
})
|
||||
.child("chat"),
|
||||
)
|
||||
.tooltip(move |cx| Tooltip::text("Open Chat", cx))
|
||||
}
|
||||
|
||||
|
@ -1249,12 +1324,14 @@ impl CollabPanel {
|
|||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
let this = cx.view().clone();
|
||||
let in_room = ActiveCall::global(cx).read(cx).room().is_some();
|
||||
let room = ActiveCall::global(cx).read(cx).room();
|
||||
let in_room = room.is_some();
|
||||
let in_call = room.is_some_and(|room| room.read(cx).in_call());
|
||||
|
||||
let context_menu = ContextMenu::build(cx, |mut context_menu, _| {
|
||||
let user_id = contact.user.id;
|
||||
|
||||
if contact.online && !contact.busy {
|
||||
if contact.online && !contact.busy && (!in_room || in_call) {
|
||||
let label = if in_room {
|
||||
format!("Invite {} to join", contact.user.github_login)
|
||||
} else {
|
||||
|
@ -1402,7 +1479,7 @@ impl CollabPanel {
|
|||
if is_active {
|
||||
self.open_channel_notes(channel.id, cx)
|
||||
} else {
|
||||
self.join_channel(channel.id, cx)
|
||||
self.open_channel(channel.id, cx)
|
||||
}
|
||||
}
|
||||
ListEntry::ContactPlaceholder => self.toggle_contact_finder(cx),
|
||||
|
@ -1421,6 +1498,9 @@ impl CollabPanel {
|
|||
ListEntry::ChannelInvite(channel) => {
|
||||
self.respond_to_channel_invite(channel.id, true, cx)
|
||||
}
|
||||
ListEntry::ChannelCall { channel_id } => {
|
||||
self.join_channel_call(*channel_id, cx)
|
||||
}
|
||||
ListEntry::ChannelNotes { channel_id } => {
|
||||
self.open_channel_notes(*channel_id, cx)
|
||||
}
|
||||
|
@ -1883,14 +1963,14 @@ impl CollabPanel {
|
|||
.detach_and_prompt_err("Call failed", cx, |_, _| None);
|
||||
}
|
||||
|
||||
fn join_channel(&self, channel_id: u64, cx: &mut ViewContext<Self>) {
|
||||
fn open_channel(&self, channel_id: u64, cx: &mut ViewContext<Self>) {
|
||||
let Some(workspace) = self.workspace.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let Some(handle) = cx.window_handle().downcast::<Workspace>() else {
|
||||
return;
|
||||
};
|
||||
workspace::join_channel(
|
||||
workspace::open_channel(
|
||||
channel_id,
|
||||
workspace.read(cx).app_state().clone(),
|
||||
Some(handle),
|
||||
|
@ -1899,6 +1979,23 @@ impl CollabPanel {
|
|||
.detach_and_prompt_err("Failed to join channel", cx, |_, _| None)
|
||||
}
|
||||
|
||||
fn join_channel_call(&mut self, _channel_id: ChannelId, cx: &mut ViewContext<Self>) {
|
||||
let Some(room) = ActiveCall::global(cx).read(cx).room().cloned() else {
|
||||
return;
|
||||
};
|
||||
|
||||
room.update(cx, |room, cx| room.join_call(cx))
|
||||
.detach_and_prompt_err("Failed to join call", cx, |_, _| None)
|
||||
}
|
||||
|
||||
fn leave_channel_call(&mut self, cx: &mut ViewContext<Self>) {
|
||||
let Some(room) = ActiveCall::global(cx).read(cx).room().cloned() else {
|
||||
return;
|
||||
};
|
||||
|
||||
room.update(cx, |room, cx| room.leave_call(cx));
|
||||
}
|
||||
|
||||
fn join_channel_chat(&mut self, channel_id: ChannelId, cx: &mut ViewContext<Self>) {
|
||||
let Some(workspace) = self.workspace.upgrade() else {
|
||||
return;
|
||||
|
@ -2024,6 +2121,9 @@ impl CollabPanel {
|
|||
ListEntry::ParticipantScreen { peer_id, is_last } => self
|
||||
.render_participant_screen(*peer_id, *is_last, is_selected, cx)
|
||||
.into_any_element(),
|
||||
ListEntry::ChannelCall { channel_id } => self
|
||||
.render_channel_call(*channel_id, is_selected, cx)
|
||||
.into_any_element(),
|
||||
ListEntry::ChannelNotes { channel_id } => self
|
||||
.render_channel_notes(*channel_id, is_selected, cx)
|
||||
.into_any_element(),
|
||||
|
@ -2089,7 +2189,6 @@ impl CollabPanel {
|
|||
is_collapsed: bool,
|
||||
cx: &ViewContext<Self>,
|
||||
) -> impl IntoElement {
|
||||
let mut channel_link = None;
|
||||
let mut channel_tooltip_text = None;
|
||||
let mut channel_icon = None;
|
||||
|
||||
|
@ -2100,13 +2199,12 @@ impl CollabPanel {
|
|||
|
||||
let channel = self.channel_store.read(cx).channel_for_id(channel_id)?;
|
||||
|
||||
channel_link = Some(channel.link());
|
||||
(channel_icon, channel_tooltip_text) = match channel.visibility {
|
||||
proto::ChannelVisibility::Public => {
|
||||
(Some("icons/public.svg"), Some("Copy public channel link."))
|
||||
(Some(IconName::Public), Some("Close Channel"))
|
||||
}
|
||||
proto::ChannelVisibility::Members => {
|
||||
(Some("icons/hash.svg"), Some("Copy private channel link."))
|
||||
(Some(IconName::Hash), Some("Close Channel"))
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2128,17 +2226,10 @@ impl CollabPanel {
|
|||
};
|
||||
|
||||
let button = match section {
|
||||
Section::ActiveCall => channel_link.map(|channel_link| {
|
||||
let channel_link_copy = channel_link.clone();
|
||||
IconButton::new("channel-link", IconName::Copy)
|
||||
.icon_size(IconSize::Small)
|
||||
.size(ButtonSize::None)
|
||||
.visible_on_hover("section-header")
|
||||
.on_click(move |_, cx| {
|
||||
let item = ClipboardItem::new(channel_link_copy.clone());
|
||||
cx.write_to_clipboard(item)
|
||||
})
|
||||
.tooltip(|cx| Tooltip::text("Copy channel link", cx))
|
||||
Section::ActiveCall => channel_icon.map(|_| {
|
||||
IconButton::new("channel-link", IconName::Close)
|
||||
.on_click(move |_, cx| Self::leave_call(cx))
|
||||
.tooltip(|cx| Tooltip::text("Close channel", cx))
|
||||
.into_any_element()
|
||||
}),
|
||||
Section::Contacts => Some(
|
||||
|
@ -2173,6 +2264,9 @@ impl CollabPanel {
|
|||
this.toggle_section_expanded(section, cx);
|
||||
}))
|
||||
})
|
||||
.when_some(channel_icon, |el, channel_icon| {
|
||||
el.start_slot(Icon::new(channel_icon).color(Color::Muted))
|
||||
})
|
||||
.inset(true)
|
||||
.end_slot::<AnyElement>(button)
|
||||
.selected(is_selected),
|
||||
|
@ -2478,11 +2572,9 @@ impl CollabPanel {
|
|||
}),
|
||||
)
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
if is_active {
|
||||
this.open_channel_notes(channel_id, cx)
|
||||
} else {
|
||||
this.join_channel(channel_id, cx)
|
||||
}
|
||||
this.open_channel(channel_id, cx);
|
||||
this.open_channel_notes(channel_id, cx);
|
||||
this.join_channel_chat(channel_id, cx);
|
||||
}))
|
||||
.on_secondary_mouse_down(cx.listener(
|
||||
move |this, event: &MouseDownEvent, cx| {
|
||||
|
@ -2499,61 +2591,24 @@ impl CollabPanel {
|
|||
.color(Color::Muted),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.id(channel_id as usize)
|
||||
.child(Label::new(channel.name.clone()))
|
||||
.children(face_pile.map(|face_pile| face_pile.p_1())),
|
||||
h_flex().id(channel_id as usize).child(
|
||||
div()
|
||||
.text_ui()
|
||||
.when(has_messages_notification || has_notes_notification, |el| {
|
||||
el.font_weight(FontWeight::SEMIBOLD)
|
||||
})
|
||||
.child(channel.name.clone()),
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
.children(face_pile.map(|face_pile| {
|
||||
h_flex()
|
||||
.absolute()
|
||||
.right(rems(0.))
|
||||
.z_index(1)
|
||||
.h_full()
|
||||
.child(
|
||||
h_flex()
|
||||
.h_full()
|
||||
.gap_1()
|
||||
.px_1()
|
||||
.child(
|
||||
IconButton::new("channel_chat", IconName::MessageBubbles)
|
||||
.style(ButtonStyle::Filled)
|
||||
.shape(ui::IconButtonShape::Square)
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_color(if has_messages_notification {
|
||||
Color::Default
|
||||
} else {
|
||||
Color::Muted
|
||||
})
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
this.join_channel_chat(channel_id, cx)
|
||||
}))
|
||||
.tooltip(|cx| Tooltip::text("Open channel chat", cx))
|
||||
.when(!has_messages_notification, |this| {
|
||||
this.visible_on_hover("")
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
IconButton::new("channel_notes", IconName::File)
|
||||
.style(ButtonStyle::Filled)
|
||||
.shape(ui::IconButtonShape::Square)
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_color(if has_notes_notification {
|
||||
Color::Default
|
||||
} else {
|
||||
Color::Muted
|
||||
})
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
this.open_channel_notes(channel_id, cx)
|
||||
}))
|
||||
.tooltip(|cx| Tooltip::text("Open channel notes", cx))
|
||||
.when(!has_notes_notification, |this| {
|
||||
this.visible_on_hover("")
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(face_pile.p_1())
|
||||
}))
|
||||
.tooltip({
|
||||
let channel_store = self.channel_store.clone();
|
||||
move |cx| {
|
||||
|
@ -2757,6 +2812,14 @@ impl PartialEq for ListEntry {
|
|||
return channel_1.id == channel_2.id;
|
||||
}
|
||||
}
|
||||
ListEntry::ChannelCall { channel_id } => {
|
||||
if let ListEntry::ChannelCall {
|
||||
channel_id: other_id,
|
||||
} = other
|
||||
{
|
||||
return channel_id == other_id;
|
||||
}
|
||||
}
|
||||
ListEntry::ChannelNotes { channel_id } => {
|
||||
if let ListEntry::ChannelNotes {
|
||||
channel_id: other_id,
|
||||
|
@ -2855,7 +2918,7 @@ impl Render for JoinChannelTooltip {
|
|||
.read(cx)
|
||||
.channel_participants(self.channel_id);
|
||||
|
||||
div.child(Label::new("Join Channel"))
|
||||
div.child(Label::new("Open Channel"))
|
||||
.children(participants.iter().map(|participant| {
|
||||
h_flex()
|
||||
.gap_2()
|
||||
|
|
|
@ -102,6 +102,10 @@ impl Render for CollabTitlebarItem {
|
|||
room.remote_participants().values().collect::<Vec<_>>();
|
||||
remote_participants.sort_by_key(|p| p.participant_index.0);
|
||||
|
||||
if !room.in_call() {
|
||||
return this;
|
||||
}
|
||||
|
||||
let current_user_face_pile = self.render_collaborator(
|
||||
¤t_user,
|
||||
peer_id,
|
||||
|
@ -133,6 +137,10 @@ impl Render for CollabTitlebarItem {
|
|||
== ParticipantLocation::SharedProject { project_id }
|
||||
});
|
||||
|
||||
if !collaborator.in_call {
|
||||
return None;
|
||||
}
|
||||
|
||||
let face_pile = self.render_collaborator(
|
||||
&collaborator.user,
|
||||
collaborator.peer_id,
|
||||
|
@ -185,7 +193,7 @@ impl Render for CollabTitlebarItem {
|
|||
let is_local = project.is_local();
|
||||
let is_shared = is_local && project.is_shared();
|
||||
let is_muted = room.is_muted();
|
||||
let is_deafened = room.is_deafened().unwrap_or(false);
|
||||
let is_connected_to_livekit = room.in_call();
|
||||
let is_screen_sharing = room.is_screen_sharing();
|
||||
let read_only = room.read_only();
|
||||
|
||||
|
@ -220,22 +228,28 @@ impl Render for CollabTitlebarItem {
|
|||
)),
|
||||
)
|
||||
})
|
||||
.child(
|
||||
div()
|
||||
.child(
|
||||
IconButton::new("leave-call", ui::IconName::Exit)
|
||||
.style(ButtonStyle::Subtle)
|
||||
.tooltip(|cx| Tooltip::text("Leave call", cx))
|
||||
.icon_size(IconSize::Small)
|
||||
.on_click(move |_, cx| {
|
||||
ActiveCall::global(cx)
|
||||
.update(cx, |call, cx| call.hang_up(cx))
|
||||
.detach_and_log_err(cx);
|
||||
}),
|
||||
)
|
||||
.pr_2(),
|
||||
)
|
||||
.when(!read_only, |this| {
|
||||
.when(is_connected_to_livekit, |el| {
|
||||
el.child(
|
||||
div()
|
||||
.child(
|
||||
IconButton::new("leave-call", ui::IconName::Exit)
|
||||
.style(ButtonStyle::Subtle)
|
||||
.tooltip(|cx| Tooltip::text("Leave call", cx))
|
||||
.icon_size(IconSize::Small)
|
||||
.on_click(move |_, cx| {
|
||||
ActiveCall::global(cx).update(cx, |call, cx| {
|
||||
if let Some(room) = call.room() {
|
||||
room.update(cx, |room, cx| {
|
||||
room.leave_call(cx)
|
||||
})
|
||||
}
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pl_2(),
|
||||
)
|
||||
})
|
||||
.when(!read_only && is_connected_to_livekit, |this| {
|
||||
this.child(
|
||||
IconButton::new(
|
||||
"mute-microphone",
|
||||
|
@ -262,34 +276,7 @@ impl Render for CollabTitlebarItem {
|
|||
.on_click(move |_, cx| crate::toggle_mute(&Default::default(), cx)),
|
||||
)
|
||||
})
|
||||
.child(
|
||||
IconButton::new(
|
||||
"mute-sound",
|
||||
if is_deafened {
|
||||
ui::IconName::AudioOff
|
||||
} else {
|
||||
ui::IconName::AudioOn
|
||||
},
|
||||
)
|
||||
.style(ButtonStyle::Subtle)
|
||||
.selected_style(ButtonStyle::Tinted(TintColor::Negative))
|
||||
.icon_size(IconSize::Small)
|
||||
.selected(is_deafened)
|
||||
.tooltip(move |cx| {
|
||||
if !read_only {
|
||||
Tooltip::with_meta(
|
||||
"Deafen Audio",
|
||||
None,
|
||||
"Mic will be muted",
|
||||
cx,
|
||||
)
|
||||
} else {
|
||||
Tooltip::text("Deafen Audio", cx)
|
||||
}
|
||||
})
|
||||
.on_click(move |_, cx| crate::toggle_deafen(&Default::default(), cx)),
|
||||
)
|
||||
.when(!read_only, |this| {
|
||||
.when(!read_only && is_connected_to_livekit, |this| {
|
||||
this.child(
|
||||
IconButton::new("screen-share", ui::IconName::Screen)
|
||||
.style(ButtonStyle::Subtle)
|
||||
|
|
|
@ -22,10 +22,7 @@ pub use panel_settings::{
|
|||
use settings::Settings;
|
||||
use workspace::{notifications::DetachAndPromptErr, AppState};
|
||||
|
||||
actions!(
|
||||
collab,
|
||||
[ToggleScreenSharing, ToggleMute, ToggleDeafen, LeaveCall]
|
||||
);
|
||||
actions!(collab, [ToggleScreenSharing, ToggleMute, LeaveCall]);
|
||||
|
||||
pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
|
||||
CollaborationPanelSettings::register(cx);
|
||||
|
@ -85,12 +82,6 @@ pub fn toggle_mute(_: &ToggleMute, cx: &mut AppContext) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn toggle_deafen(_: &ToggleDeafen, cx: &mut AppContext) {
|
||||
if let Some(room) = ActiveCall::global(cx).read(cx).room().cloned() {
|
||||
room.update(cx, |room, cx| room.toggle_deafen(cx));
|
||||
}
|
||||
}
|
||||
|
||||
fn notification_window_options(
|
||||
screen: Rc<dyn PlatformDisplay>,
|
||||
window_size: Size<Pixels>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue