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, WeakViewHandle,
  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(|cx| WelcomePage::new(workspace, cx));
 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(workspace, 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    workspace: WeakViewHandle<Workspace>,
 47    _settings_subscription: Subscription,
 48}
 49
 50impl Entity for WelcomePage {
 51    type Event = ();
 52}
 53
 54impl View for WelcomePage {
 55    fn ui_name() -> &'static str {
 56        "WelcomePage"
 57    }
 58
 59    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> AnyElement<Self> {
 60        let self_handle = cx.handle();
 61        let settings = cx.global::<Settings>();
 62        let theme = settings.theme.clone();
 63
 64        let width = theme.welcome.page_width;
 65
 66        let (diagnostics, metrics) = {
 67            let telemetry = settings.telemetry();
 68            (telemetry.diagnostics(), telemetry.metrics())
 69        };
 70
 71        enum Metrics {}
 72        enum Diagnostics {}
 73
 74        PaneBackdrop::new(
 75            self_handle.id(),
 76            Flex::column()
 77                .with_child(
 78                    Flex::column()
 79                        .with_child(
 80                            theme::ui::svg(&theme.welcome.logo)
 81                                .aligned()
 82                                .contained()
 83                                .aligned(),
 84                        )
 85                        .with_child(
 86                            Label::new(
 87                                "Code at the speed of thought",
 88                                theme.welcome.logo_subheading.text.clone(),
 89                            )
 90                            .aligned()
 91                            .contained()
 92                            .with_style(theme.welcome.logo_subheading.container),
 93                        )
 94                        .contained()
 95                        .with_style(theme.welcome.heading_group)
 96                        .constrained()
 97                        .with_width(width),
 98                )
 99                .with_child(
100                    Flex::column()
101                        .with_child(theme::ui::cta_button::<theme_selector::Toggle, _, _, _>(
102                            "Choose a theme",
103                            width,
104                            &theme.welcome.button,
105                            cx,
106                            |_, this, cx| {
107                                if let Some(workspace) = this.workspace.upgrade(cx) {
108                                    workspace.update(cx, |workspace, cx| {
109                                        theme_selector::toggle(workspace, &Default::default(), cx)
110                                    })
111                                }
112                            },
113                        ))
114                        .with_child(theme::ui::cta_button::<ToggleBaseKeymapSelector, _, _, _>(
115                            "Choose a keymap",
116                            width,
117                            &theme.welcome.button,
118                            cx,
119                            |_, this, cx| {
120                                if let Some(workspace) = this.workspace.upgrade(cx) {
121                                    workspace.update(cx, |workspace, cx| {
122                                        base_keymap_picker::toggle(
123                                            workspace,
124                                            &Default::default(),
125                                            cx,
126                                        )
127                                    })
128                                }
129                            },
130                        ))
131                        .with_child(theme::ui::cta_button::<install_cli::Install, _, _, _>(
132                            "Install the CLI",
133                            width,
134                            &theme.welcome.button,
135                            cx,
136                            |_, _, cx| {
137                                cx.app_context()
138                                    .spawn(|cx| async move { install_cli::install_cli(&cx).await })
139                                    .detach_and_log_err(cx);
140                            },
141                        ))
142                        .contained()
143                        .with_style(theme.welcome.button_group)
144                        .constrained()
145                        .with_width(width),
146                )
147                .with_child(
148                    Flex::column()
149                        .with_child(
150                            theme::ui::checkbox_with_label::<Metrics, _, Self, _>(
151                                Flex::column()
152                                    .with_child(
153                                        Label::new(
154                                            "Send anonymous usage data",
155                                            theme.welcome.checkbox.label.text.clone(),
156                                        )
157                                        .contained()
158                                        .with_style(theme.welcome.checkbox.label.container),
159                                    )
160                                    .with_child(
161                                        Label::new(
162                                            "Help > View Telemetry",
163                                            theme.welcome.usage_note.text.clone(),
164                                        )
165                                        .contained()
166                                        .with_style(theme.welcome.usage_note.container),
167                                    ),
168                                &theme.welcome.checkbox,
169                                metrics,
170                                0,
171                                cx,
172                                |_, checked, cx| {
173                                    SettingsFile::update(cx, move |file| {
174                                        file.telemetry.set_metrics(checked)
175                                    })
176                                },
177                            )
178                            .contained()
179                            .with_style(theme.welcome.checkbox_container),
180                        )
181                        .with_child(
182                            theme::ui::checkbox::<Diagnostics, Self, _>(
183                                "Send crash reports",
184                                &theme.welcome.checkbox,
185                                diagnostics,
186                                0,
187                                cx,
188                                |_, checked, cx| {
189                                    SettingsFile::update(cx, move |file| {
190                                        file.telemetry.set_diagnostics(checked)
191                                    })
192                                },
193                            )
194                            .contained()
195                            .with_style(theme.welcome.checkbox_container),
196                        )
197                        .contained()
198                        .with_style(theme.welcome.checkbox_group)
199                        .constrained()
200                        .with_width(width),
201                )
202                .constrained()
203                .with_max_width(width)
204                .contained()
205                .with_uniform_padding(10.)
206                .aligned()
207                .into_any(),
208        )
209        .into_any_named("welcome page")
210    }
211}
212
213impl WelcomePage {
214    pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
215        WelcomePage {
216            workspace: workspace.weak_handle(),
217            _settings_subscription: cx.observe_global::<Settings, _>(move |_, cx| cx.notify()),
218        }
219    }
220}
221
222impl Item for WelcomePage {
223    fn tab_tooltip_text(&self, _: &AppContext) -> Option<Cow<str>> {
224        Some("Welcome to Zed!".into())
225    }
226
227    fn tab_content<T: View>(
228        &self,
229        _detail: Option<usize>,
230        style: &theme::Tab,
231        _cx: &gpui::AppContext,
232    ) -> AnyElement<T> {
233        Flex::row()
234            .with_child(
235                Label::new("Welcome to Zed!", style.label.clone())
236                    .aligned()
237                    .contained(),
238            )
239            .into_any()
240    }
241
242    fn show_toolbar(&self) -> bool {
243        false
244    }
245
246    fn clone_on_split(
247        &self,
248        _workspace_id: WorkspaceId,
249        cx: &mut ViewContext<Self>,
250    ) -> Option<Self> {
251        Some(WelcomePage {
252            workspace: self.workspace.clone(),
253            _settings_subscription: cx.observe_global::<Settings, _>(move |_, cx| cx.notify()),
254        })
255    }
256}