onboarding: Add some adjustments (#35887)

Danilo Leal created

Release Notes:

- N/A

Change summary

assets/keymaps/default-linux.json      |  3 
assets/keymaps/default-macos.json      |  3 
crates/client/src/zed_urls.rs          |  8 ++
crates/onboarding/src/ai_setup_page.rs | 97 +++++++++++----------------
crates/onboarding/src/editing_page.rs  |  2 
crates/onboarding/src/onboarding.rs    | 50 ++++++++++++--
6 files changed, 97 insertions(+), 66 deletions(-)

Detailed changes

assets/keymaps/default-linux.json 🔗

@@ -1187,7 +1187,8 @@
       "ctrl-2": "onboarding::ActivateEditingPage",
       "ctrl-3": "onboarding::ActivateAISetupPage",
       "ctrl-escape": "onboarding::Finish",
-      "alt-tab": "onboarding::SignIn"
+      "alt-tab": "onboarding::SignIn",
+      "alt-shift-a": "onboarding::OpenAccount"
     }
   }
 ]

assets/keymaps/default-macos.json 🔗

@@ -1289,7 +1289,8 @@
       "cmd-2": "onboarding::ActivateEditingPage",
       "cmd-3": "onboarding::ActivateAISetupPage",
       "cmd-escape": "onboarding::Finish",
-      "alt-tab": "onboarding::SignIn"
+      "alt-tab": "onboarding::SignIn",
+      "alt-shift-a": "onboarding::OpenAccount"
     }
   }
 ]

crates/client/src/zed_urls.rs 🔗

