diff --git a/crates/contacts_panel/src/contacts_panel.rs b/crates/contacts_panel/src/contacts_panel.rs index df6d85712b..4f484f0cd6 100644 --- a/crates/contacts_panel/src/contacts_panel.rs +++ b/crates/contacts_panel/src/contacts_panel.rs @@ -132,16 +132,15 @@ impl ContactsPanel { project::Event::ContactRequestedJoin(user) => { if let Some(workspace) = workspace.upgrade(cx) { workspace.update(cx, |workspace, cx| { - workspace.show_notification( + workspace.show_notification(user.id as usize, cx, |cx| { cx.add_view(|cx| { JoinProjectNotification::new( project, user.clone(), cx, ) - }), - cx, - ) + }) + }) }); } } @@ -161,12 +160,11 @@ impl ContactsPanel { { workspace.update(cx, |workspace, cx| match event.kind { ContactEventKind::Requested | ContactEventKind::Accepted => workspace - .show_notification( + .show_notification(event.user.id as usize, cx, |cx| { cx.add_view(|cx| { ContactNotification::new(event.clone(), user_store, cx) - }), - cx, - ), + }) + }), _ => {} }); } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index d27cb9bfba..b6cb95292a 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -716,7 +716,7 @@ pub struct Workspace { panes: Vec>, active_pane: ViewHandle, status_bar: ViewHandle, - notifications: Vec>, + notifications: Vec<(TypeId, usize, Box)>, project: ModelHandle, leader_state: LeaderState, follower_states_by_leader: FollowerStatesByLeader, @@ -1008,28 +1008,41 @@ impl Workspace { pub fn show_notification( &mut self, - notification: ViewHandle, + id: usize, cx: &mut ViewContext, + build_notification: impl FnOnce(&mut ViewContext) -> ViewHandle, ) { - cx.subscribe(¬ification, |this, handle, event, cx| { - if handle.read(cx).should_dismiss_notification_on_event(event) { - this.dismiss_notification(handle.id(), cx); - } - }) - .detach(); - self.notifications.push(Box::new(notification)); - cx.notify(); + let type_id = TypeId::of::(); + if self + .notifications + .iter() + .all(|(existing_type_id, existing_id, _)| { + (*existing_type_id, *existing_id) != (type_id, id) + }) + { + let notification = build_notification(cx); + cx.subscribe(¬ification, move |this, handle, event, cx| { + if handle.read(cx).should_dismiss_notification_on_event(event) { + this.dismiss_notification(type_id, id, cx); + } + }) + .detach(); + self.notifications + .push((type_id, id, Box::new(notification))); + cx.notify(); + } } - fn dismiss_notification(&mut self, id: usize, cx: &mut ViewContext) { - self.notifications.retain(|handle| { - if handle.id() == id { - cx.notify(); - false - } else { - true - } - }); + fn dismiss_notification(&mut self, type_id: TypeId, id: usize, cx: &mut ViewContext) { + self.notifications + .retain(|(existing_type_id, existing_id, _)| { + if (*existing_type_id, *existing_id) == (type_id, id) { + cx.notify(); + false + } else { + true + } + }); } pub fn items<'a>( @@ -1724,7 +1737,7 @@ impl Workspace { } else { Some( Flex::column() - .with_children(self.notifications.iter().map(|notification| { + .with_children(self.notifications.iter().map(|(_, _, notification)| { ChildView::new(notification.as_ref()) .contained() .with_style(theme.notification)