1mod base_keymap_picker;
2mod base_keymap_setting;
3
4use db::kvp::KEY_VALUE_STORE;
5use gpui::{
6 div, red, AnyElement, AppContext, Div, EventEmitter, FocusHandle, Focusable, FocusableView,
7 InteractiveElement, ParentElement, Render, Styled, Subscription, View, ViewContext,
8 VisualContext, WeakView, WindowContext,
9};
10use settings::{Settings, SettingsStore};
11use std::sync::Arc;
12use ui::prelude::*;
13use workspace::{
14 dock::DockPosition,
15 item::{Item, ItemEvent},
16 open_new, AppState, Welcome, Workspace, WorkspaceId,
17};
18
19pub use base_keymap_setting::BaseKeymap;
20
21pub const FIRST_OPEN: &str = "first_open";
22
23pub fn init(cx: &mut AppContext) {
24 BaseKeymap::register(cx);
25
26 cx.observe_new_views(|workspace: &mut Workspace, _cx| {
27 workspace.register_action(|workspace, _: &Welcome, cx| {
28 let welcome_page = cx.build_view(|cx| WelcomePage::new(workspace, cx));
29 workspace.add_item(Box::new(welcome_page), cx)
30 });
31 })
32 .detach();
33
34 base_keymap_picker::init(cx);
35}
36
37pub fn show_welcome_experience(app_state: &Arc<AppState>, cx: &mut AppContext) {
38 open_new(&app_state, cx, |workspace, cx| {
39 workspace.toggle_dock(DockPosition::Left, cx);
40 let welcome_page = cx.build_view(|cx| WelcomePage::new(workspace, cx));
41 workspace.add_item_to_center(Box::new(welcome_page.clone()), cx);
42 cx.focus_view(&welcome_page);
43 cx.notify();
44 })
45 .detach();
46
47 db::write_and_log(cx, || {
48 KEY_VALUE_STORE.write_kvp(FIRST_OPEN.to_string(), "false".to_string())
49 });
50}
51
52pub struct WelcomePage {
53 workspace: WeakView<Workspace>,
54 focus_handle: FocusHandle,
55 _settings_subscription: Subscription,
56}
57
58impl Render for WelcomePage {
59 type Element = Focusable<Div>;
60
61 fn render(&mut self, _cx: &mut gpui::ViewContext<Self>) -> Self::Element {
62 // todo!(welcome_ui)
63 // let self_handle = cx.handle();
64 // let theme = cx.theme();
65 // let width = theme.welcome.page_width;
66
67 // let telemetry_settings = TelemetrySettings::get(None, cx);
68 // let vim_mode_setting = VimModeSettings::get(cx);
69
70 div()
71 .track_focus(&self.focus_handle)
72 .child(div().size_full().bg(red()).child("Welcome!"))
73 //todo!()
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::<Diagnostics, Self, _>(
151 // "Enable vim mode",
152 // &theme.welcome.checkbox,
153 // vim_mode_setting,
154 // 0,
155 // cx,
156 // |this, checked, cx| {
157 // if let Some(workspace) = this.workspace.upgrade(cx) {
158 // let fs = workspace.read(cx).app_state().fs.clone();
159 // update_settings_file::<VimModeSetting>(
160 // fs,
161 // cx,
162 // move |setting| *setting = Some(checked),
163 // )
164 // }
165 // },
166 // )
167 // .contained()
168 // .with_style(theme.welcome.checkbox_container),
169 // )
170 // .with_child(
171 // theme::ui::checkbox_with_label::<Metrics, _, Self, _>(
172 // Flex::column()
173 // .with_child(
174 // Label::new(
175 // "Send anonymous usage data",
176 // theme.welcome.checkbox.label.text.clone(),
177 // )
178 // .contained()
179 // .with_style(theme.welcome.checkbox.label.container),
180 // )
181 // .with_child(
182 // Label::new(
183 // "Help > View Telemetry",
184 // theme.welcome.usage_note.text.clone(),
185 // )
186 // .contained()
187 // .with_style(theme.welcome.usage_note.container),
188 // ),
189 // &theme.welcome.checkbox,
190 // telemetry_settings.metrics,
191 // 0,
192 // cx,
193 // |this, checked, cx| {
194 // if let Some(workspace) = this.workspace.upgrade(cx) {
195 // let fs = workspace.read(cx).app_state().fs.clone();
196 // update_settings_file::<TelemetrySettings>(
197 // fs,
198 // cx,
199 // move |setting| setting.metrics = Some(checked),
200 // )
201 // }
202 // },
203 // )
204 // .contained()
205 // .with_style(theme.welcome.checkbox_container),
206 // )
207 // .with_child(
208 // theme::ui::checkbox::<Diagnostics, Self, _>(
209 // "Send crash reports",
210 // &theme.welcome.checkbox,
211 // telemetry_settings.diagnostics,
212 // 1,
213 // cx,
214 // |this, checked, cx| {
215 // if let Some(workspace) = this.workspace.upgrade(cx) {
216 // let fs = workspace.read(cx).app_state().fs.clone();
217 // update_settings_file::<TelemetrySettings>(
218 // fs,
219 // cx,
220 // move |setting| setting.diagnostics = Some(checked),
221 // )
222 // }
223 // },
224 // )
225 // .contained()
226 // .with_style(theme.welcome.checkbox_container),
227 // )
228 // .contained()
229 // .with_style(theme.welcome.checkbox_group)
230 // .constrained()
231 // .with_width(width),
232 // )
233 // .constrained()
234 // .with_max_width(width)
235 // .contained()
236 // .with_uniform_padding(10.)
237 // .aligned()
238 // .into_any(),
239 // )
240 // .into_any_named("welcome page")
241 }
242}
243
244impl WelcomePage {
245 pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
246 WelcomePage {
247 focus_handle: cx.focus_handle(),
248 workspace: workspace.weak_handle(),
249 _settings_subscription: cx.observe_global::<SettingsStore>(move |_, cx| cx.notify()),
250 }
251 }
252}
253
254impl EventEmitter<ItemEvent> for WelcomePage {}
255
256impl FocusableView for WelcomePage {
257 fn focus_handle(&self, _: &AppContext) -> gpui::FocusHandle {
258 self.focus_handle.clone()
259 }
260}
261
262impl Item for WelcomePage {
263 type Event = ItemEvent;
264
265 fn tab_content(&self, _: Option<usize>, selected: bool, _: &WindowContext) -> AnyElement {
266 Label::new("Welcome to Zed!")
267 .color(if selected {
268 Color::Default
269 } else {
270 Color::Muted
271 })
272 .into_any_element()
273 }
274
275 fn show_toolbar(&self) -> bool {
276 false
277 }
278
279 fn clone_on_split(
280 &self,
281 _workspace_id: WorkspaceId,
282 cx: &mut ViewContext<Self>,
283 ) -> Option<View<Self>> {
284 Some(cx.build_view(|cx| WelcomePage {
285 focus_handle: cx.focus_handle(),
286 workspace: self.workspace.clone(),
287 _settings_subscription: cx.observe_global::<SettingsStore>(move |_, cx| cx.notify()),
288 }))
289 }
290
291 fn to_item_events(event: &Self::Event, mut f: impl FnMut(workspace::item::ItemEvent)) {
292 f(*event)
293 }
294}