Detailed changes
@@ -55,7 +55,8 @@ pub struct UserStore {
}
pub enum Event {
- NotifyIncomingRequest(Arc<User>),
+ ContactRequested(Arc<User>),
+ ContactRequestCancelled(Arc<User>),
}
impl Entity for UserStore {
@@ -225,12 +226,18 @@ impl UserStore {
}
// Remove incoming contact requests
- this.incoming_contact_requests
- .retain(|user| !removed_incoming_requests.contains(&user.id));
+ this.incoming_contact_requests.retain(|user| {
+ if removed_incoming_requests.contains(&user.id) {
+ cx.emit(Event::ContactRequestCancelled(user.clone()));
+ false
+ } else {
+ true
+ }
+ });
// Update existing incoming requests and insert new ones
for (user, should_notify) in incoming_requests {
if should_notify {
- cx.emit(Event::NotifyIncomingRequest(user.clone()));
+ cx.emit(Event::ContactRequested(user.clone()));
}
match this
@@ -0,0 +1,58 @@
+use client::{User, UserStore};
+use gpui::{color::Color, elements::*, Entity, ModelHandle, View, ViewContext};
+use std::sync::Arc;
+use workspace::Notification;
+
+pub struct IncomingRequestNotification {
+ user: Arc<User>,
+ user_store: ModelHandle<UserStore>,
+}
+
+pub enum Event {
+ Dismiss,
+}
+
+impl Entity for IncomingRequestNotification {
+ type Event = Event;
+}
+
+impl View for IncomingRequestNotification {
+ fn ui_name() -> &'static str {
+ "IncomingRequestNotification"
+ }
+
+ fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> ElementBox {
+ Empty::new()
+ .constrained()
+ .with_height(200.)
+ .contained()
+ .with_background_color(Color::red())
+ .boxed()
+ }
+}
+
+impl Notification for IncomingRequestNotification {
+ fn should_dismiss_notification_on_event(&self, event: &<Self as Entity>::Event) -> bool {
+ matches!(event, Event::Dismiss)
+ }
+}
+
+impl IncomingRequestNotification {
+ pub fn new(
+ user: Arc<User>,
+ user_store: ModelHandle<UserStore>,
+ cx: &mut ViewContext<Self>,
+ ) -> Self {
+ let user_id = user.id;
+ cx.subscribe(&user_store, move |_, _, event, cx| {
+ if let client::Event::ContactRequestCancelled(user) = event {
+ if user.id == user_id {
+ cx.emit(Event::Dismiss);
+ }
+ }
+ })
+ .detach();
+
+ Self { user, user_store }
+ }
+}
@@ -1,7 +1,8 @@
mod contact_finder;
-mod notifications;
+mod contact_notifications;
use client::{Contact, User, UserStore};
+use contact_notifications::IncomingRequestNotification;
use editor::{Cancel, Editor};
use fuzzy::{match_strings, StringMatchCandidate};
use gpui::{
@@ -12,7 +13,6 @@ use gpui::{
Element, ElementBox, Entity, LayoutContext, ModelHandle, MutableAppContext, RenderContext,
Subscription, View, ViewContext, ViewHandle, WeakViewHandle,
};
-use notifications::IncomingRequestNotification;
use serde::Deserialize;
use settings::Settings;
use std::sync::Arc;
@@ -86,14 +86,15 @@ impl ContactsPanel {
cx.subscribe(&app_state.user_store, {
let user_store = app_state.user_store.clone();
move |_, _, event, cx| match event {
- client::Event::NotifyIncomingRequest(user) => {
+ client::Event::ContactRequested(user) => {
if let Some(workspace) = workspace.upgrade(cx) {
workspace.update(cx, |workspace, cx| {
workspace.show_notification(
- cx.add_view(|_| {
+ cx.add_view(|cx| {
IncomingRequestNotification::new(
user.clone(),
user_store.clone(),
+ cx,
)
}),
cx,
@@ -101,6 +102,7 @@ impl ContactsPanel {
})
}
}
+ _ => {}
}
})
.detach();
@@ -1,36 +0,0 @@
-use client::{User, UserStore};
-use gpui::{color::Color, elements::*, Entity, ModelHandle, View};
-use std::sync::Arc;
-use workspace::Notification;
-
-pub struct IncomingRequestNotification {
- user: Arc<User>,
- user_store: ModelHandle<UserStore>,
-}
-
-impl Entity for IncomingRequestNotification {
- type Event = ();
-}
-
-impl View for IncomingRequestNotification {
- fn ui_name() -> &'static str {
- "IncomingRequestNotification"
- }
-
- fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> ElementBox {
- Empty::new()
- .constrained()
- .with_height(200.)
- .contained()
- .with_background_color(Color::red())
- .boxed()
- }
-}
-
-impl Notification for IncomingRequestNotification {}
-
-impl IncomingRequestNotification {
- pub fn new(user: Arc<User>, user_store: ModelHandle<UserStore>) -> Self {
- Self { user, user_store }
- }
-}
@@ -604,13 +604,20 @@ impl<T: Item> WeakItemHandle for WeakViewHandle<T> {
}
}
-pub trait Notification: View {}
+pub trait Notification: View {
+ fn should_dismiss_notification_on_event(&self, event: &<Self as Entity>::Event) -> bool;
+}
pub trait NotificationHandle {
+ fn id(&self) -> usize;
fn to_any(&self) -> AnyViewHandle;
}
impl<T: Notification> NotificationHandle for ViewHandle<T> {
+ fn id(&self) -> usize {
+ self.id()
+ }
+
fn to_any(&self) -> AnyViewHandle {
self.into()
}
@@ -996,10 +1003,27 @@ impl Workspace {
notification: ViewHandle<V>,
cx: &mut ViewContext<Self>,
) {
+ 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();
}
+ fn dismiss_notification(&mut self, id: usize, cx: &mut ViewContext<Self>) {
+ self.notifications.retain(|handle| {
+ if handle.id() == id {
+ cx.notify();
+ false
+ } else {
+ true
+ }
+ });
+ }
+
pub fn items<'a>(
&'a self,
cx: &'a AppContext,