diff --git a/crates/story/src/modal_story.rs b/crates/story/src/modal_story.rs index 280e70a6..71ef71e1 100644 --- a/crates/story/src/modal_story.rs +++ b/crates/story/src/modal_story.rs @@ -495,10 +495,13 @@ impl Render for ModalStory { Button::new("show-notify-warning", cx) .label("Notification with Title") .on_click(cx.listener(|_, _, cx| { + struct TestNotification; + cx.push_notification( Notification::new( "你已经成功保存了文件,但是有一些警告信息需要你注意。", ) + .with_type_id::() .title("保存成功") .icon(IconName::Inbox) .autohide(false) diff --git a/crates/ui/src/notification.rs b/crates/ui/src/notification.rs index d9c8a569..1323e495 100644 --- a/crates/ui/src/notification.rs +++ b/crates/ui/src/notification.rs @@ -1,10 +1,9 @@ -use std::{sync::Arc, time::Duration}; +use std::{any::TypeId, sync::Arc, time::Duration}; use gpui::{ div, prelude::FluentBuilder as _, px, Animation, AnimationExt, ClickEvent, DismissEvent, - ElementId, EventEmitter, InteractiveElement as _, IntoElement, ParentElement as _, Render, - SharedString, StatefulInteractiveElement, Styled, View, ViewContext, VisualContext, - WindowContext, + EventEmitter, InteractiveElement as _, IntoElement, ParentElement as _, Render, SharedString, + StatefulInteractiveElement, Styled, View, ViewContext, VisualContext, WindowContext, }; use smol::Timer; @@ -20,12 +19,36 @@ pub enum NotificationType { Error, } +#[derive(Debug, PartialEq, Clone)] +pub(crate) enum NotificationId { + Type(TypeId), + Id(SharedString), +} + +impl From for NotificationId { + fn from(type_id: TypeId) -> Self { + Self::Type(type_id) + } +} + +impl From for NotificationId { + fn from(id: SharedString) -> Self { + Self::Id(id) + } +} + +impl From<&'static str> for NotificationId { + fn from(id: &'static str) -> Self { + Self::Id(id.into()) + } +} + pub struct Notification { /// The id is used make the notification unique. /// Then you push a notification with the same id, the previous notification will be replaced. /// /// None means the notification will be added to the end of the list. - id: ElementId, + id: NotificationId, type_: NotificationType, title: Option, content: SharedString, @@ -63,10 +86,10 @@ impl Notification { /// /// default width is 320px. pub fn new(content: impl Into) -> Self { - let id = uuid::Uuid::new_v4().to_string(); + let id: SharedString = uuid::Uuid::new_v4().to_string().into(); Self { - id: SharedString::from(id).into(), + id: id.into(), title: None, content: content.into(), type_: NotificationType::Info, @@ -76,11 +99,25 @@ impl Notification { } } - pub fn with_id(mut self, id: impl Into) -> Self { + /// Set the id of the notification, used to uniquely identify the notification. + pub fn with_id(mut self, id: impl Into) -> Self { + let id: SharedString = id.into(); self.id = id.into(); self } + /// Set the type id of the notification, used to uniquely identify the notification. + /// + /// ```rs + /// struct MyNotificationKind; + /// let notification = Notification::new("Hello").with_type_id::(); + /// ``` + pub fn with_type_id(mut self) -> Self { + let type_id = TypeId::of::(); + self.id = type_id.into(); + self + } + /// Set the title of the notification, default is None. /// /// If tilte is None, the notification will not have a title.