Detailed changes
@@ -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"
}
}
]
@@ -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"
}
}
]
@@ -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)
+ )
+}
@@ -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(
@@ -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
@@ -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);
}))