1use std::sync::Arc;
2
3use client::{Client, UserStore};
4use cloud_llm_client::Plan;
5use gpui::{Entity, IntoElement, ParentElement};
6use ui::prelude::*;
7
8use crate::ZedAiOnboarding;
9
10pub struct EditPredictionOnboarding {
11 user_store: Entity<UserStore>,
12 client: Arc<Client>,
13 copilot_is_configured: bool,
14 continue_with_zed_ai: Arc<dyn Fn(&mut Window, &mut App)>,
15 continue_with_copilot: Arc<dyn Fn(&mut Window, &mut App)>,
16}
17
18impl EditPredictionOnboarding {
19 pub fn new(
20 user_store: Entity<UserStore>,
21 client: Arc<Client>,
22 copilot_is_configured: bool,
23 continue_with_zed_ai: Arc<dyn Fn(&mut Window, &mut App)>,
24 continue_with_copilot: Arc<dyn Fn(&mut Window, &mut App)>,
25 _cx: &mut Context<Self>,
26 ) -> Self {
27 Self {
28 user_store,
29 copilot_is_configured,
30 client,
31 continue_with_zed_ai,
32 continue_with_copilot,
33 }
34 }
35}
36
37impl Render for EditPredictionOnboarding {
38 fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
39 let is_free_plan = self.user_store.read(cx).plan() == Some(Plan::ZedFree);
40
41 let github_copilot = v_flex()
42 .gap_1()
43 .child(Label::new(if self.copilot_is_configured {
44 "Alternatively, you can continue to use GitHub Copilot as that's already set up."
45 } else {
46 "Alternatively, you can use GitHub Copilot as your edit prediction provider."
47 }))
48 .child(
49 Button::new(
50 "configure-copilot",
51 if self.copilot_is_configured {
52 "Use Copilot"
53 } else {
54 "Configure Copilot"
55 },
56 )
57 .full_width()
58 .style(ButtonStyle::Outlined)
59 .on_click({
60 let callback = self.continue_with_copilot.clone();
61 move |_, window, cx| callback(window, cx)
62 }),
63 );
64
65 v_flex()
66 .gap_2()
67 .child(ZedAiOnboarding::new(
68 self.client.clone(),
69 &self.user_store,
70 self.continue_with_zed_ai.clone(),
71 cx,
72 ))
73 .when(is_free_plan, |this| {
74 this.child(ui::Divider::horizontal()).child(github_copilot)
75 })
76 }
77}