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