Use the `MessageNotification` component for the release notes toast (#25013)

Danilo Leal and smit created

Closes https://github.com/zed-industries/zed/issues/24981

Release Notes:

- N/A

---------

Co-authored-by: smit <0xtimsb@gmail.com>

Change summary

Cargo.lock                                       |  1 
crates/auto_update_ui/Cargo.toml                 |  1 
crates/auto_update_ui/src/auto_update_ui.rs      | 27 ++++--
crates/auto_update_ui/src/update_notification.rs | 70 ------------------
crates/workspace/src/notifications.rs            |  2 
5 files changed, 20 insertions(+), 81 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -1142,7 +1142,6 @@ dependencies = [
  "gpui",
  "http_client",
  "markdown_preview",
- "menu",
  "release_channel",
  "serde",
  "serde_json",

crates/auto_update_ui/Cargo.toml 🔗

@@ -19,7 +19,6 @@ editor.workspace = true
 gpui.workspace = true
 http_client.workspace = true
 markdown_preview.workspace = true
-menu.workspace = true
 release_channel.workspace = true
 serde.workspace = true
 serde_json.workspace = true

crates/auto_update_ui/src/auto_update_ui.rs 🔗

@@ -1,19 +1,17 @@
-mod update_notification;
-
 use auto_update::AutoUpdater;
+use client::proto::UpdateNotification;
 use editor::{Editor, MultiBuffer};
-use gpui::{actions, prelude::*, App, Context, Entity, SharedString, Window};
+use gpui::{actions, prelude::*, App, Context, DismissEvent, Entity, SharedString, Window};
 use http_client::HttpClient;
 use markdown_preview::markdown_preview_view::{MarkdownPreviewMode, MarkdownPreviewView};
 use release_channel::{AppVersion, ReleaseChannel};
 use serde::Deserialize;
 use smol::io::AsyncReadExt;
 use util::ResultExt as _;
+use workspace::notifications::simple_message_notification::MessageNotification;
 use workspace::notifications::{show_app_notification, NotificationId};
 use workspace::Workspace;
 
-use crate::update_notification::UpdateNotification;
-
 actions!(auto_update, [ViewReleaseNotesLocally]);
 
 pub fn init(cx: &mut App) {
@@ -131,19 +129,32 @@ pub fn notify_if_app_was_updated(cx: &mut App) {
     let Some(updater) = AutoUpdater::get(cx) else {
         return;
     };
-    let version = updater.read(cx).current_version();
     let should_show_notification = updater.read(cx).should_show_update_notification(cx);
-
     cx.spawn(|cx| async move {
         let should_show_notification = should_show_notification.await?;
         if should_show_notification {
             cx.update(|cx| {
+                let version = updater.read(cx).current_version();
+                let app_name = ReleaseChannel::global(cx).display_name();
                 show_app_notification(
                     NotificationId::unique::<UpdateNotification>(),
                     cx,
                     move |cx| {
                         let workspace_handle = cx.entity().downgrade();
-                        cx.new(|_| UpdateNotification::new(version, workspace_handle))
+                        cx.new(|_cx| {
+                            MessageNotification::new(format!("Updated to {app_name} {}", version))
+                                .primary_message("View Release Notes")
+                                .primary_on_click(move |window, cx| {
+                                    if let Some(workspace) = workspace_handle.upgrade() {
+                                        workspace.update(cx, |workspace, cx| {
+                                            crate::view_release_notes_locally(
+                                                workspace, window, cx,
+                                            );
+                                        })
+                                    }
+                                    cx.emit(DismissEvent);
+                                })
+                        })
                     },
                 );
                 updater.update(cx, |updater, cx| {

crates/auto_update_ui/src/update_notification.rs 🔗

@@ -1,70 +0,0 @@
-use gpui::{
-    div, Context, DismissEvent, EventEmitter, InteractiveElement, IntoElement, ParentElement,
-    Render, SemanticVersion, StatefulInteractiveElement, Styled, WeakEntity, Window,
-};
-use menu::Cancel;
-use release_channel::ReleaseChannel;
-use util::ResultExt;
-use workspace::{
-    ui::{h_flex, v_flex, Icon, IconName, Label, StyledExt},
-    Workspace,
-};
-
-pub struct UpdateNotification {
-    version: SemanticVersion,
-    workspace: WeakEntity<Workspace>,
-}
-
-impl EventEmitter<DismissEvent> for UpdateNotification {}
-
-impl Render for UpdateNotification {
-    fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        let app_name = ReleaseChannel::global(cx).display_name();
-
-        v_flex()
-            .on_action(cx.listener(UpdateNotification::dismiss))
-            .elevation_3(cx)
-            .p_4()
-            .child(
-                h_flex()
-                    .justify_between()
-                    .child(Label::new(format!(
-                        "Updated to {app_name} {}",
-                        self.version
-                    )))
-                    .child(
-                        div()
-                            .id("cancel")
-                            .child(Icon::new(IconName::Close))
-                            .cursor_pointer()
-                            .on_click(cx.listener(|this, _, window, cx| {
-                                this.dismiss(&menu::Cancel, window, cx)
-                            })),
-                    ),
-            )
-            .child(
-                div()
-                    .id("notes")
-                    .child(Label::new("View the release notes"))
-                    .cursor_pointer()
-                    .on_click(cx.listener(|this, _, window, cx| {
-                        this.workspace
-                            .update(cx, |workspace, cx| {
-                                crate::view_release_notes_locally(workspace, window, cx);
-                            })
-                            .log_err();
-                        this.dismiss(&menu::Cancel, window, cx)
-                    })),
-            )
-    }
-}
-
-impl UpdateNotification {
-    pub fn new(version: SemanticVersion, workspace: WeakEntity<Workspace>) -> Self {
-        Self { version, workspace }
-    }
-
-    pub fn dismiss(&mut self, _: &Cancel, _: &mut Window, cx: &mut Context<Self>) {
-        cx.emit(DismissEvent);
-    }
-}