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