agent_panel_onboarding_content.rs

 1use std::sync::Arc;
 2
 3use client::{Client, UserStore};
 4use cloud_llm_client::{Plan, PlanV1, PlanV2};
 5use gpui::{Entity, IntoElement, ParentElement};
 6use language_model::{LanguageModelRegistry, ZED_CLOUD_PROVIDER_ID};
 7use ui::prelude::*;
 8
 9use crate::{AgentPanelOnboardingCard, ApiKeysWithoutProviders, ZedAiOnboarding};
10
11pub struct AgentPanelOnboarding {
12    user_store: Entity<UserStore>,
13    client: Arc<Client>,
14    has_configured_providers: bool,
15    continue_with_zed_ai: Arc<dyn Fn(&mut Window, &mut App)>,
16}
17
18impl AgentPanelOnboarding {
19    pub fn new(
20        user_store: Entity<UserStore>,
21        client: Arc<Client>,
22        continue_with_zed_ai: impl Fn(&mut Window, &mut App) + 'static,
23        cx: &mut Context<Self>,
24    ) -> Self {
25        cx.subscribe(
26            &LanguageModelRegistry::global(cx),
27            |this: &mut Self, _registry, event: &language_model::Event, cx| match event {
28                language_model::Event::ProviderStateChanged(_)
29                | language_model::Event::AddedProvider(_)
30                | language_model::Event::RemovedProvider(_) => {
31                    this.has_configured_providers = Self::has_configured_providers(cx)
32                }
33                _ => {}
34            },
35        )
36        .detach();
37
38        Self {
39            user_store,
40            client,
41            has_configured_providers: Self::has_configured_providers(cx),
42            continue_with_zed_ai: Arc::new(continue_with_zed_ai),
43        }
44    }
45
46    fn has_configured_providers(cx: &App) -> bool {
47        LanguageModelRegistry::read_global(cx)
48            .providers()
49            .iter()
50            .any(|provider| provider.is_authenticated(cx) && provider.id() != ZED_CLOUD_PROVIDER_ID)
51    }
52}
53
54impl Render for AgentPanelOnboarding {
55    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
56        let enrolled_in_trial = self.user_store.read(cx).plan().is_some_and(|plan| {
57            matches!(
58                plan,
59                Plan::V1(PlanV1::ZedProTrial) | Plan::V2(PlanV2::ZedProTrial)
60            )
61        });
62        let is_pro_user = self.user_store.read(cx).plan().is_some_and(|plan| {
63            matches!(plan, Plan::V1(PlanV1::ZedPro) | Plan::V2(PlanV2::ZedPro))
64        });
65
66        AgentPanelOnboardingCard::new()
67            .child(
68                ZedAiOnboarding::new(
69                    self.client.clone(),
70                    &self.user_store,
71                    self.continue_with_zed_ai.clone(),
72                    cx,
73                )
74                .with_dismiss({
75                    let callback = self.continue_with_zed_ai.clone();
76                    move |window, cx| callback(window, cx)
77                }),
78            )
79            .map(|this| {
80                if enrolled_in_trial || is_pro_user || self.has_configured_providers {
81                    this
82                } else {
83                    this.child(ApiKeysWithoutProviders::new())
84                }
85            })
86    }
87}