onboarding: Add design adjustments (#35480)
Release Notes: - N/A --------- Co-authored-by: Anthony <anthony@zed.dev>
This commit is contained in:
parent
b31f893408
commit
faa45c53d7
17 changed files with 348 additions and 185 deletions
|
@ -43,6 +43,8 @@ fn render_llm_provider_section(
|
|||
}
|
||||
|
||||
fn render_privacy_card(disabled: bool, cx: &mut App) -> impl IntoElement {
|
||||
let privacy_badge = || Badge::new("Privacy").icon(IconName::ShieldCheck);
|
||||
|
||||
v_flex()
|
||||
.relative()
|
||||
.pt_2()
|
||||
|
@ -71,7 +73,7 @@ fn render_privacy_card(disabled: bool, cx: &mut App) -> impl IntoElement {
|
|||
.size(IconSize::XSmall),
|
||||
),
|
||||
)
|
||||
.child(Badge::new("PRIVACY").icon(IconName::FileLock)),
|
||||
.child(privacy_badge()),
|
||||
)
|
||||
.child(
|
||||
Label::new("Re-enable it any time in Settings.")
|
||||
|
@ -85,22 +87,17 @@ fn render_privacy_card(disabled: bool, cx: &mut App) -> impl IntoElement {
|
|||
.justify_between()
|
||||
.child(Label::new("We don't train models using your data"))
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(Badge::new("Privacy").icon(IconName::FileLock))
|
||||
.child(
|
||||
Button::new("learn_more", "Learn More")
|
||||
.style(ButtonStyle::Outlined)
|
||||
.label_size(LabelSize::Small)
|
||||
.icon(IconName::ArrowUpRight)
|
||||
.icon_size(IconSize::XSmall)
|
||||
.icon_color(Color::Muted)
|
||||
.on_click(|_, _, cx| {
|
||||
cx.open_url(
|
||||
"https://zed.dev/docs/ai/privacy-and-security",
|
||||
);
|
||||
}),
|
||||
),
|
||||
h_flex().gap_1().child(privacy_badge()).child(
|
||||
Button::new("learn_more", "Learn More")
|
||||
.style(ButtonStyle::Outlined)
|
||||
.label_size(LabelSize::Small)
|
||||
.icon(IconName::ArrowUpRight)
|
||||
.icon_size(IconSize::XSmall)
|
||||
.icon_color(Color::Muted)
|
||||
.on_click(|_, _, cx| {
|
||||
cx.open_url("https://zed.dev/docs/ai/privacy-and-security");
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
|
|
|
@ -48,7 +48,11 @@ fn render_theme_section(window: &mut Window, cx: &mut App) -> impl IntoElement {
|
|||
let theme_registry = ThemeRegistry::global(cx);
|
||||
|
||||
let current_theme_name = theme_selection.theme(appearance);
|
||||
let theme_mode = theme_selection.mode();
|
||||
let theme_mode = theme_selection.mode().unwrap_or_default();
|
||||
|
||||
// let theme_mode = theme_selection.mode();
|
||||
// TODO: Clean this up once the "System" button inside the
|
||||
// toggle button group is done
|
||||
|
||||
let selected_index = match appearance {
|
||||
Appearance::Light => 0,
|
||||
|
@ -72,8 +76,28 @@ fn render_theme_section(window: &mut Window, cx: &mut App) -> impl IntoElement {
|
|||
let is_selected = theme.name == current_theme_name;
|
||||
let name = theme.name.clone();
|
||||
let colors = cx.theme().colors();
|
||||
|
||||
v_flex()
|
||||
.id(name.clone())
|
||||
.w_full()
|
||||
.items_center()
|
||||
.gap_1()
|
||||
.child(
|
||||
div()
|
||||
.w_full()
|
||||
.border_2()
|
||||
.border_color(colors.border_transparent)
|
||||
.rounded(ThemePreviewTile::CORNER_RADIUS)
|
||||
.map(|this| {
|
||||
if is_selected {
|
||||
this.border_color(colors.border_selected)
|
||||
} else {
|
||||
this.opacity(0.8).hover(|s| s.border_color(colors.border))
|
||||
}
|
||||
})
|
||||
.child(ThemePreviewTile::new(theme.clone(), theme_seed)),
|
||||
)
|
||||
.child(Label::new(name).color(Color::Muted).size(LabelSize::Small))
|
||||
.on_click({
|
||||
let theme_name = theme.name.clone();
|
||||
move |_, _, cx| {
|
||||
|
@ -84,84 +108,45 @@ fn render_theme_section(window: &mut Window, cx: &mut App) -> impl IntoElement {
|
|||
});
|
||||
}
|
||||
})
|
||||
.flex_1()
|
||||
.child(
|
||||
div()
|
||||
.border_2()
|
||||
.border_color(colors.border_transparent)
|
||||
.rounded(ThemePreviewTile::CORNER_RADIUS)
|
||||
.hover(|mut style| {
|
||||
if !is_selected {
|
||||
style.border_color = Some(colors.element_hover);
|
||||
}
|
||||
style
|
||||
})
|
||||
.when(is_selected, |this| {
|
||||
this.border_color(colors.border_selected)
|
||||
})
|
||||
.cursor_pointer()
|
||||
.child(ThemePreviewTile::new(theme, theme_seed)),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.justify_center()
|
||||
.items_baseline()
|
||||
.child(Label::new(name).color(Color::Muted)),
|
||||
)
|
||||
});
|
||||
|
||||
return v_flex()
|
||||
.gap_2()
|
||||
.child(
|
||||
h_flex().justify_between().child(Label::new("Theme")).child(
|
||||
h_flex()
|
||||
.gap_2()
|
||||
.child(
|
||||
ToggleButtonGroup::single_row(
|
||||
"theme-selector-onboarding-dark-light",
|
||||
[
|
||||
ToggleButtonSimple::new("Light", {
|
||||
let appearance_state = appearance_state.clone();
|
||||
move |_, _, cx| {
|
||||
write_appearance_change(
|
||||
&appearance_state,
|
||||
Appearance::Light,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
}),
|
||||
ToggleButtonSimple::new("Dark", {
|
||||
let appearance_state = appearance_state.clone();
|
||||
move |_, _, cx| {
|
||||
write_appearance_change(
|
||||
&appearance_state,
|
||||
Appearance::Dark,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
}),
|
||||
],
|
||||
)
|
||||
.selected_index(selected_index)
|
||||
.style(ui::ToggleButtonGroupStyle::Outlined)
|
||||
.button_width(rems_from_px(64.)),
|
||||
)
|
||||
.child(
|
||||
ToggleButtonGroup::single_row(
|
||||
"theme-selector-onboarding-system",
|
||||
[ToggleButtonSimple::new("System", {
|
||||
let theme = theme_selection.clone();
|
||||
move |_, _, cx| {
|
||||
toggle_system_theme_mode(theme.clone(), appearance, cx);
|
||||
}
|
||||
})],
|
||||
)
|
||||
.selected_index((theme_mode != Some(ThemeMode::System)) as usize)
|
||||
.style(ui::ToggleButtonGroupStyle::Outlined)
|
||||
.button_width(rems_from_px(64.)),
|
||||
),
|
||||
ToggleButtonGroup::single_row(
|
||||
"theme-selector-onboarding-dark-light",
|
||||
[
|
||||
ToggleButtonSimple::new("Light", {
|
||||
let appearance_state = appearance_state.clone();
|
||||
move |_, _, cx| {
|
||||
write_appearance_change(&appearance_state, Appearance::Light, cx);
|
||||
}
|
||||
}),
|
||||
ToggleButtonSimple::new("Dark", {
|
||||
let appearance_state = appearance_state.clone();
|
||||
move |_, _, cx| {
|
||||
write_appearance_change(&appearance_state, Appearance::Dark, cx);
|
||||
}
|
||||
}),
|
||||
// TODO: Properly put the System back as a button within this group
|
||||
// Currently, given "System" is not an option in the Appearance enum,
|
||||
// this button doesn't get selected
|
||||
ToggleButtonSimple::new("System", {
|
||||
let theme = theme_selection.clone();
|
||||
move |_, _, cx| {
|
||||
toggle_system_theme_mode(theme.clone(), appearance, cx);
|
||||
}
|
||||
})
|
||||
.selected(theme_mode == ThemeMode::System),
|
||||
],
|
||||
)
|
||||
.selected_index(selected_index)
|
||||
.style(ui::ToggleButtonGroupStyle::Outlined)
|
||||
.button_width(rems_from_px(64.)),
|
||||
),
|
||||
)
|
||||
.child(h_flex().justify_between().children(theme_previews));
|
||||
.child(h_flex().gap_4().justify_between().children(theme_previews));
|
||||
|
||||
fn write_appearance_change(
|
||||
appearance_state: &Entity<Appearance>,
|
||||
|
@ -210,7 +195,6 @@ fn render_theme_section(window: &mut Window, cx: &mut App) -> impl IntoElement {
|
|||
};
|
||||
ThemeSelection::Dynamic { mode, light, dark }
|
||||
}
|
||||
|
||||
ThemeSelection::Dynamic {
|
||||
mode: _,
|
||||
light,
|
||||
|
@ -311,30 +295,31 @@ pub(crate) fn render_basics_page(window: &mut Window, cx: &mut App) -> impl Into
|
|||
ToggleButtonGroup::two_rows(
|
||||
"multiple_row_test",
|
||||
[
|
||||
ToggleButtonWithIcon::new("VS Code", IconName::AiZed, |_, _, cx| {
|
||||
ToggleButtonWithIcon::new("VS Code", IconName::EditorVsCode, |_, _, cx| {
|
||||
write_keymap_base(BaseKeymap::VSCode, cx);
|
||||
}),
|
||||
ToggleButtonWithIcon::new("Jetbrains", IconName::AiZed, |_, _, cx| {
|
||||
ToggleButtonWithIcon::new("Jetbrains", IconName::EditorJetBrains, |_, _, cx| {
|
||||
write_keymap_base(BaseKeymap::JetBrains, cx);
|
||||
}),
|
||||
ToggleButtonWithIcon::new("Sublime Text", IconName::AiZed, |_, _, cx| {
|
||||
ToggleButtonWithIcon::new("Sublime Text", IconName::EditorSublime, |_, _, cx| {
|
||||
write_keymap_base(BaseKeymap::SublimeText, cx);
|
||||
}),
|
||||
],
|
||||
[
|
||||
ToggleButtonWithIcon::new("Atom", IconName::AiZed, |_, _, cx| {
|
||||
ToggleButtonWithIcon::new("Atom", IconName::EditorAtom, |_, _, cx| {
|
||||
write_keymap_base(BaseKeymap::Atom, cx);
|
||||
}),
|
||||
ToggleButtonWithIcon::new("Emacs", IconName::AiZed, |_, _, cx| {
|
||||
ToggleButtonWithIcon::new("Emacs", IconName::EditorEmacs, |_, _, cx| {
|
||||
write_keymap_base(BaseKeymap::Emacs, cx);
|
||||
}),
|
||||
ToggleButtonWithIcon::new("Cursor (Beta)", IconName::AiZed, |_, _, cx| {
|
||||
ToggleButtonWithIcon::new("Cursor (Beta)", IconName::EditorCursor, |_, _, cx| {
|
||||
write_keymap_base(BaseKeymap::Cursor, cx);
|
||||
}),
|
||||
],
|
||||
)
|
||||
.when_some(base_keymap, |this, base_keymap| this.selected_index(base_keymap))
|
||||
.button_width(rems_from_px(230.))
|
||||
.button_width(rems_from_px(216.))
|
||||
.size(ui::ToggleButtonGroupSize::Medium)
|
||||
.style(ui::ToggleButtonGroupStyle::Outlined)
|
||||
),
|
||||
)
|
||||
|
|
|
@ -143,7 +143,7 @@ fn render_import_settings_section() -> impl IntoElement {
|
|||
.gap_1p5()
|
||||
.px_1()
|
||||
.child(
|
||||
Icon::new(IconName::Sparkle)
|
||||
Icon::new(IconName::EditorVsCode)
|
||||
.color(Color::Muted)
|
||||
.size(IconSize::XSmall),
|
||||
)
|
||||
|
@ -169,7 +169,7 @@ fn render_import_settings_section() -> impl IntoElement {
|
|||
.gap_1p5()
|
||||
.px_1()
|
||||
.child(
|
||||
Icon::new(IconName::Sparkle)
|
||||
Icon::new(IconName::EditorCursor)
|
||||
.color(Color::Muted)
|
||||
.size(IconSize::XSmall),
|
||||
)
|
||||
|
|
|
@ -14,8 +14,8 @@ use serde::Deserialize;
|
|||
use settings::{SettingsStore, VsCodeSettingsSource};
|
||||
use std::sync::Arc;
|
||||
use ui::{
|
||||
Avatar, FluentBuilder, Headline, KeyBinding, ParentElement as _, StatefulInteractiveElement,
|
||||
Vector, VectorName, prelude::*, rems_from_px,
|
||||
Avatar, ButtonLike, FluentBuilder, Headline, KeyBinding, ParentElement as _,
|
||||
StatefulInteractiveElement, Vector, VectorName, prelude::*, rems_from_px,
|
||||
};
|
||||
use workspace::{
|
||||
AppState, Workspace, WorkspaceId,
|
||||
|
@ -344,12 +344,73 @@ impl Onboarding {
|
|||
.into_element(),
|
||||
]),
|
||||
)
|
||||
.child(Button::new("skip_all", "Skip All")),
|
||||
.child(
|
||||
ButtonLike::new("skip_all")
|
||||
.child(Label::new("Skip All").ml_1())
|
||||
.on_click(|_, _, cx| {
|
||||
with_active_or_new_workspace(
|
||||
cx,
|
||||
|workspace, window, cx| {
|
||||
let Some((onboarding_id, onboarding_idx)) =
|
||||
workspace
|
||||
.active_pane()
|
||||
.read(cx)
|
||||
.items()
|
||||
.enumerate()
|
||||
.find_map(|(idx, item)| {
|
||||
let _ =
|
||||
item.downcast::<Onboarding>()?;
|
||||
Some((item.item_id(), idx))
|
||||
})
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
workspace.active_pane().update(cx, |pane, cx| {
|
||||
// Get the index here to get around the borrow checker
|
||||
let idx = pane.items().enumerate().find_map(
|
||||
|(idx, item)| {
|
||||
let _ =
|
||||
item.downcast::<WelcomePage>()?;
|
||||
Some(idx)
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(idx) = idx {
|
||||
pane.activate_item(
|
||||
idx, true, true, window, cx,
|
||||
);
|
||||
} else {
|
||||
let item =
|
||||
Box::new(WelcomePage::new(window, cx));
|
||||
pane.add_item(
|
||||
item,
|
||||
true,
|
||||
true,
|
||||
Some(onboarding_idx),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
pane.remove_item(
|
||||
onboarding_id,
|
||||
false,
|
||||
false,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
if let Some(user) = self.user_store.read(cx).current_user() {
|
||||
h_flex()
|
||||
.pl_1p5()
|
||||
.gap_2()
|
||||
.child(Avatar::new(user.avatar_uri.clone()))
|
||||
.child(Label::new(user.github_login.clone()))
|
||||
|
|
|
@ -35,7 +35,7 @@ impl RenderOnce for ThemePreviewTile {
|
|||
|
||||
let item_skeleton = |w: Length, h: Pixels, bg: Hsla| div().w(w).h(h).rounded_full().bg(bg);
|
||||
|
||||
let skeleton_height = px(4.);
|
||||
let skeleton_height = px(2.);
|
||||
|
||||
let sidebar_seeded_width = |seed: f32, index: usize| {
|
||||
let value = (seed * 1000.0 + index as f32 * 10.0).sin() * 0.5 + 0.5;
|
||||
|
@ -62,12 +62,10 @@ impl RenderOnce for ThemePreviewTile {
|
|||
.border_color(color.border_transparent)
|
||||
.bg(color.panel_background)
|
||||
.child(
|
||||
div()
|
||||
v_flex()
|
||||
.p_2()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.size_full()
|
||||
.gap(px(4.))
|
||||
.gap_1()
|
||||
.children(sidebar_skeleton),
|
||||
);
|
||||
|
||||
|
@ -143,32 +141,19 @@ impl RenderOnce for ThemePreviewTile {
|
|||
v_flex()
|
||||
.size_full()
|
||||
.p_1()
|
||||
.gap(px(6.))
|
||||
.gap_1p5()
|
||||
.children(lines)
|
||||
.into_any_element()
|
||||
};
|
||||
|
||||
let pane = div()
|
||||
.h_full()
|
||||
.flex_grow()
|
||||
.flex()
|
||||
.flex_col()
|
||||
// .child(
|
||||
// div()
|
||||
// .w_full()
|
||||
// .border_color(color.border)
|
||||
// .border_b(px(1.))
|
||||
// .h(relative(0.1))
|
||||
// .bg(color.tab_bar_background),
|
||||
// )
|
||||
.child(
|
||||
div()
|
||||
.size_full()
|
||||
.overflow_hidden()
|
||||
.bg(color.editor_background)
|
||||
.p_2()
|
||||
.child(pseudo_code_skeleton(self.theme.clone(), self.seed)),
|
||||
);
|
||||
let pane = v_flex().h_full().flex_grow().child(
|
||||
div()
|
||||
.size_full()
|
||||
.overflow_hidden()
|
||||
.bg(color.editor_background)
|
||||
.p_2()
|
||||
.child(pseudo_code_skeleton(self.theme.clone(), self.seed)),
|
||||
);
|
||||
|
||||
let content = div().size_full().flex().child(sidebar).child(pane);
|
||||
|
||||
|
|
|
@ -4,11 +4,14 @@ use gpui::{
|
|||
};
|
||||
use ui::{ButtonLike, Divider, DividerColor, KeyBinding, Vector, VectorName, prelude::*};
|
||||
use workspace::{
|
||||
NewFile, Open, Workspace, WorkspaceId,
|
||||
NewFile, Open, WorkspaceId,
|
||||
item::{Item, ItemEvent},
|
||||
with_active_or_new_workspace,
|
||||
};
|
||||
use zed_actions::{Extensions, OpenSettings, agent, command_palette};
|
||||
|
||||
use crate::{Onboarding, OpenOnboarding};
|
||||
|
||||
actions!(
|
||||
zed,
|
||||
[
|
||||
|
@ -216,7 +219,64 @@ impl Render for WelcomePage {
|
|||
div().child(
|
||||
Button::new("welcome-exit", "Return to Setup")
|
||||
.full_width()
|
||||
.label_size(LabelSize::XSmall),
|
||||
.label_size(LabelSize::XSmall)
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(
|
||||
OpenOnboarding.boxed_clone(),
|
||||
cx,
|
||||
);
|
||||
|
||||
with_active_or_new_workspace(cx, |workspace, window, cx| {
|
||||
let Some((welcome_id, welcome_idx)) = workspace
|
||||
.active_pane()
|
||||
.read(cx)
|
||||
.items()
|
||||
.enumerate()
|
||||
.find_map(|(idx, item)| {
|
||||
let _ = item.downcast::<WelcomePage>()?;
|
||||
Some((item.item_id(), idx))
|
||||
})
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
workspace.active_pane().update(cx, |pane, cx| {
|
||||
// Get the index here to get around the borrow checker
|
||||
let idx = pane.items().enumerate().find_map(
|
||||
|(idx, item)| {
|
||||
let _ =
|
||||
item.downcast::<Onboarding>()?;
|
||||
Some(idx)
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(idx) = idx {
|
||||
pane.activate_item(
|
||||
idx, true, true, window, cx,
|
||||
);
|
||||
} else {
|
||||
let item =
|
||||
Box::new(Onboarding::new(workspace, cx));
|
||||
pane.add_item(
|
||||
item,
|
||||
true,
|
||||
true,
|
||||
Some(welcome_idx),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
pane.remove_item(
|
||||
welcome_id,
|
||||
false,
|
||||
false,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
});
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -227,7 +287,7 @@ impl Render for WelcomePage {
|
|||
}
|
||||
|
||||
impl WelcomePage {
|
||||
pub fn new(window: &mut Window, cx: &mut Context<Workspace>) -> Entity<Self> {
|
||||
pub fn new(window: &mut Window, cx: &mut App) -> Entity<Self> {
|
||||
cx.new(|cx| {
|
||||
let focus_handle = cx.focus_handle();
|
||||
cx.on_focus(&focus_handle, window, |_, _, cx| cx.notify())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue