From cfd56a744d594e2cb239da47cebc498ca002d659 Mon Sep 17 00:00:00 2001 From: Michael Sloan Date: Thu, 28 Aug 2025 18:22:56 -0600 Subject: [PATCH] zeta: Show update required notification on appropriate window(s) (#37130) To show these notifications, Zeta was being initialized with the initial workspace it's used on - which may not even still exist! This removes a confusing/misleading workspace field from Zeta. Release Notes: - N/A --- .../zed/src/zed/edit_prediction_registry.rs | 9 +-- crates/zeta/src/zeta.rs | 60 +++++++------------ 2 files changed, 22 insertions(+), 47 deletions(-) diff --git a/crates/zed/src/zed/edit_prediction_registry.rs b/crates/zed/src/zed/edit_prediction_registry.rs index bc2d757fd1900ef0c3ce015a33476fd2c9df9eec..7b8b98018e6d6c608574ab81e912e8a98e363046 100644 --- a/crates/zed/src/zed/edit_prediction_registry.rs +++ b/crates/zed/src/zed/edit_prediction_registry.rs @@ -8,7 +8,6 @@ use settings::SettingsStore; use std::{cell::RefCell, rc::Rc, sync::Arc}; use supermaven::{Supermaven, SupermavenCompletionProvider}; use ui::Window; -use workspace::Workspace; use zeta::{ProviderDataCollection, ZetaEditPredictionProvider}; pub fn init(client: Arc, user_store: Entity, cx: &mut App) { @@ -204,13 +203,7 @@ fn assign_edit_prediction_provider( } } - let workspace = window - .root::() - .flatten() - .map(|workspace| workspace.downgrade()); - - let zeta = - zeta::Zeta::register(workspace, worktree, client.clone(), user_store, cx); + let zeta = zeta::Zeta::register(worktree, client.clone(), user_store, cx); if let Some(buffer) = &singleton_buffer && buffer.read(cx).file().is_some() diff --git a/crates/zeta/src/zeta.rs b/crates/zeta/src/zeta.rs index 7b14d1279604bc8915e552a879cb6406f4a3948c..e0cfd23dd26cd7ea49181b5aabc16f00f4fd826a 100644 --- a/crates/zeta/src/zeta.rs +++ b/crates/zeta/src/zeta.rs @@ -24,7 +24,7 @@ use collections::{HashMap, HashSet, VecDeque}; use futures::AsyncReadExt; use gpui::{ App, AppContext as _, AsyncApp, Context, Entity, EntityId, Global, SemanticVersion, - Subscription, Task, WeakEntity, actions, + SharedString, Subscription, Task, actions, }; use http_client::{AsyncBody, HttpClient, Method, Request, Response}; use input_excerpt::excerpt_for_cursor_position; @@ -51,8 +51,7 @@ use telemetry_events::EditPredictionRating; use thiserror::Error; use util::ResultExt; use uuid::Uuid; -use workspace::Workspace; -use workspace::notifications::{ErrorMessagePrompt, NotificationId}; +use workspace::notifications::{ErrorMessagePrompt, NotificationId, show_app_notification}; use worktree::Worktree; const CURSOR_MARKER: &str = "<|user_cursor_is_here|>"; @@ -212,7 +211,6 @@ impl std::fmt::Debug for EditPrediction { } pub struct Zeta { - workspace: Option>, client: Arc, events: VecDeque, registered_buffers: HashMap, @@ -233,14 +231,13 @@ impl Zeta { } pub fn register( - workspace: Option>, worktree: Option>, client: Arc, user_store: Entity, cx: &mut App, ) -> Entity { let this = Self::global(cx).unwrap_or_else(|| { - let entity = cx.new(|cx| Self::new(workspace, client, user_store, cx)); + let entity = cx.new(|cx| Self::new(client, user_store, cx)); cx.set_global(ZetaGlobal(entity.clone())); entity }); @@ -265,19 +262,13 @@ impl Zeta { self.user_store.read(cx).edit_prediction_usage() } - fn new( - workspace: Option>, - client: Arc, - user_store: Entity, - cx: &mut Context, - ) -> Self { + fn new(client: Arc, user_store: Entity, cx: &mut Context) -> Self { let refresh_llm_token_listener = RefreshLlmTokenListener::global(cx); let data_collection_choice = Self::load_data_collection_choices(); let data_collection_choice = cx.new(|_| data_collection_choice); Self { - workspace, client, events: VecDeque::new(), shown_completions: VecDeque::new(), @@ -370,7 +361,6 @@ impl Zeta { fn request_completion_impl( &mut self, - workspace: Option>, project: Option<&Entity>, buffer: &Entity, cursor: language::Anchor, @@ -453,23 +443,20 @@ impl Zeta { zeta.update_required = true; }); - if let Some(workspace) = workspace { - workspace.update(cx, |workspace, cx| { - workspace.show_notification( - NotificationId::unique::(), - cx, - |cx| { - cx.new(|cx| { - ErrorMessagePrompt::new(err.to_string(), cx) - .with_link_button( - "Update Zed", - "https://zed.dev/releases", - ) - }) - }, - ); - }); - } + let error_message: SharedString = err.to_string().into(); + show_app_notification( + NotificationId::unique::(), + cx, + move |cx| { + cx.new(|cx| { + ErrorMessagePrompt::new(error_message.clone(), cx) + .with_link_button( + "Update Zed", + "https://zed.dev/releases", + ) + }) + }, + ); }) .ok(); } @@ -689,7 +676,7 @@ and then another ) -> Task>> { use std::future::ready; - self.request_completion_impl(None, project, buffer, position, false, cx, |_params| { + self.request_completion_impl(project, buffer, position, false, cx, |_params| { ready(Ok((response, None))) }) } @@ -702,12 +689,7 @@ and then another can_collect_data: bool, cx: &mut Context, ) -> Task>> { - let workspace = self - .workspace - .as_ref() - .and_then(|workspace| workspace.upgrade()); self.request_completion_impl( - workspace, project, buffer, position, @@ -2029,7 +2011,7 @@ mod tests { // Construct the fake server to authenticate. let _server = FakeServer::for_client(42, &client, cx).await; let user_store = cx.new(|cx| UserStore::new(client.clone(), cx)); - let zeta = cx.new(|cx| Zeta::new(None, client, user_store.clone(), cx)); + let zeta = cx.new(|cx| Zeta::new(client, user_store.clone(), cx)); let buffer = cx.new(|cx| Buffer::local(buffer_content, cx)); let cursor = buffer.read_with(cx, |buffer, _| buffer.anchor_before(Point::new(1, 0))); @@ -2093,7 +2075,7 @@ mod tests { // Construct the fake server to authenticate. let _server = FakeServer::for_client(42, &client, cx).await; let user_store = cx.new(|cx| UserStore::new(client.clone(), cx)); - let zeta = cx.new(|cx| Zeta::new(None, client, user_store.clone(), cx)); + let zeta = cx.new(|cx| Zeta::new(client, user_store.clone(), cx)); let buffer = cx.new(|cx| Buffer::local(buffer_content, cx)); let snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());