Skip to content

Commit af9a595

Browse files
authored
ssh: Add tweaks to the UI (#18817)
Follow up to #18727 --- Release Notes: - N/A
1 parent 3f2de17 commit af9a595

File tree

4 files changed

+122
-82
lines changed

4 files changed

+122
-82
lines changed

crates/recent_projects/src/dev_servers.rs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -556,23 +556,28 @@ impl DevServerProjects {
556556
.w_full()
557557
.border_l_1()
558558
.border_color(cx.theme().colors().border_variant)
559-
.my_1()
559+
.mb_1()
560560
.mx_1p5()
561-
.py_0p5()
562-
.px_3()
561+
.pl_2()
563562
.child(
564563
List::new()
565564
.empty_message("No projects.")
566565
.children(ssh_connection.projects.iter().enumerate().map(|(pix, p)| {
567-
self.render_ssh_project(ix, &ssh_connection, pix, p, cx)
566+
v_flex().gap_0p5().child(self.render_ssh_project(
567+
ix,
568+
&ssh_connection,
569+
pix,
570+
p,
571+
cx,
572+
))
568573
}))
569574
.child(
570-
h_flex().child(
575+
h_flex().mt_1().pl_1().child(
571576
Button::new("new-remote_project", "Open Folder…")
572-
.icon(IconName::Plus)
573577
.size(ButtonSize::Default)
574-
.style(ButtonStyle::Filled)
575578
.layer(ElevationIndex::ModalSurface)
579+
.icon(IconName::Plus)
580+
.icon_color(Color::Muted)
576581
.icon_position(IconPosition::Start)
577582
.on_click(cx.listener(move |this, _, cx| {
578583
this.create_ssh_project(ix, ssh_connection.clone(), cx);
@@ -593,9 +598,15 @@ impl DevServerProjects {
593598
) -> impl IntoElement {
594599
let project = project.clone();
595600
let server = server.clone();
601+
596602
ListItem::new(("remote-project", ix))
603+
.inset(true)
597604
.spacing(ui::ListItemSpacing::Sparse)
598-
.start_slot(Icon::new(IconName::Folder).color(Color::Muted))
605+
.start_slot(
606+
Icon::new(IconName::Folder)
607+
.color(Color::Muted)
608+
.size(IconSize::Small),
609+
)
599610
.child(Label::new(project.paths.join(", ")))
600611
.on_click(cx.listener(move |this, _, cx| {
601612
let Some(app_state) = this
@@ -635,7 +646,7 @@ impl DevServerProjects {
635646
.on_click(
636647
cx.listener(move |this, _, cx| this.delete_ssh_project(server_ix, ix, cx)),
637648
)
638-
.tooltip(|cx| Tooltip::text("Delete remote project", cx))
649+
.tooltip(|cx| Tooltip::text("Delete Remote Project", cx))
639650
.into_any_element(),
640651
))
641652
}
@@ -709,6 +720,7 @@ impl DevServerProjects {
709720
})
710721
});
711722
let theme = cx.theme();
723+
712724
v_flex()
713725
.id("create-dev-server")
714726
.overflow_hidden()
@@ -763,6 +775,7 @@ impl DevServerProjects {
763775
.child(
764776
h_flex()
765777
.bg(theme.colors().editor_background)
778+
.rounded_b_md()
766779
.w_full()
767780
.map(|this| {
768781
if let Some(ssh_prompt) = ssh_prompt {
@@ -773,9 +786,8 @@ impl DevServerProjects {
773786
h_flex()
774787
.p_2()
775788
.w_full()
776-
.content_center()
777-
.gap_2()
778-
.child(h_flex().w_full())
789+
.justify_center()
790+
.gap_1p5()
779791
.child(
780792
div().p_1().rounded_lg().bg(color).with_animation(
781793
"pulse-ssh-waiting-for-connection",
@@ -788,8 +800,7 @@ impl DevServerProjects {
788800
.child(
789801
Label::new("Waiting for connection…")
790802
.size(LabelSize::Small),
791-
)
792-
.child(h_flex().w_full()),
803+
),
793804
)
794805
}
795806
}),

crates/recent_projects/src/recent_projects.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -566,15 +566,15 @@ impl PickerDelegate for RecentProjectsDelegate {
566566
.border_t_1()
567567
.py_2()
568568
.pr_2()
569-
.border_color(cx.theme().colors().border)
569+
.border_color(cx.theme().colors().border_variant)
570570
.justify_end()
571571
.gap_4()
572572
.child(
573573
ButtonLike::new("remote")
574574
.when_some(KeyBinding::for_action(&OpenRemote, cx), |button, key| {
575575
button.child(key)
576576
})
577-
.child(Label::new("Open remote folder…").color(Color::Muted))
577+
.child(Label::new("Open Remote Folder…").color(Color::Muted))
578578
.on_click(|_, cx| cx.dispatch_action(OpenRemote.boxed_clone())),
579579
)
580580
.child(
@@ -583,7 +583,7 @@ impl PickerDelegate for RecentProjectsDelegate {
583583
KeyBinding::for_action(&workspace::Open, cx),
584584
|button, key| button.child(key),
585585
)
586-
.child(Label::new("Open local folder…").color(Color::Muted))
586+
.child(Label::new("Open Local Folder…").color(Color::Muted))
587587
.on_click(|_, cx| cx.dispatch_action(workspace::Open.boxed_clone())),
588588
)
589589
.into_any(),

crates/recent_projects/src/ssh_connections.rs

Lines changed: 87 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ use schemars::JsonSchema;
1616
use serde::{Deserialize, Serialize};
1717
use settings::{Settings, SettingsSources};
1818
use ui::{
19-
div, h_flex, v_flex, ActiveTheme, ButtonCommon, Clickable, Color, FluentBuilder as _, Icon,
20-
IconButton, IconName, IconSize, InteractiveElement, IntoElement, Label, LabelCommon, Styled,
21-
StyledExt as _, Tooltip, ViewContext, VisualContext, WindowContext,
19+
div, h_flex, prelude::*, v_flex, ActiveTheme, ButtonCommon, Clickable, Color, Icon, IconButton,
20+
IconName, IconSize, InteractiveElement, IntoElement, Label, LabelCommon, Styled, Tooltip,
21+
ViewContext, VisualContext, WindowContext,
2222
};
2323
use workspace::{AppState, ModalView, Workspace};
2424

@@ -84,6 +84,7 @@ pub struct SshPrompt {
8484
pub struct SshConnectionModal {
8585
pub(crate) prompt: View<SshPrompt>,
8686
}
87+
8788
impl SshPrompt {
8889
pub fn new(connection_options: &SshConnectionOptions, cx: &mut ViewContext<Self>) -> Self {
8990
let connection_string = connection_options.connection_string().into();
@@ -136,57 +137,70 @@ impl SshPrompt {
136137
}
137138

138139
impl Render for SshPrompt {
139-
fn render(&mut self, _: &mut ViewContext<Self>) -> impl IntoElement {
140+
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
141+
let cx = cx.window_context();
142+
let theme = cx.theme();
140143
v_flex()
141-
.w_full()
142144
.key_context("PasswordPrompt")
143-
.justify_start()
145+
.size_full()
146+
.justify_center()
144147
.child(
145-
v_flex()
146-
.p_4()
147-
.size_full()
148-
.child(
149-
h_flex()
150-
.gap_2()
151-
.justify_between()
152-
.child(h_flex().w_full())
153-
.child(if self.error_message.is_some() {
154-
Icon::new(IconName::XCircle)
155-
.size(IconSize::Medium)
156-
.color(Color::Error)
157-
.into_any_element()
158-
} else {
159-
Icon::new(IconName::ArrowCircle)
160-
.size(IconSize::Medium)
161-
.with_animation(
162-
"arrow-circle",
163-
Animation::new(Duration::from_secs(2)).repeat(),
164-
|icon, delta| {
165-
icon.transform(Transformation::rotate(percentage(
166-
delta,
167-
)))
168-
},
169-
)
170-
.into_any_element()
171-
})
172-
.child(Label::new(format!(
173-
"Connecting to {}…",
174-
self.connection_string
175-
)))
176-
.child(h_flex().w_full()),
177-
)
178-
.when_some(self.error_message.as_ref(), |el, error| {
179-
el.child(Label::new(error.clone()))
148+
h_flex()
149+
.py_2()
150+
.px_4()
151+
.justify_center()
152+
.child(if self.error_message.is_some() {
153+
Icon::new(IconName::XCircle)
154+
.size(IconSize::Medium)
155+
.color(Color::Error)
156+
.into_any_element()
157+
} else {
158+
Icon::new(IconName::ArrowCircle)
159+
.size(IconSize::Medium)
160+
.with_animation(
161+
"arrow-circle",
162+
Animation::new(Duration::from_secs(2)).repeat(),
163+
|icon, delta| {
164+
icon.transform(Transformation::rotate(percentage(delta)))
165+
},
166+
)
167+
.into_any_element()
180168
})
181-
.when(
182-
self.error_message.is_none() && self.status_message.is_some(),
183-
|el| el.child(Label::new(self.status_message.clone().unwrap())),
169+
.child(
170+
div()
171+
.ml_1()
172+
.child(Label::new("SSH Connection").size(LabelSize::Small)),
184173
)
185-
.when_some(self.prompt.as_ref(), |el, prompt| {
186-
el.child(Label::new(prompt.0.clone()))
187-
.child(self.editor.clone())
188-
}),
174+
.child(
175+
div()
176+
.when_some(self.error_message.as_ref(), |el, error| {
177+
el.child(Label::new(format!("-{}", error)).size(LabelSize::Small))
178+
})
179+
.when(
180+
self.error_message.is_none() && self.status_message.is_some(),
181+
|el| {
182+
el.child(
183+
Label::new(format!(
184+
"-{}",
185+
self.status_message.clone().unwrap()
186+
))
187+
.size(LabelSize::Small),
188+
)
189+
},
190+
),
191+
),
189192
)
193+
.child(div().when_some(self.prompt.as_ref(), |el, prompt| {
194+
el.child(
195+
h_flex()
196+
.p_4()
197+
.border_t_1()
198+
.border_color(theme.colors().border_variant)
199+
.font_buffer(cx)
200+
.child(Label::new(prompt.0.clone()))
201+
.child(self.editor.clone()),
202+
)
203+
}))
190204
}
191205
}
192206

@@ -210,39 +224,54 @@ impl Render for SshConnectionModal {
210224
fn render(&mut self, cx: &mut ui::ViewContext<Self>) -> impl ui::IntoElement {
211225
let connection_string = self.prompt.read(cx).connection_string.clone();
212226
let theme = cx.theme();
213-
let header_color = theme.colors().element_background;
214-
let body_color = theme.colors().background;
227+
let mut header_color = cx.theme().colors().text;
228+
header_color.fade_out(0.96);
229+
let body_color = theme.colors().editor_background;
230+
215231
v_flex()
216232
.elevation_3(cx)
217233
.on_action(cx.listener(Self::dismiss))
218234
.on_action(cx.listener(Self::confirm))
219-
.w(px(400.))
235+
.w(px(500.))
236+
.border_1()
237+
.border_color(theme.colors().border)
220238
.child(
221239
h_flex()
240+
.relative()
222241
.p_1()
242+
.rounded_t_md()
223243
.border_b_1()
224244
.border_color(theme.colors().border)
225245
.bg(header_color)
226246
.justify_between()
227247
.child(
228-
IconButton::new("ssh-connection-cancel", IconName::ArrowLeft)
229-
.icon_size(IconSize::XSmall)
230-
.on_click(|_, cx| cx.dispatch_action(menu::Cancel.boxed_clone()))
231-
.tooltip(|cx| Tooltip::for_action("Back", &menu::Cancel, cx)),
248+
div().absolute().left_0p5().top_0p5().child(
249+
IconButton::new("ssh-connection-cancel", IconName::ArrowLeft)
250+
.icon_size(IconSize::XSmall)
251+
.on_click(|_, cx| cx.dispatch_action(menu::Cancel.boxed_clone()))
252+
.tooltip(|cx| Tooltip::for_action("Back", &menu::Cancel, cx)),
253+
),
232254
)
233255
.child(
234256
h_flex()
257+
.w_full()
235258
.gap_2()
259+
.justify_center()
236260
.child(Icon::new(IconName::Server).size(IconSize::XSmall))
237261
.child(
238262
Label::new(connection_string)
239263
.size(ui::LabelSize::Small)
240264
.single_line(),
241265
),
242-
)
243-
.child(div()),
266+
),
267+
)
268+
.child(
269+
h_flex()
270+
.rounded_b_md()
271+
.bg(body_color)
272+
.w_full()
273+
.child(self.prompt.clone()),
244274
)
245-
.child(h_flex().bg(body_color).w_full().child(self.prompt.clone()))
246275
}
247276
}
248277

crates/title_bar/src/title_bar.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use smallvec::SmallVec;
2424
use std::sync::Arc;
2525
use theme::ActiveTheme;
2626
use ui::{
27-
h_flex, prelude::*, Avatar, Button, ButtonLike, ButtonStyle, ContextMenu, Icon, IconName,
28-
Indicator, PopoverMenu, Tooltip,
27+
h_flex, prelude::*, Avatar, Button, ButtonLike, ButtonStyle, ContextMenu, Icon,
28+
IconButtonShape, IconName, IconSize, Indicator, PopoverMenu, Tooltip,
2929
};
3030
use util::ResultExt;
3131
use vcs_menu::{BranchList, OpenRecent as ToggleVcsMenu};
@@ -274,18 +274,19 @@ impl TitleBar {
274274
};
275275
let indicator = div()
276276
.absolute()
277-
.w_1_4()
278-
.h_1_4()
277+
.size_1p5()
279278
.right_0p5()
280279
.bottom_0p5()
281-
.p_1()
282-
.rounded_2xl()
280+
.rounded_full()
283281
.bg(indicator_color.color(cx));
284282

285283
Some(
286284
div()
285+
.relative()
287286
.child(
288287
IconButton::new("ssh-server-icon", IconName::Server)
288+
.icon_size(IconSize::Small)
289+
.shape(IconButtonShape::Square)
289290
.tooltip(move |cx| {
290291
Tooltip::with_meta(
291292
"Remote Project",
@@ -294,7 +295,6 @@ impl TitleBar {
294295
cx,
295296
)
296297
})
297-
.shape(ui::IconButtonShape::Square)
298298
.on_click(|_, cx| {
299299
cx.dispatch_action(OpenRemote.boxed_clone());
300300
}),

0 commit comments

Comments
 (0)