Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T04:13:18.664Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

onboarding_modal.rs

151 lines · 5.5 KB · rust
1use std::sync::Arc;
2
3use crate::{EditPredictionStore, ZedPredictUpsell};
4use ai_onboarding::EditPredictionOnboarding;
5use db::kvp::Dismissable;
6use fs::Fs;
7use gpui::{
8    ClickEvent, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, MouseDownEvent, Render,
9    linear_color_stop, linear_gradient,
10};
11use language::language_settings::EditPredictionProvider;
12use settings::update_settings_file;
13use ui::prelude::*;
14use workspace::{ModalView, Workspace};
15
16#[macro_export]
17macro_rules! onboarding_event {
18    ($name:expr) => {
19        telemetry::event!($name, source = "Edit Prediction Onboarding");
20    };
21    ($name:expr, $($key:ident $(= $value:expr)?),+ $(,)?) => {
22        telemetry::event!($name, source = "Edit Prediction Onboarding", $($key $(= $value)?),+);
23    };
24}
25
26/// Introduces user to Zed's Edit Prediction feature
27pub struct ZedPredictModal {
28    onboarding: Entity<EditPredictionOnboarding>,
29    focus_handle: FocusHandle,
30}
31
32pub(crate) fn set_edit_prediction_provider(provider: EditPredictionProvider, cx: &mut App) {
33    let fs = <dyn Fs>::global(cx);
34    update_settings_file(fs, cx, move |settings, _| {
35        settings
36            .project
37            .all_languages
38            .edit_predictions
39            .get_or_insert(Default::default())
40            .provider = Some(provider);
41    });
42}
43
44impl ZedPredictModal {
45    pub fn toggle(workspace: &mut Workspace, window: &mut Window, cx: &mut Context<Workspace>) {
46        let project = workspace.project().clone();
47        workspace.toggle_modal(window, cx, |_window, cx| {
48            let weak_entity = cx.weak_entity();
49            let copilot = EditPredictionStore::try_global(cx)
50                .and_then(|store| store.read(cx).copilot_for_project(&project));
51            Self {
52                onboarding: cx.new(|cx| {
53                    EditPredictionOnboarding::new(
54                        copilot
55                            .as_ref()
56                            .is_some_and(|copilot| copilot.read(cx).status().is_configured()),
57                        Arc::new({
58                            let this = weak_entity.clone();
59                            move |window, cx| {
60                                ZedPredictUpsell::set_dismissed(true, cx);
61                                set_edit_prediction_provider(EditPredictionProvider::Copilot, cx);
62                                this.update(cx, |_, cx| cx.emit(DismissEvent)).ok();
63                                if let Some(copilot) = copilot.clone() {
64                                    copilot_ui::initiate_sign_in(copilot, window, cx);
65                                }
66                            }
67                        }),
68                        cx,
69                    )
70                }),
71                focus_handle: cx.focus_handle(),
72            }
73        });
74    }
75
76    fn cancel(&mut self, _: &menu::Cancel, _: &mut Window, cx: &mut Context<Self>) {
77        ZedPredictUpsell::set_dismissed(true, cx);
78        cx.emit(DismissEvent);
79    }
80}
81
82impl EventEmitter<DismissEvent> for ZedPredictModal {}
83
84impl Focusable for ZedPredictModal {
85    fn focus_handle(&self, _cx: &App) -> FocusHandle {
86        self.focus_handle.clone()
87    }
88}
89
90impl ModalView for ZedPredictModal {
91    fn on_before_dismiss(
92        &mut self,
93        _window: &mut Window,
94        cx: &mut Context<Self>,
95    ) -> workspace::DismissDecision {
96        ZedPredictUpsell::set_dismissed(true, cx);
97        workspace::DismissDecision::Dismiss(true)
98    }
99}
100
101impl Render for ZedPredictModal {
102    fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
103        let window_height = window.viewport_size().height;
104        let max_height = window_height - px(200.);
105        let color = cx.theme().colors();
106
107        v_flex()
108            .id("edit-prediction-onboarding")
109            .key_context("ZedPredictModal")
110            .relative()
111            .w(px(550.))
112            .h_full()
113            .max_h(max_height)
114            .p_1()
115            .gap_2()
116            .elevation_3(cx)
117            .track_focus(&self.focus_handle(cx))
118            .overflow_hidden()
119            .on_action(cx.listener(Self::cancel))
120            .on_action(cx.listener(|_, _: &menu::Cancel, _window, cx| {
121                onboarding_event!("Cancelled", trigger = "Action");
122                cx.emit(DismissEvent);
123            }))
124            .on_any_mouse_down(cx.listener(|this, _: &MouseDownEvent, window, cx| {
125                this.focus_handle.focus(window, cx);
126            }))
127            .child(
128                div()
129                    .p_3()
130                    .size_full()
131                    .border_1()
132                    .border_color(cx.theme().colors().border)
133                    .rounded(px(5.))
134                    .bg(linear_gradient(
135                        360.,
136                        linear_color_stop(color.panel_background, 1.0),
137                        linear_color_stop(color.editor_background, 0.45),
138                    ))
139                    .child(self.onboarding.clone()),
140            )
141            .child(h_flex().absolute().top_3().right_3().child(
142                IconButton::new("cancel", IconName::Close).on_click(cx.listener(
143                    |_, _: &ClickEvent, _window, cx| {
144                        onboarding_event!("Cancelled", trigger = "X click");
145                        cx.emit(DismissEvent);
146                    },
147                )),
148            ))
149    }
150}
151
Served at tenant.openagents/omega Member data and write actions are omitted.