contact_notification.rs

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