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                                cx,
150                                |checked, cx| {
151                                    SettingsFile::update(cx, move |file| {
152                                        file.telemetry.set_metrics(checked)
153                                    })
154                                },
155                            )
156                            .contained()
157                            .with_style(theme.welcome.checkbox_container),
158                        )
159                        .with_child(
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                        )
174                        .contained()
175                        .with_style(theme.welcome.checkbox_group)
176                        .constrained()
177                        .with_width(width),
178                )
179                .constrained()
180                .with_max_width(width)
181                .contained()
182                .with_uniform_padding(10.)
183                .aligned()
184                .into_any(),
185        )
186        .into_any_named("welcome page")
187    }
188}
189
190impl WelcomePage {
191    pub fn new(cx: &mut ViewContext<Self>) -> Self {
192        WelcomePage {
193            _settings_subscription: cx.observe_global::<Settings, _>(move |_, cx| cx.notify()),
194        }
195    }
196}
197
198impl Item for WelcomePage {
199    fn tab_tooltip_text(&self, _: &AppContext) -> Option<Cow<str>> {
200        Some("Welcome to Zed!".into())
201    }
202
203    fn tab_content<T: View>(
204        &self,
205        _detail: Option<usize>,
206        style: &theme::Tab,
207        _cx: &gpui::AppContext,
208    ) -> AnyElement<T> {
209        Flex::row()
210            .with_child(
211                Label::new("Welcome to Zed!", style.label.clone())
212                    .aligned()
213                    .contained(),
214            )
215            .into_any()
216    }
217
218    fn show_toolbar(&self) -> bool {
219        false
220    }
221    fn clone_on_split(
222        &self,
223        _workspace_id: WorkspaceId,
224        cx: &mut ViewContext<Self>,
225    ) -> Option<Self> {
226        Some(WelcomePage::new(cx))
227    }
228}