welcome.rs

  1mod base_keymap_picker;
  2
  3use std::sync::Arc;
  4
  5use db::kvp::KEY_VALUE_STORE;
  6use gpui::{
  7    elements::{Flex, Label, ParentElement},
  8    Element, ElementBox, Entity, MutableAppContext, 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 MutableAppContext) {
 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 MutableAppContext) {
 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::RenderContext<'_, Self>) -> ElementBox {
 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_children([
 77                    Flex::column()
 78                        .with_children([
 79                            theme::ui::svg(&theme.welcome.logo)
 80                                .aligned()
 81                                .contained()
 82                                .aligned()
 83                                .boxed(),
 84                            Label::new(
 85                                "Code at the speed of thought",
 86                                theme.welcome.logo_subheading.text.clone(),
 87                            )
 88                            .aligned()
 89                            .contained()
 90                            .with_style(theme.welcome.logo_subheading.container)
 91                            .boxed(),
 92                        ])
 93                        .contained()
 94                        .with_style(theme.welcome.heading_group)
 95                        .constrained()
 96                        .with_width(width)
 97                        .boxed(),
 98                    Flex::column()
 99                        .with_children([
100                            theme::ui::cta_button(
101                                "Choose a theme",
102                                theme_selector::Toggle,
103                                width,
104                                &theme.welcome.button,
105                                cx,
106                            ),
107                            theme::ui::cta_button(
108                                "Choose a keymap",
109                                ToggleBaseKeymapSelector,
110                                width,
111                                &theme.welcome.button,
112                                cx,
113                            ),
114                            theme::ui::cta_button(
115                                "Install the CLI",
116                                install_cli::Install,
117                                width,
118                                &theme.welcome.button,
119                                cx,
120                            ),
121                        ])
122                        .contained()
123                        .with_style(theme.welcome.button_group)
124                        .constrained()
125                        .with_width(width)
126                        .boxed(),
127                    Flex::column()
128                        .with_children([
129                            theme::ui::checkbox_with_label::<Metrics, Self>(
130                                Flex::column()
131                                    .with_children([
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                                        .boxed(),
139                                        Label::new(
140                                            "Help > View Telemetry",
141                                            theme.welcome.usage_note.text.clone(),
142                                        )
143                                        .contained()
144                                        .with_style(theme.welcome.usage_note.container)
145                                        .boxed(),
146                                    ])
147                                    .boxed(),
148                                &theme.welcome.checkbox,
149                                metrics,
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                            .boxed(),
160                            theme::ui::checkbox::<Diagnostics, Self>(
161                                "Send crash reports",
162                                &theme.welcome.checkbox,
163                                diagnostics,
164                                cx,
165                                |checked, cx| {
166                                    SettingsFile::update(cx, move |file| {
167                                        file.telemetry.set_diagnostics(checked)
168                                    })
169                                },
170                            )
171                            .contained()
172                            .with_style(theme.welcome.checkbox_container)
173                            .boxed(),
174                        ])
175                        .contained()
176                        .with_style(theme.welcome.checkbox_group)
177                        .constrained()
178                        .with_width(width)
179                        .boxed(),
180                ])
181                .constrained()
182                .with_max_width(width)
183                .contained()
184                .with_uniform_padding(10.)
185                .aligned()
186                .boxed(),
187        )
188        .boxed()
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_content(
202        &self,
203        _detail: Option<usize>,
204        style: &theme::Tab,
205        _cx: &gpui::AppContext,
206    ) -> gpui::ElementBox {
207        Flex::row()
208            .with_child(
209                Label::new("Welcome to Zed!", style.label.clone())
210                    .aligned()
211                    .contained()
212                    .boxed(),
213            )
214            .boxed()
215    }
216
217    fn show_toolbar(&self) -> bool {
218        false
219    }
220    fn clone_on_split(
221        &self,
222        _workspace_id: WorkspaceId,
223        cx: &mut ViewContext<Self>,
224    ) -> Option<Self> {
225        Some(WelcomePage::new(cx))
226    }
227}