contact_notification.rs

  1use crate::notifications::render_user_notification;
  2use client::{ContactEvent, ContactEventKind, UserStore};
  3use gpui::{
  4    elements::*, impl_internal_actions, Entity, ModelHandle, MutableAppContext, RenderContext,
  5    View, ViewContext,
  6};
  7use workspace::Notification;
  8
  9impl_internal_actions!(contact_notifications, [Dismiss, RespondToContactRequest]);
 10
 11pub fn init(cx: &mut MutableAppContext) {
 12    cx.add_action(ContactNotification::dismiss);
 13    cx.add_action(ContactNotification::respond_to_contact_request);
 14}
 15
 16pub struct ContactNotification {
 17    user_store: ModelHandle<UserStore>,
 18    event: ContactEvent,
 19}
 20
 21#[derive(Clone)]
 22struct Dismiss(u64);
 23
 24#[derive(Clone)]
 25pub struct RespondToContactRequest {
 26    pub user_id: u64,
 27    pub accept: bool,
 28}
 29
 30pub enum Event {
 31    Dismiss,
 32}
 33
 34impl Entity for ContactNotification {
 35    type Event = Event;
 36}
 37
 38impl View for ContactNotification {
 39    fn ui_name() -> &'static str {
 40        "ContactNotification"
 41    }
 42
 43    fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
 44        match self.event.kind {
 45            ContactEventKind::Requested => render_user_notification(
 46                self.event.user.clone(),
 47                "wants to add you as a contact",
 48                Some("They won't know if you decline."),
 49                RespondToContactRequest {
 50                    user_id: self.event.user.id,
 51                    accept: false,
 52                },
 53                vec![
 54                    (
 55                        "Decline",
 56                        Box::new(RespondToContactRequest {
 57                            user_id: self.event.user.id,
 58                            accept: false,
 59                        }),
 60                    ),
 61                    (
 62                        "Accept",
 63                        Box::new(RespondToContactRequest {
 64                            user_id: self.event.user.id,
 65                            accept: true,
 66                        }),
 67                    ),
 68                ],
 69                cx,
 70            ),
 71            ContactEventKind::Accepted => render_user_notification(
 72                self.event.user.clone(),
 73                "accepted your contact request",
 74                None,
 75                Dismiss(self.event.user.id),
 76                vec![],
 77                cx,
 78            ),
 79            _ => unreachable!(),
 80        }
 81    }
 82}
 83
 84impl Notification for ContactNotification {
 85    fn should_dismiss_notification_on_event(&self, event: &<Self as Entity>::Event) -> bool {
 86        matches!(event, Event::Dismiss)
 87    }
 88}
 89
 90impl ContactNotification {
 91    pub fn new(
 92        event: ContactEvent,
 93        user_store: ModelHandle<UserStore>,
 94        cx: &mut ViewContext<Self>,
 95    ) -> Self {
 96        cx.subscribe(&user_store, move |this, _, event, cx| {
 97            if let client::ContactEvent {
 98                kind: ContactEventKind::Cancelled,
 99                user,
100            } = event
101            {
102                if user.id == this.event.user.id {
103                    cx.emit(Event::Dismiss);
104                }
105            }
106        })
107        .detach();
108
109        Self { event, user_store }
110    }
111
112    fn dismiss(&mut self, _: &Dismiss, cx: &mut ViewContext<Self>) {
113        self.user_store.update(cx, |store, cx| {
114            store
115                .dismiss_contact_request(self.event.user.id, cx)
116                .detach_and_log_err(cx);
117        });
118        cx.emit(Event::Dismiss);
119    }
120
121    fn respond_to_contact_request(
122        &mut self,
123        action: &RespondToContactRequest,
124        cx: &mut ViewContext<Self>,
125    ) {
126        self.user_store
127            .update(cx, |store, cx| {
128                store.respond_to_contact_request(action.user_id, action.accept, cx)
129            })
130            .detach();
131    }
132}