contact_notification.rs

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