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}