notification: Add &mut Self to content and action method. (#1569)

This commit is contained in:
Jason Lee 2025-11-12 15:10:42 +08:00 committed by GitHub
parent e97689f12c
commit 214d3f6622
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 22 additions and 69 deletions

View file

@ -147,7 +147,7 @@ impl Render for NotificationStory {
.title("Uh oh! Something went wrong.")
.message("There was a problem with your request.")
.autohide(false)
.action(|_, cx| {
.action(|_, _, cx| {
Button::new("try-again").primary().label("Retry").on_click(
cx.listener(|this, _, window, cx| {
println!("You have clicked the try again action.");
@ -171,7 +171,7 @@ impl Render for NotificationStory {
.label("Show Custom Notification")
.on_click(cx.listener(|_, _, window, cx| {
window.push_notification(
Notification::new().content(|window, cx| {
Notification::new().content(|_, window, cx| {
TextView::markdown(
"notification-markdown",
NOTIFICATION_MARKDOWN,

View file

@ -70,8 +70,8 @@ pub struct Notification {
message: Option<SharedString>,
icon: Option<Icon>,
autohide: bool,
action_builder: Option<Rc<dyn Fn(&mut Window, &mut Context<Self>) -> Button>>,
content_builder: Option<Rc<dyn Fn(&mut Window, &mut Context<Self>) -> AnyElement>>,
action_builder: Option<Rc<dyn Fn(&mut Self, &mut Window, &mut Context<Self>) -> Button>>,
content_builder: Option<Rc<dyn Fn(&mut Self, &mut Window, &mut Context<Self>) -> AnyElement>>,
on_click: Option<Rc<dyn Fn(&ClickEvent, &mut Window, &mut App)>>,
closing: bool,
}
@ -110,6 +110,8 @@ struct DefaultIdType;
impl Notification {
/// Create a new notification.
///
/// The default id is a random UUID.
pub fn new() -> Self {
let id: SharedString = uuid::Uuid::new_v4().to_string().into();
let id = (TypeId::of::<DefaultIdType>(), id.into());
@ -220,7 +222,7 @@ impl Notification {
/// Set the action button of the notification.
pub fn action<F>(mut self, action: F) -> Self
where
F: Fn(&mut Window, &mut Context<Self>) -> Button + 'static,
F: Fn(&mut Self, &mut Window, &mut Context<Self>) -> Button + 'static,
{
self.action_builder = Some(Rc::new(action));
self
@ -249,7 +251,7 @@ impl Notification {
/// Set the content of the notification.
pub fn content(
mut self,
content: impl Fn(&mut Window, &mut Context<Self>) -> AnyElement + 'static,
content: impl Fn(&mut Self, &mut Window, &mut Context<Self>) -> AnyElement + 'static,
) -> Self {
self.content_builder = Some(Rc::new(content));
self
@ -301,11 +303,11 @@ impl Render for Notification {
this.child(div().text_sm().child(message))
})
.when_some(self.content_builder.clone(), |this, child_builder| {
this.child(child_builder(window, cx))
this.child(child_builder(self, window, cx))
}),
)
.when_some(self.action_builder.clone(), |this, action_builder| {
this.child(action_builder(window, cx).small().mr_3p5())
this.child(action_builder(self, window, cx).small().mr_3p5())
})
.when_some(self.on_click.clone(), |this, on_click| {
this.on_click(cx.listener(move |view, event, window, cx| {

View file

@ -155,7 +155,7 @@ let markdown_content = r#"
"#;
Notification::new()
.content(|window, cx| {
.content(|_, window, cx| {
TextView::markdown(
"custom-content",
markdown_content,
@ -168,6 +168,14 @@ Notification::new()
### Unique Notifications
When you need to manage notifications manually, such as for long-running processes or persistent alerts, you can use unique IDs to push and remove notifications as needed.
In this case, you can create a special `struct` in local scope, and use `id` methods with this struct to identify the notification.
Then you can push the notification when needed, and later remove it using the same ID.
Like this:
```rust
// Using type-based ID for uniqueness
struct UpdateNotification;
@ -185,70 +193,13 @@ Notification::warning("Task failed to complete")
.title("Task Failed")
```
### Manual Notification Management
Then remove the notification with `window.remove_notification::<UpdateNotification>`, like this:
```rust
// Show persistent notification
struct PersistentNotification;
window.push_notification(
Notification::new()
.id::<PersistentNotification>()
.message("Background process running...")
.autohide(false),
cx,
);
// Later, dismiss the notification
window.remove_notification::<PersistentNotification>(cx);
window.remove_notification::<UpdateNotification>(cx);
```
## API Reference
### Notification Methods
| Method | Description |
| --------------------- | -------------------------------------------------------- |
| `new()` | Create a new notification with default settings |
| `info(message)` | Create an info notification with blue styling |
| `success(message)` | Create a success notification with green styling |
| `warning(message)` | Create a warning notification with yellow/orange styling |
| `error(message)` | Create an error notification with red styling |
| `message(text)` | Set the notification message content |
| `title(text)` | Set the notification title (appears above message) |
| `with_type(type)` | Set the notification type for styling and icon |
| `icon(icon)` | Set a custom icon (overrides type default icon) |
| `autohide(bool)` | Control auto-dismiss behavior (default: true) |
| `id<T>()` | Set unique type-based ID for notification |
| `id1<T>(key)` | Set unique type + element ID for notification |
| `on_click(callback)` | Set click handler for the notification |
| `action(builder)` | Add an action button to the notification |
| `content(builder)` | Set custom content instead of title/message |
| `dismiss(window, cx)` | Manually dismiss the notification |
### NotificationType Variants
| Type | Description | Default Icon | Theme Color |
| --------- | ---------------------- | ------------- | ------------- |
| `Info` | Informational messages | Info | Blue |
| `Success` | Success confirmations | CircleCheck | Green |
| `Warning` | Warning messages | TriangleAlert | Yellow/Orange |
| `Error` | Error messages | CircleX | Red |
### Window Extensions
| Method | Description |
| -------------------------------------------- | --------------------------- |
| `window.push_notification(notification, cx)` | Show a notification |
| `window.remove_notification::<T>(cx)` | Remove notification by type |
### Auto-hide Behavior
- **Default timeout**: 5 seconds
- **Auto-hide enabled**: Notification dismisses automatically
- **Auto-hide disabled**: Notification persists until manually closed
- **Hover interaction**: Auto-hide pauses while hovering over notification area
## Examples
### Form Validation Error
@ -257,7 +208,7 @@ window.remove_notification::<PersistentNotification>(cx);
Notification::error("Please correct the following errors before submitting.")
.title("Validation Failed")
.autohide(false)
.action(|_, cx| {
.action(|_, _, cx| {
Button::new("review")
.outline()
.label("Review Form")