From c62bb8b6a1e402c7820c6c8b6a3742e20b5f313a Mon Sep 17 00:00:00 2001 From: Moulberry Date: Thu, 13 Nov 2025 00:12:01 +0800 Subject: [PATCH] notification: Fix close animation not working when closed from content (#1578) Currently, if dismiss is called from the content_builder or action_builder, the closing animation doesn't play. This is because the callback happens after the `closing` variable is set, so the animation will only start on the next frame, (and for some reason notify() doesn't trigger another frame?). This change makes it so that the content_builder is called first, so the closing animation starts playing immediately on the same frame. This also adds a check to dismiss to prevent spawning unnecessary futures if it is called multiple times --- crates/ui/src/notification.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/ui/src/notification.rs b/crates/ui/src/notification.rs index 246586c5..a548ad55 100644 --- a/crates/ui/src/notification.rs +++ b/crates/ui/src/notification.rs @@ -230,6 +230,9 @@ impl Notification { /// Dismiss the notification. pub fn dismiss(&mut self, _: &mut Window, cx: &mut Context) { + if self.closing { + return; + } self.closing = true; cx.notify(); @@ -266,6 +269,9 @@ impl Styled for Notification { } impl Render for Notification { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { + let content = self.content_builder.clone().map(|builder| builder(self, window, cx)); + let action = self.action_builder.clone().map(|builder| builder(self, window, cx).small().mr_3p5()); + let closing = self.closing; let icon = match self.type_ { None => self.icon.clone(), @@ -302,12 +308,12 @@ impl Render for Notification { .when_some(self.message.clone(), |this, message| { this.child(div().text_sm().child(message)) }) - .when_some(self.content_builder.clone(), |this, child_builder| { - this.child(child_builder(self, window, cx)) + .when_some(content, |this, content| { + this.child(content) }), ) - .when_some(self.action_builder.clone(), |this, action_builder| { - this.child(action_builder(self, window, cx).small().mr_3p5()) + .when_some(action, |this, action| { + this.child(action) }) .when_some(self.on_click.clone(), |this, on_click| { this.on_click(cx.listener(move |view, event, window, cx| {