@@ -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()),
+ ),
)
}
}),
@@ -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(),
@@ -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<SshPrompt>,
}
+
impl SshPrompt {
pub fn new(connection_options: &SshConnectionOptions, cx: &mut ViewContext<Self>) -> 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<Self>) -> impl IntoElement {
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> 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<Self>) -> 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()))
}
}
@@ -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());
}),