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}