diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs index 13aa904b5c..ce7307e845 100644 --- a/crates/copilot/src/copilot.rs +++ b/crates/copilot/src/copilot.rs @@ -443,7 +443,7 @@ impl Copilot { } } - fn sign_in(&mut self, cx: &mut ModelContext) -> Task> { + pub fn sign_in(&mut self, cx: &mut ModelContext) -> Task> { if let CopilotServer::Running(server) = &mut self.server { let task = match &server.sign_in_status { SignInStatus::Authorized { .. } | SignInStatus::Unauthorized { .. } => { diff --git a/crates/copilot_button/src/copilot_button.rs b/crates/copilot_button/src/copilot_button.rs index df75dca51c..7a9b6eccf0 100644 --- a/crates/copilot_button/src/copilot_button.rs +++ b/crates/copilot_button/src/copilot_button.rs @@ -10,12 +10,13 @@ use gpui::{ ViewHandle, }; use settings::{settings_file::SettingsFile, Settings}; +use util::ResultExt; use workspace::{ - item::ItemHandle, notifications::simple_message_notification::OsOpen, DismissToast, - StatusItemView, + item::ItemHandle, notifications::simple_message_notification::OsOpen, StatusItemView, Toast, + Workspace, }; -use copilot::{Copilot, Reinstall, SignIn, SignOut, Status}; +use copilot::{Copilot, Reinstall, SignOut, Status}; const COPILOT_SETTINGS_URL: &str = "https://github.com/settings/copilot"; const COPILOT_STARTING_TOAST_ID: usize = 1337; @@ -101,41 +102,43 @@ pub fn init(cx: &mut AppContext) { match status { Status::Starting { task } => { - cx.dispatch_action(workspace::Toast::new( - COPILOT_STARTING_TOAST_ID, - "Copilot is starting...", - )); - let window_id = cx.window_id(); - let task = task.to_owned(); - cx.spawn(|handle, mut cx| async move { + let Some(workspace) = cx.root_view().clone().downcast::() else { + return; + }; + + workspace.update(cx, |workspace, cx| { + workspace.show_toast( + Toast::new(COPILOT_STARTING_TOAST_ID, "Copilot is starting..."), + cx, + ) + }); + let workspace = workspace.downgrade(); + cx.spawn(|_, mut cx| async move { task.await; - cx.update(|cx| { - if let Some(copilot) = Copilot::global(cx) { - let status = copilot.read(cx).status(); - match status { - Status::Authorized => cx.dispatch_action_at( - window_id, - handle.id(), - workspace::Toast::new( - COPILOT_STARTING_TOAST_ID, - "Copilot has started!", - ), + if let Some(copilot) = cx.read(Copilot::global) { + workspace + .update(&mut cx, |workspace, cx| match copilot.read(cx).status() { + Status::Authorized => workspace.show_toast( + Toast::new(COPILOT_STARTING_TOAST_ID, "Copilot has started!"), + cx, ), _ => { - cx.dispatch_action_at( - window_id, - handle.id(), - DismissToast::new(COPILOT_STARTING_TOAST_ID), - ); - cx.dispatch_action_at(window_id, handle.id(), SignIn) + workspace.dismiss_toast(COPILOT_STARTING_TOAST_ID, cx); + copilot + .update(cx, |copilot, cx| copilot.sign_in(cx)) + .detach_and_log_err(cx); } - } - } - }) + }) + .log_err(); + } }) .detach(); } - _ => cx.dispatch_action(SignIn), + _ => { + copilot + .update(cx, |copilot, cx| copilot.sign_in(cx)) + .detach_and_log_err(cx); + } } }) } @@ -219,12 +222,22 @@ impl View for CopilotButton { let status = status.clone(); move |_, _, cx| match status { Status::Authorized => cx.dispatch_action(DeployCopilotMenu), - Status::Error(ref e) => cx.dispatch_action(workspace::Toast::new_action( - COPILOT_ERROR_TOAST_ID, - format!("Copilot can't be started: {}", e), - "Reinstall Copilot", - Reinstall, - )), + Status::Error(ref e) => { + if let Some(workspace) = cx.root_view().clone().downcast::() + { + workspace.update(cx, |workspace, cx| { + workspace.show_toast( + Toast::new_action( + COPILOT_ERROR_TOAST_ID, + format!("Copilot can't be started: {}", e), + "Reinstall Copilot", + Reinstall, + ), + cx, + ); + }); + } + } _ => cx.dispatch_action(DeployCopilotStartMenu), } }) diff --git a/crates/workspace/src/notifications.rs b/crates/workspace/src/notifications.rs index 05f8e98acd..57749a5c2b 100644 --- a/crates/workspace/src/notifications.rs +++ b/crates/workspace/src/notifications.rs @@ -1,9 +1,7 @@ -use std::{any::TypeId, ops::DerefMut}; - +use crate::{Toast, Workspace}; use collections::HashSet; use gpui::{AnyViewHandle, AppContext, Entity, View, ViewContext, ViewHandle}; - -use crate::Workspace; +use std::{any::TypeId, ops::DerefMut}; pub fn init(cx: &mut AppContext) { cx.set_global(NotificationTracker::new()); @@ -113,6 +111,28 @@ impl Workspace { self.dismiss_notification_internal(type_id, id, cx) } + pub fn show_toast(&mut self, toast: Toast, cx: &mut ViewContext) { + self.dismiss_notification::(toast.id, cx); + self.show_notification(toast.id, cx, |cx| { + cx.add_view(|_cx| match &toast.click { + Some((click_msg, action)) => { + simple_message_notification::MessageNotification::new_boxed_action( + toast.msg.clone(), + action.boxed_clone(), + click_msg.clone(), + ) + } + None => { + simple_message_notification::MessageNotification::new_message(toast.msg.clone()) + } + }) + }) + } + + pub fn dismiss_toast(&mut self, id: usize, cx: &mut ViewContext) { + self.dismiss_notification::(id, cx); + } + fn dismiss_notification_internal( &mut self, type_id: TypeId, diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index b71de516fd..420d5adc63 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -220,17 +220,6 @@ impl Clone for Toast { } } -#[derive(Clone, PartialEq)] -pub struct DismissToast { - id: usize, -} - -impl DismissToast { - pub fn new(id: usize) -> Self { - DismissToast { id } - } -} - pub type WorkspaceId = i64; impl_internal_actions!( @@ -244,8 +233,6 @@ impl_internal_actions!( SplitWithItem, SplitWithProjectEntry, OpenProjectEntryInPane, - Toast, - DismissToast ] ); impl_actions!(workspace, [ActivatePane]); @@ -431,24 +418,6 @@ pub fn init(app_state: Arc, cx: &mut AppContext) { .detach(); }); - cx.add_action(|workspace: &mut Workspace, alert: &Toast, cx| { - workspace.dismiss_notification::(alert.id, cx); - workspace.show_notification(alert.id, cx, |cx| { - cx.add_view(|_cx| match &alert.click { - Some((click_msg, action)) => MessageNotification::new_boxed_action( - alert.msg.clone(), - action.boxed_clone(), - click_msg.clone(), - ), - None => MessageNotification::new_message(alert.msg.clone()), - }) - }) - }); - - cx.add_action(|workspace: &mut Workspace, alert: &DismissToast, cx| { - workspace.dismiss_notification::(alert.id, cx); - }); - let client = &app_state.client; client.add_view_request_handler(Workspace::handle_follow); client.add_view_message_handler(Workspace::handle_unfollow);