Implement welcome view in zed2.

Max Brunsfeld created

Still needs styling.

Change summary

crates/welcome2/src/welcome.rs | 338 ++++++++++++++++-------------------
crates/zed2/src/main.rs        |   5 
2 files changed, 159 insertions(+), 184 deletions(-)

Detailed changes

crates/welcome2/src/welcome.rs 🔗

@@ -1,15 +1,16 @@
 mod base_keymap_picker;
 mod base_keymap_setting;
 
+use client::TelemetrySettings;
 use db::kvp::KEY_VALUE_STORE;
 use gpui::{
-    div, red, AnyElement, AppContext, Div, EventEmitter, FocusHandle, Focusable, FocusableView,
+    div, svg, AnyElement, AppContext, Div, EventEmitter, FocusHandle, Focusable, FocusableView,
     InteractiveElement, ParentElement, Render, Styled, Subscription, View, ViewContext,
     VisualContext, WeakView, WindowContext,
 };
 use settings::{Settings, SettingsStore};
 use std::sync::Arc;
-use ui::prelude::*;
+use ui::{prelude::*, Checkbox};
 use workspace::{
     dock::DockPosition,
     item::{Item, ItemEvent},
@@ -34,7 +35,7 @@ pub fn init(cx: &mut AppContext) {
     base_keymap_picker::init(cx);
 }
 
-pub fn show_welcome_experience(app_state: &Arc<AppState>, cx: &mut AppContext) {
+pub fn show_welcome_view(app_state: &Arc<AppState>, cx: &mut AppContext) {
     open_new(&app_state, cx, |workspace, cx| {
         workspace.toggle_dock(DockPosition::Left, cx);
         let welcome_page = cx.build_view(|cx| WelcomePage::new(workspace, cx));
@@ -58,186 +59,140 @@ pub struct WelcomePage {
 impl Render for WelcomePage {
     type Element = Focusable<Div>;
 
-    fn render(&mut self, _cx: &mut gpui::ViewContext<Self>) -> Self::Element {
-        // todo!(welcome_ui)
-        // let self_handle = cx.handle();
-        // let theme = cx.theme();
-        // let width = theme.welcome.page_width;
-
-        // let telemetry_settings = TelemetrySettings::get(None, cx);
-        // let vim_mode_setting = VimModeSettings::get(cx);
-
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
         div()
+            .full()
             .track_focus(&self.focus_handle)
-            .child(div().size_full().bg(red()).child("Welcome!"))
-        //todo!()
-        //     PaneBackdrop::new(
-        //         self_handle.id(),
-        //         Flex::column()
-        //             .with_child(
-        //                 Flex::column()
-        //                     .with_child(
-        //                         theme::ui::svg(&theme.welcome.logo)
-        //                             .aligned()
-        //                             .contained()
-        //                             .aligned(),
-        //                     )
-        //                     .with_child(
-        //                         Label::new(
-        //                             "Code at the speed of thought",
-        //                             theme.welcome.logo_subheading.text.clone(),
-        //                         )
-        //                         .aligned()
-        //                         .contained()
-        //                         .with_style(theme.welcome.logo_subheading.container),
-        //                     )
-        //                     .contained()
-        //                     .with_style(theme.welcome.heading_group)
-        //                     .constrained()
-        //                     .with_width(width),
-        //             )
-        //             .with_child(
-        //                 Flex::column()
-        //                     .with_child(theme::ui::cta_button::<theme_selector::Toggle, _, _, _>(
-        //                         "Choose a theme",
-        //                         width,
-        //                         &theme.welcome.button,
-        //                         cx,
-        //                         |_, this, cx| {
-        //                             if let Some(workspace) = this.workspace.upgrade(cx) {
-        //                                 workspace.update(cx, |workspace, cx| {
-        //                                     theme_selector::toggle(workspace, &Default::default(), cx)
-        //                                 })
-        //                             }
-        //                         },
-        //                     ))
-        //                     .with_child(theme::ui::cta_button::<ToggleBaseKeymapSelector, _, _, _>(
-        //                         "Choose a keymap",
-        //                         width,
-        //                         &theme.welcome.button,
-        //                         cx,
-        //                         |_, this, cx| {
-        //                             if let Some(workspace) = this.workspace.upgrade(cx) {
-        //                                 workspace.update(cx, |workspace, cx| {
-        //                                     base_keymap_picker::toggle(
-        //                                         workspace,
-        //                                         &Default::default(),
-        //                                         cx,
-        //                                     )
-        //                                 })
-        //                             }
-        //                         },
-        //                     ))
-        //                     .with_child(theme::ui::cta_button::<install_cli::Install, _, _, _>(
-        //                         "Install the CLI",
-        //                         width,
-        //                         &theme.welcome.button,
-        //                         cx,
-        //                         |_, _, cx| {
-        //                             cx.app_context()
-        //                                 .spawn(|cx| async move { install_cli::install_cli(&cx).await })
-        //                                 .detach_and_log_err(cx);
-        //                         },
-        //                     ))
-        //                     .contained()
-        //                     .with_style(theme.welcome.button_group)
-        //                     .constrained()
-        //                     .with_width(width),
-        //             )
-        //             .with_child(
-        //                 Flex::column()
-        //                     .with_child(
-        //                         theme::ui::checkbox::<Diagnostics, Self, _>(
-        //                             "Enable vim mode",
-        //                             &theme.welcome.checkbox,
-        //                             vim_mode_setting,
-        //                             0,
-        //                             cx,
-        //                             |this, checked, cx| {
-        //                                 if let Some(workspace) = this.workspace.upgrade(cx) {
-        //                                     let fs = workspace.read(cx).app_state().fs.clone();
-        //                                     update_settings_file::<VimModeSetting>(
-        //                                         fs,
-        //                                         cx,
-        //                                         move |setting| *setting = Some(checked),
-        //                                     )
-        //                                 }
-        //                             },
-        //                         )
-        //                         .contained()
-        //                         .with_style(theme.welcome.checkbox_container),
-        //                     )
-        //                     .with_child(
-        //                         theme::ui::checkbox_with_label::<Metrics, _, Self, _>(
-        //                             Flex::column()
-        //                                 .with_child(
-        //                                     Label::new(
-        //                                         "Send anonymous usage data",
-        //                                         theme.welcome.checkbox.label.text.clone(),
-        //                                     )
-        //                                     .contained()
-        //                                     .with_style(theme.welcome.checkbox.label.container),
-        //                                 )
-        //                                 .with_child(
-        //                                     Label::new(
-        //                                         "Help > View Telemetry",
-        //                                         theme.welcome.usage_note.text.clone(),
-        //                                     )
-        //                                     .contained()
-        //                                     .with_style(theme.welcome.usage_note.container),
-        //                                 ),
-        //                             &theme.welcome.checkbox,
-        //                             telemetry_settings.metrics,
-        //                             0,
-        //                             cx,
-        //                             |this, checked, cx| {
-        //                                 if let Some(workspace) = this.workspace.upgrade(cx) {
-        //                                     let fs = workspace.read(cx).app_state().fs.clone();
-        //                                     update_settings_file::<TelemetrySettings>(
-        //                                         fs,
-        //                                         cx,
-        //                                         move |setting| setting.metrics = Some(checked),
-        //                                     )
-        //                                 }
-        //                             },
-        //                         )
-        //                         .contained()
-        //                         .with_style(theme.welcome.checkbox_container),
-        //                     )
-        //                     .with_child(
-        //                         theme::ui::checkbox::<Diagnostics, Self, _>(
-        //                             "Send crash reports",
-        //                             &theme.welcome.checkbox,
-        //                             telemetry_settings.diagnostics,
-        //                             1,
-        //                             cx,
-        //                             |this, checked, cx| {
-        //                                 if let Some(workspace) = this.workspace.upgrade(cx) {
-        //                                     let fs = workspace.read(cx).app_state().fs.clone();
-        //                                     update_settings_file::<TelemetrySettings>(
-        //                                         fs,
-        //                                         cx,
-        //                                         move |setting| setting.diagnostics = Some(checked),
-        //                                     )
-        //                                 }
-        //                             },
-        //                         )
-        //                         .contained()
-        //                         .with_style(theme.welcome.checkbox_container),
-        //                     )
-        //                     .contained()
-        //                     .with_style(theme.welcome.checkbox_group)
-        //                     .constrained()
-        //                     .with_width(width),
-        //             )
-        //             .constrained()
-        //             .with_max_width(width)
-        //             .contained()
-        //             .with_uniform_padding(10.)
-        //             .aligned()
-        //             .into_any(),
-        //     )
-        //     .into_any_named("welcome page")
+            .relative()
+            .child(
+                v_stack()
+                    .w_96()
+                    .mx_auto()
+                    .child(
+                        svg()
+                            .path("icons/logo_96.svg")
+                            .text_color(gpui::white())
+                            .w(px(96.))
+                            .h(px(96.))
+                            .mx_auto(),
+                    )
+                    .child(Label::new("Code at the speed of thought"))
+                    .child(
+                        Button::new("choose-theme", "Choose a theme")
+                            .full_width()
+                            .on_click(cx.listener(|this, _, cx| {
+                                this.workspace
+                                    .update(cx, |workspace, cx| {
+                                        theme_selector::toggle(workspace, &Default::default(), cx)
+                                    })
+                                    .ok();
+                            })),
+                    )
+                    .child(
+                        Button::new("choose-keymap", "Choose a keymap")
+                            .full_width()
+                            .on_click(cx.listener(|this, _, cx| {
+                                this.workspace
+                                    .update(cx, |workspace, cx| {
+                                        base_keymap_picker::toggle(
+                                            workspace,
+                                            &Default::default(),
+                                            cx,
+                                        )
+                                    })
+                                    .ok();
+                            })),
+                    )
+                    .child(
+                        Button::new("install-cli", "Install the CLI")
+                            .full_width()
+                            .on_click(cx.listener(|_, _, cx| {
+                                cx.app_mut()
+                                    .spawn(|cx| async move { install_cli::install_cli(&cx).await })
+                                    .detach_and_log_err(cx);
+                            })),
+                    )
+                    .child(
+                        v_stack()
+                            .bg(cx.theme().colors().elevated_surface_background)
+                            .child(
+                                // todo!("vim setting")
+                                h_stack()
+                                    .child(
+                                        Checkbox::new(
+                                            "enable-vim",
+                                            if false
+                                            /* VimSettings::get_global(cx).enabled */
+                                            {
+                                                ui::Selection::Selected
+                                            } else {
+                                                ui::Selection::Unselected
+                                            },
+                                        ),
+                                        // .on_click(cx.listener(
+                                        //     move |this, selection, cx| {
+                                        //         this.update_settings::<VimSettings>(
+                                        //             selection,
+                                        //             cx,
+                                        //             |settings, value| settings.enabled = value,
+                                        //         );
+                                        //     },
+                                        // )),
+                                    )
+                                    .child("Enable vim mode"),
+                            )
+                            .child(
+                                h_stack()
+                                    .child(
+                                        Checkbox::new(
+                                            "enable-telemetry",
+                                            if TelemetrySettings::get_global(cx).metrics {
+                                                ui::Selection::Selected
+                                            } else {
+                                                ui::Selection::Unselected
+                                            },
+                                        )
+                                        .on_click(
+                                            cx.listener(move |this, selection, cx| {
+                                                this.update_settings::<TelemetrySettings>(
+                                                    selection,
+                                                    cx,
+                                                    |settings, value| {
+                                                        settings.metrics = Some(value)
+                                                    },
+                                                );
+                                            }),
+                                        ),
+                                    )
+                                    .child("Send usage data"),
+                            )
+                            .child(
+                                h_stack()
+                                    .child(
+                                        Checkbox::new(
+                                            "enable-crash",
+                                            if TelemetrySettings::get_global(cx).diagnostics {
+                                                ui::Selection::Selected
+                                            } else {
+                                                ui::Selection::Unselected
+                                            },
+                                        )
+                                        .on_click(
+                                            cx.listener(move |this, selection, cx| {
+                                                this.update_settings::<TelemetrySettings>(
+                                                    selection,
+                                                    cx,
+                                                    |settings, value| {
+                                                        settings.diagnostics = Some(value)
+                                                    },
+                                                );
+                                            }),
+                                        ),
+                                    )
+                                    .child("Send crash reports"),
+                            ),
+                    ),
+            )
     }
 }
 
@@ -249,6 +204,27 @@ impl WelcomePage {
             _settings_subscription: cx.observe_global::<SettingsStore>(move |_, cx| cx.notify()),
         }
     }
+
+    fn update_settings<T: Settings>(
+        &mut self,
+        selection: &Selection,
+        cx: &mut ViewContext<Self>,
+        callback: impl 'static + Send + Fn(&mut T::FileContent, bool),
+    ) {
+        if let Some(workspace) = self.workspace.upgrade() {
+            let fs = workspace.read(cx).app_state().fs.clone();
+            let selection = *selection;
+            settings::update_settings_file::<T>(fs, cx, move |settings| {
+                let value = match selection {
+                    Selection::Unselected => false,
+                    Selection::Selected => true,
+                    _ => return,
+                };
+
+                callback(settings, value)
+            });
+        }
+    }
 }
 
 impl EventEmitter<ItemEvent> for WelcomePage {}

crates/zed2/src/main.rs 🔗

@@ -47,7 +47,7 @@ use util::{
     paths, ResultExt,
 };
 use uuid::Uuid;
-use welcome::{show_welcome_experience, FIRST_OPEN};
+use welcome::{show_welcome_view, FIRST_OPEN};
 use workspace::{AppState, WorkspaceStore};
 use zed2::{
     app_menus, build_window_options, ensure_only_instance, handle_cli_connection,
@@ -366,8 +366,7 @@ async fn restore_or_create_workspace(app_state: &Arc<AppState>, mut cx: AsyncApp
                 .await
                 .log_err();
         } else if matches!(KEY_VALUE_STORE.read_kvp(FIRST_OPEN), Ok(None)) {
-            cx.update(|cx| show_welcome_experience(app_state, cx))
-                .log_err();
+            cx.update(|cx| show_welcome_view(app_state, cx)).log_err();
         } else {
             cx.update(|cx| {
                 workspace::open_new(app_state, cx, |workspace, cx| {