notification: Support remove notification with the given id (#980)

This commit is contained in:
Floyd Wang 2025-06-18 14:02:07 +08:00 committed by GitHub
parent fe342919e6
commit 1055131ffe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 57 additions and 59 deletions

View file

@ -4,7 +4,7 @@ use gpui::{
};
use gpui_component::{
button::{Button, ButtonVariants as _},
button::{Button, ButtonVariants},
notification::{Notification, NotificationType},
text::TextView,
ContextModal as _,
@ -178,5 +178,31 @@ impl Render for NotificationStory {
})),
),
)
.child({
struct ManualOpenNotification;
section("Manual Close Notification")
.child(
Button::new("manual-open-notify")
.label("Show")
.on_click(cx.listener(|_, _, window, cx| {
window.push_notification(
Notification::new()
.id::<ManualOpenNotification>()
.message("Click the Close Notification button to close.")
.autohide(false),
cx,
);
})),
)
.child(
Button::new("manual-close-notify")
.danger()
.label("Close")
.on_click(cx.listener(|_, _, window, cx| {
window.remove_notification::<ManualOpenNotification>(cx);
})),
)
})
}
}

View file

@ -391,6 +391,19 @@ impl NotificationList {
cx.notify();
}
pub(crate) fn close(
&mut self,
id: impl Into<NotificationId>,
window: &mut Window,
cx: &mut Context<Self>,
) {
let id: NotificationId = id.into();
if let Some(n) = self.notifications.iter().find(|n| n.read(cx).id == id) {
n.update(cx, |note, cx| note.dismiss(window, cx))
}
cx.notify();
}
pub fn clear(&mut self, _: &mut Window, cx: &mut Context<Self>) {
self.notifications.clear();
cx.notify();

View file

@ -10,7 +10,7 @@ use gpui::{
Entity, FocusHandle, InteractiveElement, IntoElement, ParentElement as _, Render, Styled,
Window,
};
use std::rc::Rc;
use std::{any::TypeId, rc::Rc};
/// Extension trait for [`WindowContext`] and [`ViewContext`] to add drawer functionality.
pub trait ContextModal: Sized {
@ -46,7 +46,13 @@ pub trait ContextModal: Sized {
/// Pushes a notification to the notification list.
fn push_notification(&mut self, note: impl Into<Notification>, cx: &mut App);
/// Removes the notification with the given id.
fn remove_notification<T: Sized + 'static>(&mut self, cx: &mut App);
/// Clears all notifications.
fn clear_notifications(&mut self, cx: &mut App);
/// Returns number of notifications.
fn notifications(&mut self, cx: &mut App) -> Rc<Vec<Entity<Notification>>>;
@ -158,6 +164,16 @@ impl ContextModal for Window {
})
}
fn remove_notification<T: Sized + 'static>(&mut self, cx: &mut App) {
Root::update(self, cx, move |root, window, cx| {
root.notification.update(cx, |view, cx| {
let id = TypeId::of::<T>();
view.close(id, window, cx);
});
cx.notify();
})
}
fn clear_notifications(&mut self, cx: &mut App) {
Root::update(self, cx, move |root, window, cx| {
root.notification
@ -180,63 +196,6 @@ impl ContextModal for Window {
}
}
// impl<V> ContextModal for Context<'_, V> {
// fn open_drawer<F>(&mut self, cx: &mut App, build: F)
// where
// F: Fn(Drawer, &mut Window, &mut App) -> Drawer + 'static,
// {
// self.deref_mut().open_drawer(cx, build)
// }
// fn open_drawer_at<F>(&mut self, cx: &mut App, placement: Placement, build: F)
// where
// F: Fn(Drawer, &mut Window, &mut App) -> Drawer + 'static,
// {
// self.deref_mut().open_drawer_at(cx, placement, build)
// }
// fn has_active_modal(&self, cx: &mut App) -> bool {
// self.deref().has_active_modal(cx)
// }
// fn close_drawer(&mut self, cx: &mut App) {
// self.deref_mut().close_drawer(cx)
// }
// fn open_modal<F>(&mut self, cx: &mut App, build: F)
// where
// F: Fn(Modal, &mut Window, &mut App) -> Modal + 'static,
// {
// self.deref_mut().open_modal(cx, build)
// }
// fn has_active_drawer(&self, cx: &mut App) -> bool {
// self.deref().has_active_drawer(cx)
// }
// /// Close the last active modal.
// fn close_modal(&mut self, cx: &mut App) {
// self.deref_mut().close_modal(cx)
// }
// /// Close all modals.
// fn close_all_modals(&mut self, cx: &mut App) {
// self.deref_mut().close_all_modals(cx)
// }
// fn push_notification(&mut self, cx: &mut App, note: impl Into<Notification>) {
// self.deref_mut().push_notification(cx, note)
// }
// fn clear_notifications(&mut self, cx: &mut App) {
// self.deref_mut().clear_notifications(cx)
// }
// fn notifications(&self, cx: &mut App) -> Rc<Vec<Entity<Notification>>> {
// self.deref().notifications(cx)
// }
// }
/// Root is a view for the App window for as the top level view (Must be the first view in the window).
///
/// It is used to manage the Drawer, Modal, and Notification.