1mod edit_prediction_button;
2mod edit_prediction_context_view;
3mod rate_prediction_modal;
4
5use std::any::{Any as _, TypeId};
6
7use command_palette_hooks::CommandPaletteFilter;
8use edit_prediction::{ResetOnboarding, Zeta2FeatureFlag};
9use edit_prediction_context_view::EditPredictionContextView;
10use feature_flags::FeatureFlagAppExt as _;
11use gpui::actions;
12use project::DisableAiSettings;
13use rate_prediction_modal::RatePredictionsModal;
14use settings::{Settings as _, SettingsStore};
15use ui::{App, prelude::*};
16use workspace::{SplitDirection, Workspace};
17
18pub use edit_prediction_button::{EditPredictionButton, ToggleMenu};
19
20use crate::rate_prediction_modal::PredictEditsRatePredictionsFeatureFlag;
21
22actions!(
23 dev,
24 [
25 /// Opens the edit prediction context view.
26 OpenEditPredictionContextView,
27 ]
28);
29
30actions!(
31 edit_prediction,
32 [
33 /// Opens the rate completions modal.
34 RatePredictions,
35 ]
36);
37
38pub fn init(cx: &mut App) {
39 feature_gate_predict_edits_actions(cx);
40
41 cx.observe_new(move |workspace: &mut Workspace, _, _cx| {
42 workspace.register_action(|workspace, _: &RatePredictions, window, cx| {
43 if cx.has_flag::<PredictEditsRatePredictionsFeatureFlag>() {
44 RatePredictionsModal::toggle(workspace, window, cx);
45 }
46 });
47
48 workspace.register_action_renderer(|div, _, _, cx| {
49 let has_flag = cx.has_flag::<Zeta2FeatureFlag>();
50 div.when(has_flag, |div| {
51 div.on_action(cx.listener(
52 move |workspace, _: &OpenEditPredictionContextView, window, cx| {
53 let project = workspace.project();
54 workspace.split_item(
55 SplitDirection::Right,
56 Box::new(cx.new(|cx| {
57 EditPredictionContextView::new(
58 project.clone(),
59 workspace.client(),
60 workspace.user_store(),
61 window,
62 cx,
63 )
64 })),
65 window,
66 cx,
67 );
68 },
69 ))
70 })
71 });
72 })
73 .detach();
74}
75
76fn feature_gate_predict_edits_actions(cx: &mut App) {
77 let rate_completion_action_types = [TypeId::of::<RatePredictions>()];
78 let reset_onboarding_action_types = [TypeId::of::<ResetOnboarding>()];
79 let all_action_types = [
80 TypeId::of::<RatePredictions>(),
81 TypeId::of::<edit_prediction::ResetOnboarding>(),
82 zed_actions::OpenZedPredictOnboarding.type_id(),
83 TypeId::of::<edit_prediction::ClearHistory>(),
84 TypeId::of::<rate_prediction_modal::ThumbsUpActivePrediction>(),
85 TypeId::of::<rate_prediction_modal::ThumbsDownActivePrediction>(),
86 TypeId::of::<rate_prediction_modal::NextEdit>(),
87 TypeId::of::<rate_prediction_modal::PreviousEdit>(),
88 ];
89
90 CommandPaletteFilter::update_global(cx, |filter, _cx| {
91 filter.hide_action_types(&rate_completion_action_types);
92 filter.hide_action_types(&reset_onboarding_action_types);
93 filter.hide_action_types(&[zed_actions::OpenZedPredictOnboarding.type_id()]);
94 });
95
96 cx.observe_global::<SettingsStore>(move |cx| {
97 let is_ai_disabled = DisableAiSettings::get_global(cx).disable_ai;
98 let has_feature_flag = cx.has_flag::<PredictEditsRatePredictionsFeatureFlag>();
99
100 CommandPaletteFilter::update_global(cx, |filter, _cx| {
101 if is_ai_disabled {
102 filter.hide_action_types(&all_action_types);
103 } else if has_feature_flag {
104 filter.show_action_types(&rate_completion_action_types);
105 } else {
106 filter.hide_action_types(&rate_completion_action_types);
107 }
108 });
109 })
110 .detach();
111
112 cx.observe_flag::<PredictEditsRatePredictionsFeatureFlag, _>(move |is_enabled, cx| {
113 if !DisableAiSettings::get_global(cx).disable_ai {
114 if is_enabled {
115 CommandPaletteFilter::update_global(cx, |filter, _cx| {
116 filter.show_action_types(&rate_completion_action_types);
117 });
118 } else {
119 CommandPaletteFilter::update_global(cx, |filter, _cx| {
120 filter.hide_action_types(&rate_completion_action_types);
121 });
122 }
123 }
124 })
125 .detach();
126}