diff --git a/crates/recent_projects/src/dev_servers.rs b/crates/recent_projects/src/dev_servers.rs index fa1d511791..6171489872 100644 --- a/crates/recent_projects/src/dev_servers.rs +++ b/crates/recent_projects/src/dev_servers.rs @@ -556,23 +556,28 @@ impl DevServerProjects { .w_full() .border_l_1() .border_color(cx.theme().colors().border_variant) - .my_1() + .mb_1() .mx_1p5() - .py_0p5() - .px_3() + .pl_2() .child( List::new() .empty_message("No projects.") .children(ssh_connection.projects.iter().enumerate().map(|(pix, p)| { - self.render_ssh_project(ix, &ssh_connection, pix, p, cx) + v_flex().gap_0p5().child(self.render_ssh_project( + ix, + &ssh_connection, + pix, + p, + cx, + )) })) .child( - h_flex().child( + h_flex().mt_1().pl_1().child( Button::new("new-remote_project", "Open Folder…") - .icon(IconName::Plus) .size(ButtonSize::Default) - .style(ButtonStyle::Filled) .layer(ElevationIndex::ModalSurface) + .icon(IconName::Plus) + .icon_color(Color::Muted) .icon_position(IconPosition::Start) .on_click(cx.listener(move |this, _, cx| { this.create_ssh_project(ix, ssh_connection.clone(), cx); @@ -593,9 +598,15 @@ impl DevServerProjects { ) -> impl IntoElement { let project = project.clone(); let server = server.clone(); + ListItem::new(("remote-project", ix)) + .inset(true) .spacing(ui::ListItemSpacing::Sparse) - .start_slot(Icon::new(IconName::Folder).color(Color::Muted)) + .start_slot( + Icon::new(IconName::Folder) + .color(Color::Muted) + .size(IconSize::Small), + ) .child(Label::new(project.paths.join(", "))) .on_click(cx.listener(move |this, _, cx| { let Some(app_state) = this @@ -635,7 +646,7 @@ impl DevServerProjects { .on_click( cx.listener(move |this, _, cx| this.delete_ssh_project(server_ix, ix, cx)), ) - .tooltip(|cx| Tooltip::text("Delete remote project", cx)) + .tooltip(|cx| Tooltip::text("Delete Remote Project", cx)) .into_any_element(), )) } @@ -709,6 +720,7 @@ impl DevServerProjects { }) }); let theme = cx.theme(); + v_flex() .id("create-dev-server") .overflow_hidden() @@ -763,6 +775,7 @@ impl DevServerProjects { .child( h_flex() .bg(theme.colors().editor_background) + .rounded_b_md() .w_full() .map(|this| { if let Some(ssh_prompt) = ssh_prompt { @@ -773,9 +786,8 @@ impl DevServerProjects { h_flex() .p_2() .w_full() - .content_center() - .gap_2() - .child(h_flex().w_full()) + .justify_center() + .gap_1p5() .child( div().p_1().rounded_lg().bg(color).with_animation( "pulse-ssh-waiting-for-connection", @@ -788,8 +800,7 @@ impl DevServerProjects { .child( Label::new("Waiting for connection…") .size(LabelSize::Small), - ) - .child(h_flex().w_full()), + ), ) } }), diff --git a/crates/recent_projects/src/recent_projects.rs b/crates/recent_projects/src/recent_projects.rs index f73e7069d4..2285ed6287 100644 --- a/crates/recent_projects/src/recent_projects.rs +++ b/crates/recent_projects/src/recent_projects.rs @@ -566,7 +566,7 @@ impl PickerDelegate for RecentProjectsDelegate { .border_t_1() .py_2() .pr_2() - .border_color(cx.theme().colors().border) + .border_color(cx.theme().colors().border_variant) .justify_end() .gap_4() .child( @@ -574,7 +574,7 @@ impl PickerDelegate for RecentProjectsDelegate { .when_some(KeyBinding::for_action(&OpenRemote, cx), |button, key| { button.child(key) }) - .child(Label::new("Open remote folder…").color(Color::Muted)) + .child(Label::new("Open Remote Folder…").color(Color::Muted)) .on_click(|_, cx| cx.dispatch_action(OpenRemote.boxed_clone())), ) .child( @@ -583,7 +583,7 @@ impl PickerDelegate for RecentProjectsDelegate { KeyBinding::for_action(&workspace::Open, cx), |button, key| button.child(key), ) - .child(Label::new("Open local folder…").color(Color::Muted)) + .child(Label::new("Open Local Folder…").color(Color::Muted)) .on_click(|_, cx| cx.dispatch_action(workspace::Open.boxed_clone())), ) .into_any(), diff --git a/crates/recent_projects/src/ssh_connections.rs b/crates/recent_projects/src/ssh_connections.rs index 5862d48e81..2e41d56468 100644 --- a/crates/recent_projects/src/ssh_connections.rs +++ b/crates/recent_projects/src/ssh_connections.rs @@ -16,9 +16,9 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use settings::{Settings, SettingsSources}; use ui::{ - div, h_flex, v_flex, ActiveTheme, ButtonCommon, Clickable, Color, FluentBuilder as _, Icon, - IconButton, IconName, IconSize, InteractiveElement, IntoElement, Label, LabelCommon, Styled, - StyledExt as _, Tooltip, ViewContext, VisualContext, WindowContext, + div, h_flex, prelude::*, v_flex, ActiveTheme, ButtonCommon, Clickable, Color, Icon, IconButton, + IconName, IconSize, InteractiveElement, IntoElement, Label, LabelCommon, Styled, Tooltip, + ViewContext, VisualContext, WindowContext, }; use workspace::{AppState, ModalView, Workspace}; @@ -84,6 +84,7 @@ pub struct SshPrompt { pub struct SshConnectionModal { pub(crate) prompt: View, } + impl SshPrompt { pub fn new(connection_options: &SshConnectionOptions, cx: &mut ViewContext) -> Self { let connection_string = connection_options.connection_string().into(); @@ -136,57 +137,70 @@ impl SshPrompt { } impl Render for SshPrompt { - fn render(&mut self, _: &mut ViewContext) -> impl IntoElement { + fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { + let cx = cx.window_context(); + let theme = cx.theme(); v_flex() - .w_full() .key_context("PasswordPrompt") - .justify_start() + .size_full() + .justify_center() .child( - v_flex() - .p_4() - .size_full() - .child( - h_flex() - .gap_2() - .justify_between() - .child(h_flex().w_full()) - .child(if self.error_message.is_some() { - Icon::new(IconName::XCircle) - .size(IconSize::Medium) - .color(Color::Error) - .into_any_element() - } else { - Icon::new(IconName::ArrowCircle) - .size(IconSize::Medium) - .with_animation( - "arrow-circle", - Animation::new(Duration::from_secs(2)).repeat(), - |icon, delta| { - icon.transform(Transformation::rotate(percentage( - delta, - ))) - }, - ) - .into_any_element() - }) - .child(Label::new(format!( - "Connecting to {}…", - self.connection_string - ))) - .child(h_flex().w_full()), - ) - .when_some(self.error_message.as_ref(), |el, error| { - el.child(Label::new(error.clone())) + h_flex() + .py_2() + .px_4() + .justify_center() + .child(if self.error_message.is_some() { + Icon::new(IconName::XCircle) + .size(IconSize::Medium) + .color(Color::Error) + .into_any_element() + } else { + Icon::new(IconName::ArrowCircle) + .size(IconSize::Medium) + .with_animation( + "arrow-circle", + Animation::new(Duration::from_secs(2)).repeat(), + |icon, delta| { + icon.transform(Transformation::rotate(percentage(delta))) + }, + ) + .into_any_element() }) - .when( - self.error_message.is_none() && self.status_message.is_some(), - |el| el.child(Label::new(self.status_message.clone().unwrap())), + .child( + div() + .ml_1() + .child(Label::new("SSH Connection").size(LabelSize::Small)), ) - .when_some(self.prompt.as_ref(), |el, prompt| { - el.child(Label::new(prompt.0.clone())) - .child(self.editor.clone()) - }), + .child( + div() + .when_some(self.error_message.as_ref(), |el, error| { + el.child(Label::new(format!("-{}", error)).size(LabelSize::Small)) + }) + .when( + self.error_message.is_none() && self.status_message.is_some(), + |el| { + el.child( + Label::new(format!( + "-{}", + self.status_message.clone().unwrap() + )) + .size(LabelSize::Small), + ) + }, + ), + ), ) + .child(div().when_some(self.prompt.as_ref(), |el, prompt| { + el.child( + h_flex() + .p_4() + .border_t_1() + .border_color(theme.colors().border_variant) + .font_buffer(cx) + .child(Label::new(prompt.0.clone())) + .child(self.editor.clone()), + ) + })) } } @@ -210,39 +224,54 @@ impl Render for SshConnectionModal { fn render(&mut self, cx: &mut ui::ViewContext) -> impl ui::IntoElement { let connection_string = self.prompt.read(cx).connection_string.clone(); let theme = cx.theme(); - let header_color = theme.colors().element_background; - let body_color = theme.colors().background; + let mut header_color = cx.theme().colors().text; + header_color.fade_out(0.96); + let body_color = theme.colors().editor_background; + v_flex() .elevation_3(cx) .on_action(cx.listener(Self::dismiss)) .on_action(cx.listener(Self::confirm)) - .w(px(400.)) + .w(px(500.)) + .border_1() + .border_color(theme.colors().border) .child( h_flex() + .relative() .p_1() + .rounded_t_md() .border_b_1() .border_color(theme.colors().border) .bg(header_color) .justify_between() .child( - IconButton::new("ssh-connection-cancel", IconName::ArrowLeft) - .icon_size(IconSize::XSmall) - .on_click(|_, cx| cx.dispatch_action(menu::Cancel.boxed_clone())) - .tooltip(|cx| Tooltip::for_action("Back", &menu::Cancel, cx)), + div().absolute().left_0p5().top_0p5().child( + IconButton::new("ssh-connection-cancel", IconName::ArrowLeft) + .icon_size(IconSize::XSmall) + .on_click(|_, cx| cx.dispatch_action(menu::Cancel.boxed_clone())) + .tooltip(|cx| Tooltip::for_action("Back", &menu::Cancel, cx)), + ), ) .child( h_flex() + .w_full() .gap_2() + .justify_center() .child(Icon::new(IconName::Server).size(IconSize::XSmall)) .child( Label::new(connection_string) .size(ui::LabelSize::Small) .single_line(), ), - ) - .child(div()), + ), + ) + .child( + h_flex() + .rounded_b_md() + .bg(body_color) + .w_full() + .child(self.prompt.clone()), ) - .child(h_flex().bg(body_color).w_full().child(self.prompt.clone())) } } diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs index da0179fd64..6fda4d594f 100644 --- a/crates/title_bar/src/title_bar.rs +++ b/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, IconName, - Indicator, PopoverMenu, Tooltip, + h_flex, prelude::*, Avatar, Button, ButtonLike, ButtonStyle, ContextMenu, Icon, + IconButtonShape, IconName, IconSize, Indicator, PopoverMenu, Tooltip, }; use util::ResultExt; use vcs_menu::{BranchList, OpenRecent as ToggleVcsMenu}; @@ -274,18 +274,19 @@ impl TitleBar { }; let indicator = div() .absolute() - .w_1_4() - .h_1_4() + .size_1p5() .right_0p5() .bottom_0p5() - .p_1() - .rounded_2xl() + .rounded_full() .bg(indicator_color.color(cx)); Some( div() + .relative() .child( IconButton::new("ssh-server-icon", IconName::Server) + .icon_size(IconSize::Small) + .shape(IconButtonShape::Square) .tooltip(move |cx| { Tooltip::with_meta( "Remote Project", @@ -294,7 +295,6 @@ impl TitleBar { cx, ) }) - .shape(ui::IconButtonShape::Square) .on_click(|_, cx| { cx.dispatch_action(OpenRemote.boxed_clone()); }),