welcome.rs

  1mod base_keymap_picker;
  2
  3use std::{borrow::Cow, sync::Arc};
  4
  5use db::kvp::KEY_VALUE_STORE;
  6use gpui::{
  7    elements::{Flex, Label, ParentElement},
  8    AnyElement, AppContext, Element, Entity, Subscription, View, ViewContext,
  9};
 10use settings::{settings_file::SettingsFile, Settings};
 11
 12use workspace::{
 13    item::Item, open_new, sidebar::SidebarSide, AppState, PaneBackdrop, Welcome, Workspace,
 14    WorkspaceId,
 15};
 16
 17use crate::base_keymap_picker::ToggleBaseKeymapSelector;
 18
 19pub const FIRST_OPEN: &str = "first_open";
 20
 21pub fn init(cx: &mut AppContext) {
 22    cx.add_action(|workspace: &mut Workspace, _: &Welcome, cx| {
 23        let welcome_page = cx.add_view(WelcomePage::new);
 24        workspace.add_item(Box::new(welcome_page), cx)
 25    });
 26
 27    base_keymap_picker::init(cx);
 28}
 29
 30pub fn show_welcome_experience(app_state: &Arc<AppState>, cx: &mut AppContext) {
 31    open_new(&app_state, cx, |workspace, cx| {
 32        workspace.toggle_sidebar(SidebarSide::Left, cx);
 33        let welcome_page = cx.add_view(|cx| WelcomePage::new(cx));
 34        workspace.add_item_to_center(Box::new(welcome_page.clone()), cx);
 35        cx.focus(&welcome_page);
 36        cx.notify();
 37    })
 38    .detach();
 39
 40    db::write_and_log(cx, || {
 41        KEY_VALUE_STORE.write_kvp(FIRST_OPEN.to_string(), "false".to_string())
 42    });
 43}
 44
 45pub struct WelcomePage {
 46    _settings_subscription: Subscription,
 47}
 48
 49impl Entity for WelcomePage {
 50    type Event = ();
 51}
 52
 53impl View for WelcomePage {
 54    fn ui_name() -> &'static str {
 55        "WelcomePage"
 56    }
 57
 58    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> AnyElement<Self> {
 59        let self_handle = cx.handle();
 60        let settings = cx.global::<Settings>();
 61        let theme = settings.theme.clone();
 62
 63        let width = theme.welcome.page_width;
 64
 65        let (diagnostics, metrics) = {
 66            let telemetry = settings.telemetry();
 67            (telemetry.diagnostics(), telemetry.metrics())
 68        };
 69
 70        enum Metrics {}
 71        enum Diagnostics {}
 72
 73        PaneBackdrop::new(
 74            self_handle.id(),
 75            Flex::column()
 76                .with_child(
 77                    Flex::column()
 78                        .with_child(
 79                            theme::ui::svg(&theme.welcome.logo)
 80                                .aligned()
 81                                .contained()
 82                                .aligned(),
 83                        )
 84                        .with_child(
 85                            Label::new(
 86                                "Code at the speed of thought",
 87                                theme.welcome.logo_subheading.text.clone(),
 88                            )
 89                            .aligned()
 90                            .contained()
 91                            .with_style(theme.welcome.logo_subheading.container),
 92                        )
 93                        .contained()
 94                        .with_style(theme.welcome.heading_group)
 95                        .constrained()
 96                        .with_width(width),
 97                )
 98                .with_child(
 99                    Flex::column()
100                        .with_child(theme::ui::cta_button(
101                            "Choose a theme",
102                            theme_selector::Toggle,
103                            width,
104                            &theme.welcome.button,
105                            cx,
106                        ))
107                        .with_child(theme::ui::cta_button(
108                            "Choose a keymap",
109                            ToggleBaseKeymapSelector,
110                            width,
111                            &theme.welcome.button,
112                            cx,
113                        ))
114                        .with_child(theme::ui::cta_button(
115                            "Install the CLI",
116                            install_cli::Install,
117                            width,
118                            &theme.welcome.button,
119                            cx,
120                        ))
121                        .contained()
122                        .with_style(theme.welcome.button_group)
123                        .constrained()
124                        .with_width(width),
125                )
126                .with_child(
127                    Flex::column()
128                        .with_child(
129                            theme::ui::checkbox_with_label::<Metrics, _, Self, _>(
130                                Flex::column()
131                                    .with_child(
132                                        Label::new(
133                                            "Send anonymous usage data",
134                                            theme.welcome.checkbox.label.text.clone(),
135                                        )
136                                        .contained()
137                                        .with_style(theme.welcome.checkbox.label.container),
138                                    )
139                                    .with_child(
140                                        Label::new(
141                                            "Help > View Telemetry",
142                                            theme.welcome.usage_note.text.clone(),
143                                        )
144                                        .contained()
145                                        .with_style(theme.welcome.usage_note.container),
146                                    ),
147                                &theme.welcome.checkbox,
148                                metrics,
149                                0,
150                                cx,
151                                |_, checked, cx| {
152                                    SettingsFile::update(cx, move |file| {
153                                        file.telemetry.set_metrics(checked)
154                                    })
155                                },
156                            )
157                            .contained()
158                            .with_style(theme.welcome.checkbox_container),
159                        )
160                        .with_child(
161                            theme::ui::checkbox::<Diagnostics, Self, _>(
162                                "Send crash reports",
163                                &theme.welcome.checkbox,
164                                diagnostics,
165                                0,
166                                cx,
167                                |_, checked, cx| {
168                                    SettingsFile::update(cx, move |file| {
169                                        file.telemetry.set_diagnostics(checked)
170                                    })
171                                },
172                            )
173                            .contained()
174                            .with_style(theme.welcome.checkbox_container),
175                        )
176                        .contained()
177                        .with_style(theme.welcome.checkbox_group)
178                        .constrained()
179                        .with_width(width),
180                )
181                .constrained()
182                .with_max_width(width)
183                .contained()
184                .with_uniform_padding(10.)
185                .aligned()
186                .into_any(),
187        )
188        .into_any_named("welcome page")
189    }
190}
191
192impl WelcomePage {
193    pub fn new(cx: &mut ViewContext<Self>) -> Self {
194        WelcomePage {
195            _settings_subscription: cx.observe_global::<Settings, _>(move |_, cx| cx.notify()),
196        }
197    }
198}
199
200impl Item for WelcomePage {
201    fn tab_tooltip_text(&self, _: &AppContext) -> Option<Cow<str>> {
202        Some("Welcome to Zed!".into())
203    }
204
205    fn tab_content<T: View>(
206        &self,
207        _detail: Option<usize>,
208        style: &theme::Tab,
209        _cx: &gpui::AppContext,
210    ) -> AnyElement<T> {
211        Flex::row()
212            .with_child(
213                Label::new("Welcome to Zed!", style.label.clone())
214                    .aligned()
215                    .contained(),
216            )
217            .into_any()
218    }
219
220    fn show_toolbar(&self) -> bool {
221        false
222    }
223    fn clone_on_split(
224        &self,
225        _workspace_id: WorkspaceId,
226        cx: &mut ViewContext<Self>,
227    ) -> Option<Self> {
228        Some(WelcomePage::new(cx))
229    }
230}