@@ -35,3 +35,11 @@ pub fn upgrade_to_zed_pro_url(cx: &App) -> String {
 pub fn terms_of_service(cx: &App) -> String {
     format!("{server_url}/terms-of-service", server_url = server_url(cx))
 }
+
+/// Returns the URL to Zed AI's privacy and security docs.
+pub fn ai_privacy_and_security(cx: &App) -> String {
+    format!(
+        "{server_url}/docs/ai/privacy-and-security",
+        server_url = server_url(cx)
+    )
+}

crates/onboarding/src/ai_setup_page.rs 🔗

@@ -1,7 +1,7 @@
 use std::sync::Arc;
 
 use ai_onboarding::AiUpsellCard;
-use client::{Client, UserStore};
+use client::{Client, UserStore, zed_urls};
 use fs::Fs;
 use gpui::{
     Action, AnyView, App, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, WeakEntity,
@@ -42,10 +42,16 @@ fn render_llm_provider_section(
 }
 
 fn render_privacy_card(tab_index: &mut isize, disabled: bool, cx: &mut App) -> impl IntoElement {
-    let privacy_badge = || {
-        Badge::new("Privacy")
-            .icon(IconName::ShieldCheck)
-            .tooltip(move |_, cx| cx.new(|_| AiPrivacyTooltip::new()).into())
+    let (title, description) = if disabled {
+        (
+            "AI is disabled across Zed",
+            "Re-enable it any time in Settings.",
+        )
+    } else {
+        (
+            "Privacy is the default for Zed",
+            "Any use or storage of your data is with your explicit, single-use, opt-in consent.",
+        )
     };
 
     v_flex()
@@ -60,62 +66,41 @@ fn render_privacy_card(tab_index: &mut isize, disabled: bool, cx: &mut App) -> i
         .bg(cx.theme().colors().surface_background.opacity(0.3))
         .rounded_lg()
         .overflow_hidden()
-        .map(|this| {
-            if disabled {
-                this.child(
+        .child(
+            h_flex()
+                .gap_2()
+                .justify_between()
+                .child(Label::new(title))
+                .child(
                     h_flex()
-                        .gap_2()
-                        .justify_between()
+                        .gap_1()
                         .child(
-                            h_flex()
-                                .gap_1()
-                                .child(Label::new("AI is disabled across Zed"))
-                                .child(
-                                    Icon::new(IconName::Check)
-                                        .color(Color::Success)
-                                        .size(IconSize::XSmall),
-                                ),
+                            Badge::new("Privacy")
+                                .icon(IconName::ShieldCheck)
+                                .tooltip(move |_, cx| cx.new(|_| AiPrivacyTooltip::new()).into()),
                         )
-                        .child(privacy_badge()),
-                )
-                .child(
-                    Label::new("Re-enable it any time in Settings.")
-                        .size(LabelSize::Small)
-                        .color(Color::Muted),
-                )
-            } else {
-                this.child(
-                    h_flex()
-                        .gap_2()
-                        .justify_between()
-                        .child(Label::new("Privacy is the default for Zed"))
                         .child(
-                            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::Small)
-                                    .icon_color(Color::Muted)
-                                    .on_click(|_, _, cx| {
-                                        cx.open_url("https://zed.dev/docs/ai/privacy-and-security");
-                                    })
-                                    .tab_index({
-                                        *tab_index += 1;
-                                        *tab_index - 1
-                                    }),
-                            ),
+                            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(&zed_urls::ai_privacy_and_security(cx))
+                                })
+                                .tab_index({
+                                    *tab_index += 1;
+                                    *tab_index - 1
+                                }),
                         ),
-                )
-                .child(
-                    Label::new(
-                        "Any use or storage of your data is with your explicit, single-use, opt-in consent.",
-                    )
-                    .size(LabelSize::Small)
-                    .color(Color::Muted),
-                )
-            }
-        })
+                ),
+        )
+        .child(
+            Label::new(description)
+                .size(LabelSize::Small)
+                .color(Color::Muted),
+        )
 }
 
 fn render_llm_provider_card(

crates/onboarding/src/editing_page.rs 🔗

@@ -655,7 +655,7 @@ fn render_popular_settings_section(
         .child(
             SwitchField::new(
                 "onboarding-git-blame-switch",
-                "Git Blame",
+                "Inline Git Blame",
                 Some("See who committed each line on a given file.".into()),
                 if read_git_blame(cx) {
                     ui::ToggleState::Selected

crates/onboarding/src/onboarding.rs 🔗

@@ -1,5 +1,5 @@
 use crate::welcome::{ShowWelcome, WelcomePage};
-use client::{Client, UserStore};
+use client::{Client, UserStore, zed_urls};
 use command_palette_hooks::CommandPaletteFilter;
 use db::kvp::KEY_VALUE_STORE;
 use feature_flags::{FeatureFlag, FeatureFlagViewExt as _};
@@ -78,7 +78,9 @@ actions!(
         /// Finish the onboarding process.
         Finish,
         /// Sign in while in the onboarding flow.
-        SignIn
+        SignIn,
+        /// Open the user account in zed.dev while in the onboarding flow.
+        OpenAccount
     ]
 );
 
@@ -420,11 +422,40 @@ impl Onboarding {
             )
             .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()))
+                    v_flex()
+                        .gap_1()
+                        .child(
+                            h_flex()
+                                .ml_2()
+                                .gap_2()
+                                .max_w_full()
+                                .w_full()
+                                .child(Avatar::new(user.avatar_uri.clone()))
+                                .child(Label::new(user.github_login.clone()).truncate()),
+                        )
+                        .child(
+                            ButtonLike::new("open_account")
+                                .size(ButtonSize::Medium)
+                                .child(
+                                    h_flex()
+                                        .ml_1()
+                                        .w_full()
+                                        .justify_between()
+                                        .child(Label::new("Open Account"))
+                                        .children(
+                                            KeyBinding::for_action_in(
+                                                &OpenAccount,
+                                                &self.focus_handle,
+                                                window,
+                                                cx,
+                                            )
+                                            .map(|kb| kb.size(rems_from_px(12.))),
+                                        ),
+                                )
+                                .on_click(|_, window, cx| {
+                                    window.dispatch_action(OpenAccount.boxed_clone(), cx);
+                                }),
+                        )
                         .into_any_element()
                 } else {
                     Button::new("sign_in", "Sign In")
@@ -460,6 +491,10 @@ impl Onboarding {
             .detach();
     }
 
+    fn handle_open_account(_: &OpenAccount, _: &mut Window, cx: &mut App) {
+        cx.open_url(&zed_urls::account_url(cx))
+    }
+
     fn render_page(&mut self, window: &mut Window, cx: &mut Context<Self>) -> AnyElement {
         let client = Client::global(cx);
 
@@ -495,6 +530,7 @@ impl Render for Onboarding {
             .bg(cx.theme().colors().editor_background)
             .on_action(Self::on_finish)
             .on_action(Self::handle_sign_in)
+            .on_action(Self::handle_open_account)
             .on_action(cx.listener(|this, _: &ActivateBasicsPage, _, cx| {
                 this.set_page(SelectedPage::Basics, cx);
             }))