From f136ac55c10b3928e47f23c4585ae529ae7be464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Sat, 9 May 2026 18:08:42 -0400 Subject: [PATCH] Move expanded sidebar list out of render.rs render.rs was 525 lines because it carried both the shell orchestrator and every sidebar row helper. The expanded sidebar (favorites, pinned, spaces, tabs, archive sections plus the profile footer and the row helpers) now lives in chrome::sidebar, where panel/soft shadow tokens also moved. render.rs is back to a 150-line orchestrator that only composes wallpaper, sidebar, topbar, and content area. Behaviour preserved: render_tab_row stays available for tab_groups via pub(crate) on impl ElyShell, and all existing on_action listeners and keyboard captures remain wired in render_browser. --- crates/ely_app/src/shell/chrome/mod.rs | 2 + crates/ely_app/src/shell/chrome/sidebar.rs | 392 ++++++++++++++++++++ crates/ely_app/src/shell/render.rs | 396 +-------------------- 3 files changed, 406 insertions(+), 384 deletions(-) create mode 100644 crates/ely_app/src/shell/chrome/sidebar.rs diff --git a/crates/ely_app/src/shell/chrome/mod.rs b/crates/ely_app/src/shell/chrome/mod.rs index 2b1830f..8e6b73e 100644 --- a/crates/ely_app/src/shell/chrome/mod.rs +++ b/crates/ely_app/src/shell/chrome/mod.rs @@ -1,9 +1,11 @@ pub(crate) mod home; +pub(crate) mod sidebar; pub(crate) mod sidebar_header; pub(crate) mod topbar; pub(crate) mod wallpaper; pub(crate) use home::render_home_page; +pub(crate) use sidebar::{PANEL_BG, panel_shadow}; pub(crate) use sidebar_header::render_sidebar_header; pub(crate) use topbar::render_topbar; pub(crate) use wallpaper::{WallpaperTheme, render_wallpaper}; diff --git a/crates/ely_app/src/shell/chrome/sidebar.rs b/crates/ely_app/src/shell/chrome/sidebar.rs new file mode 100644 index 0000000..dcece13 --- /dev/null +++ b/crates/ely_app/src/shell/chrome/sidebar.rs @@ -0,0 +1,392 @@ +use ely_browser_core::BrowserSnapshot; +use ely_design_system::{colors, spacing}; +use ely_domain::{ArchivedTab, BrowserTab, Profile, Space}; +use gpui::{ + AnyElement, BoxShadow, Context, InteractiveElement, IntoElement, ParentElement, SharedString, + StatefulInteractiveElement, Styled, div, hsla, linear_color_stop, linear_gradient, point, + prelude::FluentBuilder, px, rgb, rgba, +}; +use gpui_component::{IconName, StyledExt, scroll::ScrollableElement}; + +use crate::shell::ElyShell; +use crate::shell::archive_labels::archive_detail_label; +use crate::shell::chrome::render_sidebar_header; + +impl ElyShell { + pub(crate) fn render_expanded_sidebar( + &mut self, + snapshot: &BrowserSnapshot, + sidebar_width: f32, + cx: &mut Context, + ) -> AnyElement { + div() + .w(px(sidebar_width)) + .h_full() + .flex() + .flex_col() + .rounded(px(spacing::RADIUS_CARD)) + .bg(rgba(PANEL_BG)) + .shadow(panel_shadow()) + .overflow_hidden() + .child(render_sidebar_header(snapshot, cx)) + .child( + div() + .flex_1() + .overflow_y_scrollbar() + .p(px(10.0)) + .flex() + .flex_col() + .gap(px(6.0)) + .child(section_label("FAVORITES")) + .children(snapshot.favorites.iter().map(|tab| { + self.render_favorite_row( + tab, + &snapshot.profiles, + tab.id() == &snapshot.active_tab_id, + cx, + ) + })) + .child(section_label("PINNED")) + .children(snapshot.pinned_tabs.iter().map(|tab| { + self.render_pinned_row( + tab, + &snapshot.profiles, + tab.id() == &snapshot.active_tab_id, + cx, + ) + })) + .child(section_label("SPACES")) + .children(snapshot.spaces.iter().map(|space| { + self.render_space_row( + space, + space.id() == &snapshot.active_space_id, + cx, + ) + })) + .child(section_label("TABS")) + .children(self.render_sidebar_tab_rows(snapshot, cx)) + .child(section_label("ARCHIVE")) + .children( + snapshot + .archived_tabs + .iter() + .rev() + .map(|archived_tab| { + self.render_archived_row(archived_tab, snapshot, cx) + }), + ), + ) + .child(self.render_sidebar_footer(snapshot)) + .into_any_element() + } + + fn render_sidebar_footer(&self, snapshot: &BrowserSnapshot) -> AnyElement { + div() + .px(px(14.0)) + .py(px(12.0)) + .flex() + .items_center() + .gap_2() + .flex_shrink_0() + .border_t_1() + .border_color(rgba(colors::DIVIDER)) + .child( + div() + .size(px(26.0)) + .rounded_full() + .bg(linear_gradient( + 135.0, + linear_color_stop(hsla(20.0 / 360.0, 0.6, 0.84, 1.0), 0.0), + linear_color_stop(hsla(15.0 / 360.0, 0.55, 0.53, 1.0), 1.0), + )) + .flex() + .items_center() + .justify_center() + .child( + div() + .text_size(px(10.0)) + .font_semibold() + .text_color(rgb(0xffffff)) + .child(profile_initial(&snapshot.active_profile_name)), + ), + ) + .child( + div() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight(500.0)) + .text_color(rgb(colors::INK_2)) + .child(snapshot.active_profile_name.clone()), + ) + .into_any_element() + } + + fn render_space_row( + &mut self, + space: &Space, + active: bool, + cx: &mut Context, + ) -> AnyElement { + let space_id = space.id().clone(); + let bg_color = if active { ACTIVE_NAV_BG } else { 0x00000000 }; + let text_color = if active { colors::INK } else { colors::INK_2 }; + + div() + .id(SharedString::from(format!("space-{}", space.id().as_str()))) + .rounded(px(spacing::RADIUS_NAV)) + .px(px(10.0)) + .py(px(7.0)) + .gap(px(10.0)) + .flex() + .items_center() + .cursor_pointer() + .hover(|style| style.bg(rgba(ACTIVE_NAV_BG))) + .active(|style| style.opacity(0.82)) + .bg(rgba(bg_color)) + .when(active, |el| el.shadow(soft_shadow())) + .on_click(cx.listener(move |shell, _, window, cx| { + shell.select_space(&space_id, window, cx); + })) + .child(render_workspace_tile(space)) + .child( + div() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight(500.0)) + .text_color(rgb(text_color)) + .child(space.name().to_string()), + ) + .into_any_element() + } + + fn render_favorite_row( + &mut self, + tab: &BrowserTab, + profiles: &[Profile], + active: bool, + cx: &mut Context, + ) -> AnyElement { + self.render_nav_row(tab, profiles, active, IconName::Star, colors::ACCENT, cx) + } + + fn render_pinned_row( + &mut self, + tab: &BrowserTab, + profiles: &[Profile], + active: bool, + cx: &mut Context, + ) -> AnyElement { + self.render_nav_row(tab, profiles, active, IconName::Asterisk, colors::INK_3, cx) + } + + fn render_nav_row( + &mut self, + tab: &BrowserTab, + _profiles: &[Profile], + active: bool, + icon: IconName, + icon_color: u32, + cx: &mut Context, + ) -> AnyElement { + let tab_id = tab.id().clone(); + let bg_color = if active { ACTIVE_NAV_BG } else { 0x00000000 }; + let text_color = if active { colors::INK } else { colors::INK_2 }; + + div() + .id(SharedString::from(format!("nav-{}", tab.id().as_str()))) + .rounded(px(spacing::RADIUS_NAV)) + .px(px(10.0)) + .py(px(7.0)) + .gap(px(10.0)) + .flex() + .items_center() + .cursor_pointer() + .hover(|style| style.bg(rgba(ACTIVE_NAV_BG))) + .active(|style| style.opacity(0.82)) + .bg(rgba(bg_color)) + .when(active, |el| el.shadow(soft_shadow())) + .on_click(cx.listener(move |shell, _, window, cx| { + shell.select_tab(&tab_id, window, cx); + })) + .child(div().text_color(rgb(icon_color)).child(icon)) + .child( + div() + .min_w_0() + .overflow_hidden() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight(500.0)) + .text_color(rgb(text_color)) + .child(tab.title().to_string()), + ) + .into_any_element() + } + + pub(crate) fn render_tab_row( + &mut self, + tab: &BrowserTab, + active: bool, + cx: &mut Context, + ) -> AnyElement { + let tab_id = tab.id().clone(); + let bg_color = if active { ACTIVE_NAV_BG } else { 0x00000000 }; + let text_color = if active { colors::INK } else { colors::INK_2 }; + + div() + .id(SharedString::from(tab.id().as_str().to_string())) + .rounded(px(spacing::RADIUS_NAV)) + .px(px(10.0)) + .py(px(7.0)) + .gap(px(6.0)) + .flex() + .flex_col() + .cursor_pointer() + .hover(|style| style.bg(rgba(ACTIVE_NAV_BG))) + .active(|style| style.opacity(0.82)) + .bg(rgba(bg_color)) + .when(active, |el| el.shadow(soft_shadow())) + .on_click(cx.listener(move |shell, _, window, cx| { + shell.select_tab(&tab_id, window, cx); + })) + .child( + div() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight(500.0)) + .text_color(rgb(text_color)) + .overflow_hidden() + .child(tab.title().to_string()), + ) + .child( + div() + .text_size(px(11.0)) + .text_color(rgb(colors::INK_4)) + .overflow_hidden() + .child(tab.display_url()), + ) + .into_any_element() + } + + fn render_archived_row( + &mut self, + archived_tab: &ArchivedTab, + snapshot: &BrowserSnapshot, + cx: &mut Context, + ) -> AnyElement { + let tab = archived_tab.tab(); + let tab_id = tab.id().clone(); + let detail = archive_detail_label(archived_tab, &snapshot.spaces, &snapshot.profiles); + + div() + .id(SharedString::from(format!("archived-{}", tab.id().as_str()))) + .rounded(px(spacing::RADIUS_NAV)) + .px(px(10.0)) + .py(px(7.0)) + .gap(px(10.0)) + .flex() + .items_center() + .cursor_pointer() + .hover(|style| style.bg(rgba(ACTIVE_NAV_BG))) + .active(|style| style.opacity(0.82)) + .on_click(cx.listener(move |shell, _, window, cx| { + shell.restore_archived_tab(&tab_id, window, cx); + })) + .child(div().text_color(rgb(colors::INK_4)).child(IconName::Undo2)) + .child( + div() + .min_w_0() + .flex() + .flex_col() + .gap_1() + .child( + div() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight(500.0)) + .text_color(rgb(colors::INK_2)) + .overflow_hidden() + .child(tab.title().to_string()), + ) + .child( + div() + .text_size(px(11.0)) + .text_color(rgb(colors::INK_4)) + .overflow_hidden() + .child(detail), + ), + ) + .into_any_element() + } +} + +fn profile_initial(name: &str) -> String { + name.chars() + .next() + .unwrap_or('P') + .to_uppercase() + .to_string() +} + +fn render_workspace_tile(space: &Space) -> impl IntoElement { + div() + .size(px(32.0)) + .rounded(px(9.0)) + .bg(linear_gradient( + 135.0, + linear_color_stop(hsla(0., 0., 1., 1.0), 0.0), + linear_color_stop(hsla(20.0 / 360.0, 0.6, 0.94, 1.0), 1.0), + )) + .shadow(soft_shadow()) + .flex() + .items_center() + .justify_center() + .child( + div() + .text_size(px(14.0)) + .text_color(rgb(colors::ACCENT)) + .child(space.icon().to_string()), + ) +} + +fn section_label(label: &'static str) -> impl IntoElement { + div() + .pt(px(8.0)) + .pb(px(4.0)) + .px(px(10.0)) + .text_size(px(10.5)) + .font_weight(gpui::FontWeight(500.0)) + .text_color(rgb(colors::INK_4)) + .child(label) +} + +pub(crate) const ACTIVE_NAV_BG: u32 = 0xffffffd9; +pub(crate) const PANEL_BG: u32 = 0xffffffe0; + +pub(crate) fn panel_shadow() -> Vec { + vec![ + BoxShadow { + color: hsla(25.0 / 360.0, 0.33, 0.12, 0.30), + offset: point(px(0.), px(20.)), + blur_radius: px(50.), + spread_radius: px(-15.), + }, + BoxShadow { + color: hsla(0., 0., 1., 0.5), + offset: point(px(0.), px(0.)), + blur_radius: px(0.), + spread_radius: px(1.), + }, + ] +} + +pub(crate) fn soft_shadow() -> Vec { + vec![ + BoxShadow { + color: hsla(0., 0., 1., 0.7), + offset: point(px(0.), px(1.)), + blur_radius: px(0.), + spread_radius: px(0.), + }, + BoxShadow { + color: hsla(25.0 / 360.0, 0.33, 0.12, 0.08), + offset: point(px(0.), px(0.)), + blur_radius: px(0.), + spread_radius: px(1.), + }, + ] +} diff --git a/crates/ely_app/src/shell/render.rs b/crates/ely_app/src/shell/render.rs index eb534e4..328dd1c 100644 --- a/crates/ely_app/src/shell/render.rs +++ b/crates/ely_app/src/shell/render.rs @@ -1,19 +1,17 @@ use ely_browser_core::BrowserSnapshot; use ely_design_system::{colors, spacing}; -use ely_domain::{ArchivedTab, BrowserTab, Profile, Space}; +use ely_domain::BrowserTab; use gpui::{ - AnyElement, BoxShadow, Context, InteractiveElement, IntoElement, ParentElement, Render, - SharedString, StatefulInteractiveElement, Styled, Window, div, hsla, linear_gradient, point, - linear_color_stop, prelude::FluentBuilder, px, rgb, rgba, + AnyElement, Context, InteractiveElement, IntoElement, ParentElement, Render, Styled, Window, + div, px, rgb, rgba, }; -use gpui_component::{IconName, StyledExt, scroll::ScrollableElement}; use super::chrome::{ - WallpaperTheme, render_sidebar_header, render_topbar as render_topbar_chrome, + PANEL_BG, WallpaperTheme, panel_shadow, render_topbar as render_topbar_chrome, render_wallpaper, }; use super::sidebar::collapsed_sidebar_active; -use super::{ElyShell, ShellState, archive_labels::archive_detail_label}; +use super::{ElyShell, ShellState}; impl Render for ElyShell { fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { @@ -74,12 +72,8 @@ impl ElyShell { .p(px(spacing::SHELL_INSET)) .gap(px(spacing::SIDEBAR_MAIN_GAP)) .flex() - .child( - self.render_sidebar(&snapshot, sidebar_width, sidebar_collapsed, cx), - ) - .child( - self.render_main_pane(&snapshot, &active_tab, sidebar_collapsed, cx), - ), + .child(self.render_sidebar(&snapshot, sidebar_width, sidebar_collapsed, cx)) + .child(self.render_main_pane(&snapshot, &active_tab, sidebar_collapsed, cx)), ) .into_any_element() } @@ -121,345 +115,8 @@ impl ElyShell { if sidebar_collapsed { return self.render_compact_sidebar(snapshot, sidebar_width, cx); } - - div() - .w(px(sidebar_width)) - .h_full() - .flex() - .flex_col() - .rounded(px(spacing::RADIUS_CARD)) - .bg(rgba(PANEL_BG)) - .shadow(panel_shadow()) - .overflow_hidden() - .child(render_sidebar_header(snapshot, cx)) - .child( - div() - .flex_1() - .overflow_y_scrollbar() - .p(px(10.0)) - .flex() - .flex_col() - .gap(px(6.0)) - .child(section_label("FAVORITES")) - .children(snapshot.favorites.iter().map(|tab| { - self.render_favorite_row( - tab, - &snapshot.profiles, - tab.id() == &snapshot.active_tab_id, - cx, - ) - })) - .child(section_label("PINNED")) - .children(snapshot.pinned_tabs.iter().map(|tab| { - self.render_pinned_row( - tab, - &snapshot.profiles, - tab.id() == &snapshot.active_tab_id, - cx, - ) - })) - .child(section_label("SPACES")) - .children(snapshot.spaces.iter().map(|space| { - self.render_space_row( - space, - space.id() == &snapshot.active_space_id, - cx, - ) - })) - .child(section_label("TABS")) - .children(self.render_sidebar_tab_rows(snapshot, cx)) - .child(section_label("ARCHIVE")) - .children( - snapshot - .archived_tabs - .iter() - .rev() - .map(|archived_tab| { - self.render_archived_row(archived_tab, snapshot, cx) - }), - ), - ) - .child(self.render_sidebar_footer(snapshot)) - .into_any_element() + self.render_expanded_sidebar(snapshot, sidebar_width, cx) } - - fn render_sidebar_footer(&self, snapshot: &BrowserSnapshot) -> AnyElement { - div() - .px(px(14.0)) - .py(px(12.0)) - .flex() - .items_center() - .gap_2() - .flex_shrink_0() - .border_t_1() - .border_color(rgba(colors::DIVIDER)) - .child( - div() - .size(px(26.0)) - .rounded_full() - .bg(linear_gradient( - 135.0, - linear_color_stop(hsla(20.0 / 360.0, 0.6, 0.84, 1.0), 0.0), - linear_color_stop(hsla(15.0 / 360.0, 0.55, 0.53, 1.0), 1.0), - )) - .flex() - .items_center() - .justify_center() - .child( - div() - .text_size(px(10.0)) - .font_semibold() - .text_color(rgb(0xffffff)) - .child( - snapshot - .active_profile_name - .chars() - .next() - .unwrap_or('P') - .to_uppercase() - .to_string(), - ), - ), - ) - .child( - div() - .text_size(px(13.0)) - .font_weight(gpui::FontWeight(500.0)) - .text_color(rgb(colors::INK_2)) - .child(snapshot.active_profile_name.clone()), - ) - .into_any_element() - } - - fn render_space_row( - &mut self, - space: &Space, - active: bool, - cx: &mut Context, - ) -> AnyElement { - let space_id = space.id().clone(); - let bg_color = if active { ACTIVE_NAV_BG } else { 0x00000000 }; - let text_color = if active { colors::INK } else { colors::INK_2 }; - - div() - .id(SharedString::from(format!("space-{}", space.id().as_str()))) - .rounded(px(spacing::RADIUS_NAV)) - .px(px(10.0)) - .py(px(7.0)) - .gap(px(10.0)) - .flex() - .items_center() - .cursor_pointer() - .hover(|style| style.bg(rgba(ACTIVE_NAV_BG))) - .active(|style| style.opacity(0.82)) - .bg(rgba(bg_color)) - .when(active, |el| el.shadow(soft_shadow())) - .on_click(cx.listener(move |shell, _, window, cx| { - shell.select_space(&space_id, window, cx); - })) - .child(render_workspace_tile(space)) - .child( - div() - .text_size(px(13.0)) - .font_weight(gpui::FontWeight(500.0)) - .text_color(rgb(text_color)) - .child(space.name().to_string()), - ) - .into_any_element() - } - - fn render_favorite_row( - &mut self, - tab: &BrowserTab, - profiles: &[Profile], - active: bool, - cx: &mut Context, - ) -> AnyElement { - self.render_nav_row(tab, profiles, active, IconName::Star, colors::ACCENT, cx) - } - - fn render_pinned_row( - &mut self, - tab: &BrowserTab, - profiles: &[Profile], - active: bool, - cx: &mut Context, - ) -> AnyElement { - self.render_nav_row(tab, profiles, active, IconName::Asterisk, colors::INK_3, cx) - } - - fn render_nav_row( - &mut self, - tab: &BrowserTab, - _profiles: &[Profile], - active: bool, - icon: IconName, - icon_color: u32, - cx: &mut Context, - ) -> AnyElement { - let tab_id = tab.id().clone(); - let bg_color = if active { ACTIVE_NAV_BG } else { 0x00000000 }; - let text_color = if active { colors::INK } else { colors::INK_2 }; - - div() - .id(SharedString::from(format!("nav-{}", tab.id().as_str()))) - .rounded(px(spacing::RADIUS_NAV)) - .px(px(10.0)) - .py(px(7.0)) - .gap(px(10.0)) - .flex() - .items_center() - .cursor_pointer() - .hover(|style| style.bg(rgba(ACTIVE_NAV_BG))) - .active(|style| style.opacity(0.82)) - .bg(rgba(bg_color)) - .when(active, |el| el.shadow(soft_shadow())) - .on_click(cx.listener(move |shell, _, window, cx| { - shell.select_tab(&tab_id, window, cx); - })) - .child(div().text_color(rgb(icon_color)).child(icon)) - .child( - div() - .min_w_0() - .overflow_hidden() - .text_size(px(13.0)) - .font_weight(gpui::FontWeight(500.0)) - .text_color(rgb(text_color)) - .child(tab.title().to_string()), - ) - .into_any_element() - } - - pub(super) fn render_tab_row( - &mut self, - tab: &BrowserTab, - active: bool, - cx: &mut Context, - ) -> AnyElement { - let tab_id = tab.id().clone(); - let bg_color = if active { ACTIVE_NAV_BG } else { 0x00000000 }; - let text_color = if active { colors::INK } else { colors::INK_2 }; - - div() - .id(SharedString::from(tab.id().as_str().to_string())) - .rounded(px(spacing::RADIUS_NAV)) - .px(px(10.0)) - .py(px(7.0)) - .gap(px(6.0)) - .flex() - .flex_col() - .cursor_pointer() - .hover(|style| style.bg(rgba(ACTIVE_NAV_BG))) - .active(|style| style.opacity(0.82)) - .bg(rgba(bg_color)) - .when(active, |el| el.shadow(soft_shadow())) - .on_click(cx.listener(move |shell, _, window, cx| { - shell.select_tab(&tab_id, window, cx); - })) - .child( - div() - .text_size(px(13.0)) - .font_weight(gpui::FontWeight(500.0)) - .text_color(rgb(text_color)) - .overflow_hidden() - .child(tab.title().to_string()), - ) - .child( - div() - .text_size(px(11.0)) - .text_color(rgb(colors::INK_4)) - .overflow_hidden() - .child(tab.display_url()), - ) - .into_any_element() - } - - fn render_archived_row( - &mut self, - archived_tab: &ArchivedTab, - snapshot: &BrowserSnapshot, - cx: &mut Context, - ) -> AnyElement { - let tab = archived_tab.tab(); - let tab_id = tab.id().clone(); - let detail = archive_detail_label(archived_tab, &snapshot.spaces, &snapshot.profiles); - - div() - .id(SharedString::from(format!("archived-{}", tab.id().as_str()))) - .rounded(px(spacing::RADIUS_NAV)) - .px(px(10.0)) - .py(px(7.0)) - .gap(px(10.0)) - .flex() - .items_center() - .cursor_pointer() - .hover(|style| style.bg(rgba(ACTIVE_NAV_BG))) - .active(|style| style.opacity(0.82)) - .on_click(cx.listener(move |shell, _, window, cx| { - shell.restore_archived_tab(&tab_id, window, cx); - })) - .child(div().text_color(rgb(colors::INK_4)).child(IconName::Undo2)) - .child( - div() - .min_w_0() - .flex() - .flex_col() - .gap_1() - .child( - div() - .text_size(px(13.0)) - .font_weight(gpui::FontWeight(500.0)) - .text_color(rgb(colors::INK_2)) - .overflow_hidden() - .child(tab.title().to_string()), - ) - .child( - div() - .text_size(px(11.0)) - .text_color(rgb(colors::INK_4)) - .overflow_hidden() - .child(detail), - ), - ) - .into_any_element() - } -} - -const ACTIVE_NAV_BG: u32 = 0xffffffd9; -const PANEL_BG: u32 = 0xffffffe0; - -fn panel_shadow() -> Vec { - vec![ - BoxShadow { - color: hsla(25.0 / 360.0, 0.33, 0.12, 0.30), - offset: point(px(0.), px(20.)), - blur_radius: px(50.), - spread_radius: px(-15.), - }, - BoxShadow { - color: hsla(0., 0., 1., 0.5), - offset: point(px(0.), px(0.)), - blur_radius: px(0.), - spread_radius: px(1.), - }, - ] -} - -fn soft_shadow() -> Vec { - vec![ - BoxShadow { - color: hsla(0., 0., 1., 0.7), - offset: point(px(0.), px(1.)), - blur_radius: px(0.), - spread_radius: px(0.), - }, - BoxShadow { - color: hsla(25.0 / 360.0, 0.33, 0.12, 0.08), - offset: point(px(0.), px(0.)), - blur_radius: px(0.), - spread_radius: px(1.), - }, - ] } fn render_error(message: String) -> AnyElement { @@ -474,38 +131,6 @@ fn render_error(message: String) -> AnyElement { .into_any_element() } -fn section_label(label: &'static str) -> impl IntoElement { - div() - .pt(px(8.0)) - .pb(px(4.0)) - .px(px(10.0)) - .text_size(px(10.5)) - .font_weight(gpui::FontWeight(500.0)) - .text_color(rgb(colors::INK_4)) - .child(label) -} - -fn render_workspace_tile(space: &Space) -> impl IntoElement { - div() - .size(px(32.0)) - .rounded(px(9.0)) - .bg(linear_gradient( - 135.0, - linear_color_stop(hsla(0., 0., 1., 1.0), 0.0), - linear_color_stop(hsla(20.0 / 360.0, 0.6, 0.94, 1.0), 1.0), - )) - .shadow(soft_shadow()) - .flex() - .items_center() - .justify_center() - .child( - div() - .text_size(px(14.0)) - .text_color(rgb(colors::ACCENT)) - .child(space.icon().to_string()), - ) -} - fn active_sidebar_width(snapshot: &BrowserSnapshot) -> Result { let Some(active_space) = snapshot.spaces.iter().find(|space| space.id() == &snapshot.active_space_id) @@ -516,7 +141,10 @@ fn active_sidebar_width(snapshot: &BrowserSnapshot) -> Result { Ok(f32::from(active_space.sidebar_width_px())) } -pub(super) fn tab_profile_label(tab: &BrowserTab, profiles: &[Profile]) -> String { +pub(super) fn tab_profile_label( + tab: &BrowserTab, + profiles: &[ely_domain::Profile], +) -> String { profiles .iter() .find(|profile| profile.id() == tab.profile_id())