From cef7d53607381975ea00d6302d8a9aab3c40eb1f Mon Sep 17 00:00:00 2001
From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
Date: Mon, 28 Jul 2025 10:01:31 -0300
Subject: [PATCH] collab: Refine call buttons design (#35007)
Making icons consistent, adjusting spacing, and moving the "Leave Call"
button to be the very last, which makes more sense to me than the
"Share" button being the last. Sharing your project is still part of the
call, so in the left edge of the button strip is where, conceptually,
the option to end the call should be, I think!
Release Notes:
- N/A
---
assets/icons/audio_off.svg | 8 ++-
assets/icons/audio_on.svg | 6 +-
assets/icons/exit.svg | 11 ++--
assets/icons/mic.svg | 6 +-
assets/icons/mic_mute.svg | 9 ++-
assets/icons/screen.svg | 11 ++--
crates/title_bar/src/collab.rs | 60 +++++++++----------
.../ui/src/components/button/split_button.rs | 12 +++-
8 files changed, 71 insertions(+), 52 deletions(-)
diff --git a/assets/icons/audio_off.svg b/assets/icons/audio_off.svg
index 93b98471ca1a15e4ef92860e953dde8beb559c37..dfb5a1c45829119ea0dc89bbca3a3f33228ee88f 100644
--- a/assets/icons/audio_off.svg
+++ b/assets/icons/audio_off.svg
@@ -1 +1,7 @@
-
+
+
+
+
+
+
+
diff --git a/assets/icons/audio_on.svg b/assets/icons/audio_on.svg
index 42310ea32c289e2ecf24a6fa231ae55fce3cb05e..d1bef0d337d6c8a0e79cb0dab8b7d63d5cb2a4d1 100644
--- a/assets/icons/audio_on.svg
+++ b/assets/icons/audio_on.svg
@@ -1 +1,5 @@
-
+
+
+
+
+
diff --git a/assets/icons/exit.svg b/assets/icons/exit.svg
index 2cc6ce120dc9af17a642ac3bf2f2451209cb5e5e..1ff9d7882441548e9c3534ae5ffe6b6331391b45 100644
--- a/assets/icons/exit.svg
+++ b/assets/icons/exit.svg
@@ -1,8 +1,5 @@
-
-
+
+
+
+
diff --git a/assets/icons/mic.svg b/assets/icons/mic.svg
index 01f4c9bf669ba253edaa43dc641fdb9a1b7c51d1..1d9c5bc9edf2a48b3311965fb57758b3ee2e015e 100644
--- a/assets/icons/mic.svg
+++ b/assets/icons/mic.svg
@@ -1,3 +1,5 @@
-
-
+
+
+
+
diff --git a/assets/icons/mic_mute.svg b/assets/icons/mic_mute.svg
index fe5f8201cc4da5e2cf6a1b770c538d421994e1c4..8c61ae2f1ccedc1b27244ed80e1a3fdd75cd4120 100644
--- a/assets/icons/mic_mute.svg
+++ b/assets/icons/mic_mute.svg
@@ -1,3 +1,8 @@
-
-
+
+
+
+
+
+
+
diff --git a/assets/icons/screen.svg b/assets/icons/screen.svg
index ad252e64cf5c73d4cd6ae48dd0abede47d3323e6..4b686b58f9de2e4993546ddad1a20af395d50330 100644
--- a/assets/icons/screen.svg
+++ b/assets/icons/screen.svg
@@ -1,8 +1,5 @@
-
-
+
+
+
+
diff --git a/crates/title_bar/src/collab.rs b/crates/title_bar/src/collab.rs
index 056c981ccf16a1e56fcaff99c32b4a284553a706..d026b4de14263f442c1ede308da0fe467fe69bba 100644
--- a/crates/title_bar/src/collab.rs
+++ b/crates/title_bar/src/collab.rs
@@ -11,8 +11,8 @@ use gpui::{App, Task, Window, actions};
use rpc::proto::{self};
use theme::ActiveTheme;
use ui::{
- Avatar, AvatarAudioStatusIndicator, ContextMenu, ContextMenuItem, Divider, Facepile,
- PopoverMenu, SplitButton, SplitButtonStyle, TintColor, Tooltip, prelude::*,
+ Avatar, AvatarAudioStatusIndicator, ContextMenu, ContextMenuItem, Divider, DividerColor,
+ Facepile, PopoverMenu, SplitButton, SplitButtonStyle, TintColor, Tooltip, prelude::*,
};
use util::maybe;
use workspace::notifications::DetachAndPromptErr;
@@ -343,6 +343,24 @@ impl TitleBar {
let mut children = Vec::new();
+ children.push(
+ h_flex()
+ .gap_1()
+ .child(
+ IconButton::new("leave-call", IconName::Exit)
+ .style(ButtonStyle::Subtle)
+ .tooltip(Tooltip::text("Leave Call"))
+ .icon_size(IconSize::Small)
+ .on_click(move |_, _window, cx| {
+ ActiveCall::global(cx)
+ .update(cx, |call, cx| call.hang_up(cx))
+ .detach_and_log_err(cx);
+ }),
+ )
+ .child(Divider::vertical().color(DividerColor::Border))
+ .into_any_element(),
+ );
+
if is_local && can_share_projects && !is_connecting_to_project {
children.push(
Button::new(
@@ -369,32 +387,14 @@ impl TitleBar {
);
}
- children.push(
- div()
- .pr_2()
- .child(
- IconButton::new("leave-call", ui::IconName::Exit)
- .style(ButtonStyle::Subtle)
- .tooltip(Tooltip::text("Leave call"))
- .icon_size(IconSize::Small)
- .on_click(move |_, _window, cx| {
- ActiveCall::global(cx)
- .update(cx, |call, cx| call.hang_up(cx))
- .detach_and_log_err(cx);
- }),
- )
- .child(Divider::vertical())
- .into_any_element(),
- );
-
if can_use_microphone {
children.push(
IconButton::new(
"mute-microphone",
if is_muted {
- ui::IconName::MicMute
+ IconName::MicMute
} else {
- ui::IconName::Mic
+ IconName::Mic
},
)
.tooltip(move |window, cx| {
@@ -429,9 +429,9 @@ impl TitleBar {
IconButton::new(
"mute-sound",
if is_deafened {
- ui::IconName::AudioOff
+ IconName::AudioOff
} else {
- ui::IconName::AudioOn
+ IconName::AudioOn
},
)
.style(ButtonStyle::Subtle)
@@ -462,7 +462,7 @@ impl TitleBar {
);
if can_use_microphone && screen_sharing_supported {
- let trigger = IconButton::new("screen-share", ui::IconName::Screen)
+ let trigger = IconButton::new("screen-share", IconName::Screen)
.style(ButtonStyle::Subtle)
.icon_size(IconSize::Small)
.toggle_state(is_screen_sharing)
@@ -498,7 +498,7 @@ impl TitleBar {
trigger.render(window, cx),
self.render_screen_list().into_any_element(),
)
- .style(SplitButtonStyle::Outlined)
+ .style(SplitButtonStyle::Transparent)
.into_any_element(),
);
}
@@ -513,11 +513,11 @@ impl TitleBar {
.with_handle(self.screen_share_popover_handle.clone())
.trigger(
ui::ButtonLike::new_rounded_right("screen-share-screen-list-trigger")
- .layer(ui::ElevationIndex::ModalSurface)
- .size(ui::ButtonSize::None)
.child(
- div()
- .px_1()
+ h_flex()
+ .mx_neg_0p5()
+ .h_full()
+ .justify_center()
.child(Icon::new(IconName::ChevronDownSmall).size(IconSize::XSmall)),
)
.toggle_state(self.screen_share_popover_handle.is_deployed()),
diff --git a/crates/ui/src/components/button/split_button.rs b/crates/ui/src/components/button/split_button.rs
index a7fa2106d127662c4f1498e41372780065649e56..14b9fd153cd5ad662467c75ff81700587667cee3 100644
--- a/crates/ui/src/components/button/split_button.rs
+++ b/crates/ui/src/components/button/split_button.rs
@@ -12,6 +12,7 @@ use super::ButtonLike;
pub enum SplitButtonStyle {
Filled,
Outlined,
+ Transparent,
}
/// /// A button with two parts: a primary action on the left and a secondary action on the right.
@@ -44,10 +45,17 @@ impl SplitButton {
impl RenderOnce for SplitButton {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
+ let is_filled_or_outlined = matches!(
+ self.style,
+ SplitButtonStyle::Filled | SplitButtonStyle::Outlined
+ );
+
h_flex()
.rounded_sm()
- .border_1()
- .border_color(cx.theme().colors().border.opacity(0.5))
+ .when(is_filled_or_outlined, |this| {
+ this.border_1()
+ .border_color(cx.theme().colors().border.opacity(0.8))
+ })
.child(div().flex_grow().child(self.left))
.child(
div()