ssh: Clean up title bar indicator icon (#19328)

Danilo Leal created

This PR cleans up the custom icon with indicator implementation in favor
of `IconWithIndicator`, which we already had. It seems like it isn't
super used still, but it's good to try to enforce some consistency
either way. I checked my changes against the REPL stuff (one instance
where its used) and everything's looking good so far. As far as SSH,
nothing has visually changed; we just have less code for this thing now.

<img width="800" alt="Screenshot 2024-10-17 at 2 15 47 AM"
src="https://github.com/user-attachments/assets/5c146757-501e-4242-b145-a576a8f289b5">

---

Release Notes:

- N/A

Change summary

crates/title_bar/src/title_bar.rs | 52 +++++++++-----------------------
crates/ui/src/components/icon.rs  |  7 +--
2 files changed, 18 insertions(+), 41 deletions(-)

Detailed changes

crates/title_bar/src/title_bar.rs 🔗

@@ -24,8 +24,8 @@ use smallvec::SmallVec;
 use std::sync::Arc;
 use theme::ActiveTheme;
 use ui::{
-    h_flex, prelude::*, Avatar, Button, ButtonLike, ButtonStyle, ContextMenu, Icon,
-    IconButtonShape, IconName, IconSize, Indicator, PopoverMenu, Tooltip,
+    h_flex, prelude::*, Avatar, Button, ButtonLike, ButtonStyle, ContextMenu, Icon, IconName,
+    IconSize, IconWithIndicator, Indicator, PopoverMenu, Tooltip,
 };
 use util::ResultExt;
 use vcs_menu::{BranchList, OpenRecent as ToggleVcsMenu};
@@ -281,8 +281,6 @@ impl TitleBar {
             }
         };
 
-        let indicator_border_color = cx.theme().colors().title_bar_background;
-
         let icon_color = match self.project.read(cx).ssh_connection_state(cx)? {
             remote::ConnectionState::Connecting => Color::Info,
             remote::ConnectionState::Connected => Color::Default,
@@ -293,42 +291,22 @@ impl TitleBar {
 
         let meta = SharedString::from(meta);
 
-        let indicator = h_flex()
-            // We're using the circle inside a circle approach because, otherwise, by using borders
-            // we'd get a very thin, leaking indicator color, which is not what we want.
-            .absolute()
-            .size_2p5()
-            .right_0()
-            .bottom_0()
-            .bg(indicator_border_color)
-            .size_2p5()
-            .rounded_full()
-            .items_center()
-            .justify_center()
-            .overflow_hidden()
-            .child(Indicator::dot().color(indicator_color));
-
         Some(
-            div()
-                .relative()
+            ButtonLike::new("ssh-server-icon")
                 .child(
-                    IconButton::new("ssh-server-icon", IconName::Server)
-                        .icon_size(IconSize::Small)
-                        .shape(IconButtonShape::Square)
-                        .icon_color(icon_color)
-                        .tooltip(move |cx| {
-                            Tooltip::with_meta(
-                                "Remote Project",
-                                Some(&OpenRemote),
-                                meta.clone(),
-                                cx,
-                            )
-                        })
-                        .on_click(|_, cx| {
-                            cx.dispatch_action(OpenRemote.boxed_clone());
-                        }),
+                    IconWithIndicator::new(
+                        Icon::new(IconName::Server).color(icon_color),
+                        Some(Indicator::dot().color(indicator_color)),
+                    )
+                    .indicator_border_color(Some(cx.theme().colors().title_bar_background))
+                    .into_any_element(),
                 )
-                .child(indicator)
+                .tooltip(move |cx| {
+                    Tooltip::with_meta("Remote Project", Some(&OpenRemote), meta.clone(), cx)
+                })
+                .on_click(|_, cx| {
+                    cx.dispatch_action(OpenRemote.boxed_clone());
+                })
                 .into_any_element(),
         )
     }

crates/ui/src/components/icon.rs 🔗

@@ -473,13 +473,12 @@ impl RenderOnce for IconWithIndicator {
                 this.child(
                     div()
                         .absolute()
-                        .w_2()
-                        .h_2()
-                        .border_1()
+                        .size_2p5()
+                        .border_2()
                         .border_color(indicator_border_color)
                         .rounded_full()
                         .bottom_neg_0p5()
-                        .right_neg_1()
+                        .right_neg_0p5()
                         .child(indicator),
                 )
             })