1use edit_prediction::EditPredictionStore;
2use gpui::{
3 DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, IntoElement, ParentElement, Render,
4};
5use ui::{Button, ButtonStyle, Clickable, Headline, HeadlineSize, prelude::*};
6use ui_input::InputField;
7use workspace::ModalView;
8
9pub struct ExternalProviderApiKeyModal {
10 api_key_input: Entity<InputField>,
11 focus_handle: FocusHandle,
12 on_confirm: Box<dyn Fn(Option<String>, &mut EditPredictionStore, &mut App)>,
13}
14
15impl ExternalProviderApiKeyModal {
16 pub fn new(
17 window: &mut Window,
18 cx: &mut Context<Self>,
19 on_confirm: impl Fn(Option<String>, &mut EditPredictionStore, &mut App) + 'static,
20 ) -> Self {
21 let api_key_input = cx.new(|cx| InputField::new(window, cx, "Enter your API key"));
22
23 Self {
24 api_key_input,
25 focus_handle: cx.focus_handle(),
26 on_confirm: Box::new(on_confirm),
27 }
28 }
29
30 fn cancel(&mut self, _: &menu::Cancel, _window: &mut Window, cx: &mut Context<Self>) {
31 cx.emit(DismissEvent);
32 }
33
34 fn confirm(&mut self, _: &menu::Confirm, _window: &mut Window, cx: &mut Context<Self>) {
35 let api_key = self.api_key_input.read(cx).text(cx);
36 let api_key = (!api_key.trim().is_empty()).then_some(api_key);
37
38 if let Some(ep_store) = EditPredictionStore::try_global(cx) {
39 ep_store.update(cx, |ep_store, cx| (self.on_confirm)(api_key, ep_store, cx))
40 }
41
42 cx.emit(DismissEvent);
43 }
44}
45
46impl EventEmitter<DismissEvent> for ExternalProviderApiKeyModal {}
47
48impl ModalView for ExternalProviderApiKeyModal {}
49
50impl Focusable for ExternalProviderApiKeyModal {
51 fn focus_handle(&self, _cx: &App) -> FocusHandle {
52 self.focus_handle.clone()
53 }
54}
55
56impl Render for ExternalProviderApiKeyModal {
57 fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
58 v_flex()
59 .key_context("ExternalApiKeyModal")
60 .on_action(cx.listener(Self::cancel))
61 .on_action(cx.listener(Self::confirm))
62 .elevation_2(cx)
63 .w(px(400.))
64 .p_4()
65 .gap_3()
66 .child(Headline::new("API Token").size(HeadlineSize::Small))
67 .child(self.api_key_input.clone())
68 .child(
69 h_flex()
70 .justify_end()
71 .gap_2()
72 .child(Button::new("cancel", "Cancel").on_click(cx.listener(
73 |_, _, _window, cx| {
74 cx.emit(DismissEvent);
75 },
76 )))
77 .child(
78 Button::new("save", "Save")
79 .style(ButtonStyle::Filled)
80 .on_click(cx.listener(|this, _, window, cx| {
81 this.confirm(&menu::Confirm, window, cx);
82 })),
83 ),
84 )
85 }
86}