diff --git a/crates/ely_app/src/shell/splits.rs b/crates/ely_app/src/shell/splits.rs index 2833540..20fe982 100644 --- a/crates/ely_app/src/shell/splits.rs +++ b/crates/ely_app/src/shell/splits.rs @@ -183,8 +183,12 @@ impl ElyShell { ) -> AnyElement { let active = tab.id() == &snapshot.active_tab_id; let tab_id = tab.id().clone(); + let close_tab_id = tab.id().clone(); let border = if active { colors::ACCENT } else { colors::HAIRLINE_STRONG }; - let title_color = if active { colors::INK } else { colors::INK_2 }; + let host = pane_host_label(tab); + let path = pane_path_label(tab); + let secure = pane_url_is_secure(tab); + let dot_color = if active { colors::ACCENT } else { colors::INK_4 }; div() .id(SharedString::from(format!("split-pane-{}", tab.id().as_str()))) @@ -197,38 +201,14 @@ impl ElyShell { .rounded(px(10.0)) .border_1() .border_color(rgb(border)) - .bg(rgba(colors::GLASS_2)) + .bg(rgb(0xffffff)) .cursor_pointer() - .hover(|style| style.bg(rgba(colors::GLASS_3))) + .hover(|style| style.opacity(0.98)) .active(|style| style.opacity(0.92)) .on_click(cx.listener(move |shell, _, window, cx| { shell.select_tab(&tab_id, window, cx); })) - .child( - div() - .h(px(30.0)) - .px(px(10.0)) - .gap(px(6.0)) - .flex() - .items_center() - .flex_shrink_0() - .child( - div() - .size(px(6.0)) - .rounded_full() - .bg(rgb(if active { colors::ACCENT } else { colors::INK_4 })), - ) - .child( - div() - .flex_1() - .min_w_0() - .truncate() - .text_size(px(12.0)) - .font_weight(gpui::FontWeight(500.0)) - .text_color(rgb(title_color)) - .child(tab.title().to_string()), - ), - ) + .child(self.render_split_pane_header(host, path, secure, dot_color, close_tab_id, cx)) .child(div().flex_1().min_h_0().overflow_hidden().child(if compact_canvas { render_compact_split_canvas(tab) } else { @@ -237,6 +217,74 @@ impl ElyShell { .into_any_element() } + fn render_split_pane_header( + &mut self, + host: String, + path: String, + secure: bool, + dot_color: u32, + close_tab_id: ely_domain::TabId, + cx: &mut Context, + ) -> AnyElement { + let lock_or_globe = if secure { IconName::Search } else { IconName::Globe }; + + div() + .h(px(30.0)) + .px(px(10.0)) + .gap(px(8.0)) + .flex() + .items_center() + .flex_shrink_0() + .border_b_1() + .border_color(rgb(colors::HAIRLINE)) + .bg(rgb(0xf6f4ef)) + .child( + div() + .size(px(8.0)) + .rounded_full() + .bg(rgb(dot_color)), + ) + .child( + div() + .text_color(rgb(colors::INK_3)) + .text_size(px(11.0)) + .child(lock_or_globe), + ) + .child( + div() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight(500.0)) + .text_color(rgb(colors::INK)) + .child(host), + ) + .child( + div() + .flex_1() + .min_w_0() + .truncate() + .text_size(px(11.0)) + .text_color(rgb(colors::INK_4)) + .child(path), + ) + .child( + div() + .id(SharedString::from(format!( + "split-pane-close-{}", + close_tab_id.as_str() + ))) + .text_color(rgb(colors::INK_4)) + .text_size(px(11.0)) + .cursor_pointer() + .hover(|style| style.text_color(rgb(colors::INK))) + .on_click(cx.listener(move |shell, _, window, cx| { + shell.select_tab(&close_tab_id, window, cx); + shell.close_active_tab(window, cx); + })) + .child(IconName::Close), + ) + .into_any_element() + } + fn render_split_controls( &mut self, active_axis: &SplitAxis, @@ -480,3 +528,24 @@ fn render_compact_split_canvas(tab: &BrowserTab) -> AnyElement { fn split_canvas_status(tab: &BrowserTab) -> String { if tab.url().as_str() == "ely://new-tab" { "Ready".to_string() } else { tab.display_url() } } + +fn pane_host_label(tab: &BrowserTab) -> String { + tab.url() + .host() + .map(|host| host.to_string()) + .unwrap_or_else(|| tab.title().to_string()) +} + +fn pane_path_label(tab: &BrowserTab) -> String { + let url = tab.url().as_str(); + let path_start = url.find("://").map(|prefix| prefix + 3).unwrap_or(0); + let from_path = &url[path_start..]; + match from_path.find('/') { + Some(slash) => from_path[slash..].to_string(), + None => String::new(), + } +} + +fn pane_url_is_secure(tab: &BrowserTab) -> bool { + tab.url().as_str().starts_with("https://") || tab.url().as_str().starts_with("ely://") +}