Show provider configuration in EP menu when signed out (#48325)

Max Brunsfeld created

This way, you can configure external EP providers from the EP menu.

Release Notes:

- N/A

Change summary

crates/edit_prediction_ui/src/edit_prediction_button.rs | 117 ++++------
1 file changed, 53 insertions(+), 64 deletions(-)

Detailed changes

crates/edit_prediction_ui/src/edit_prediction_button.rs 🔗

@@ -488,9 +488,8 @@ impl Render for EditPredictionButton {
                 let this = cx.weak_entity();
 
                 let mut popover_menu = PopoverMenu::new("edit-prediction")
-                    .when(user.is_some(), |popover_menu| {
+                    .map(|popover_menu| {
                         let this = this.clone();
-
                         popover_menu.menu(move |window, cx| {
                             this.update(cx, |this, cx| {
                                 this.build_edit_prediction_context_menu(provider, window, cx)
@@ -498,16 +497,6 @@ impl Render for EditPredictionButton {
                             .ok()
                         })
                     })
-                    .when(user.is_none(), |popover_menu| {
-                        let this = this.clone();
-
-                        popover_menu.menu(move |window, cx| {
-                            this.update(cx, |this, cx| {
-                                this.build_zeta_upsell_context_menu(window, cx)
-                            })
-                            .ok()
-                        })
-                    })
                     .anchor(Corner::BottomRight)
                     .with_handle(self.popover_menu_handle.clone());
 
@@ -1036,7 +1025,55 @@ impl EditPredictionButton {
         cx: &mut Context<Self>,
     ) -> Entity<ContextMenu> {
         ContextMenu::build(window, cx, |mut menu, window, cx| {
-            if let Some(usage) = self
+            let user = self.user_store.read(cx).current_user();
+
+            let needs_sign_in = user.is_none()
+                && matches!(
+                    provider,
+                    EditPredictionProvider::None | EditPredictionProvider::Zed
+                );
+
+            if needs_sign_in {
+                menu = menu
+                    .custom_row(move |_window, cx| {
+                        let description = indoc! {
+                            "You get 2,000 accepted suggestions at every keystroke for free, \
+                            powered by Zeta, our open-source, open-data model"
+                        };
+
+                        v_flex()
+                            .max_w_64()
+                            .h(rems_from_px(148.))
+                            .child(render_zeta_tab_animation(cx))
+                            .child(Label::new("Edit Prediction"))
+                            .child(
+                                Label::new(description)
+                                    .color(Color::Muted)
+                                    .size(LabelSize::Small),
+                            )
+                            .into_any_element()
+                    })
+                    .separator()
+                    .entry("Sign In & Start Using", None, |window, cx| {
+                        let client = Client::global(cx);
+                        window
+                            .spawn(cx, async move |cx| {
+                                client
+                                    .sign_in_with_optional_connect(true, &cx)
+                                    .await
+                                    .log_err();
+                            })
+                            .detach();
+                    })
+                    .link(
+                        "Learn More",
+                        OpenBrowser {
+                            url: zed_urls::edit_prediction_docs(cx),
+                        }
+                        .boxed_clone(),
+                    )
+                    .separator();
+            } else if let Some(usage) = self
                 .edit_prediction_provider
                 .as_ref()
                 .and_then(|provider| provider.usage(cx))
@@ -1118,8 +1155,9 @@ impl EditPredictionButton {
                     .separator();
             }
 
-            menu = self.build_language_settings_menu(menu, window, cx);
-
+            if !needs_sign_in {
+                menu = self.build_language_settings_menu(menu, window, cx);
+            }
             menu = self.add_provider_switching_section(menu, provider, cx);
             menu = menu.separator().item(
                 ContextMenuEntry::new("Configure Providers")
@@ -1141,55 +1179,6 @@ impl EditPredictionButton {
         })
     }
 
-    fn build_zeta_upsell_context_menu(
-        &self,
-        window: &mut Window,
-        cx: &mut Context<Self>,
-    ) -> Entity<ContextMenu> {
-        ContextMenu::build(window, cx, |mut menu, _window, cx| {
-            menu = menu
-                .custom_row(move |_window, cx| {
-                    let description = indoc! {
-                        "You get 2,000 accepted suggestions at every keystroke for free, \
-                        powered by Zeta, our open-source, open-data model"
-                    };
-
-                    v_flex()
-                        .max_w_64()
-                        .h(rems_from_px(148.))
-                        .child(render_zeta_tab_animation(cx))
-                        .child(Label::new("Edit Prediction"))
-                        .child(
-                            Label::new(description)
-                                .color(Color::Muted)
-                                .size(LabelSize::Small),
-                        )
-                        .into_any_element()
-                })
-                .separator()
-                .entry("Sign In & Start Using", None, |window, cx| {
-                    let client = Client::global(cx);
-                    window
-                        .spawn(cx, async move |cx| {
-                            client
-                                .sign_in_with_optional_connect(true, &cx)
-                                .await
-                                .log_err();
-                        })
-                        .detach();
-                })
-                .link(
-                    "Learn More",
-                    OpenBrowser {
-                        url: zed_urls::edit_prediction_docs(cx),
-                    }
-                    .boxed_clone(),
-                );
-
-            menu
-        })
-    }
-
     pub fn update_enabled(&mut self, editor: Entity<Editor>, cx: &mut Context<Self>) {
         let editor = editor.read(cx);
         let snapshot = editor.buffer().read(cx).snapshot(cx);