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, RenderContext, View,
7 ViewContext,
8};
9use workspace::notifications::Notification;
10
11impl_internal_actions!(contact_notifications, [Dismiss, RespondToContactRequest]);
12
13pub fn init(cx: &mut AppContext) {
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 be alerted if you decline."),
52 Dismiss(self.user.id),
53 vec![
54 (
55 "Decline",
56 Box::new(RespondToContactRequest {
57 user_id: self.user.id,
58 accept: false,
59 }),
60 ),
61 (
62 "Accept",
63 Box::new(RespondToContactRequest {
64 user_id: self.user.id,
65 accept: true,
66 }),
67 ),
68 ],
69 cx,
70 ),
71 ContactEventKind::Accepted => render_user_notification(
72 self.user.clone(),
73 "accepted your contact request",
74 None,
75 Dismiss(self.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 user: Arc<User>,
93 kind: client::ContactEventKind,
94 user_store: ModelHandle<UserStore>,
95 cx: &mut ViewContext<Self>,
96 ) -> Self {
97 cx.subscribe(&user_store, move |this, _, event, cx| {
98 if let client::Event::Contact {
99 kind: ContactEventKind::Cancelled,
100 user,
101 } = event
102 {
103 if user.id == this.user.id {
104 cx.emit(Event::Dismiss);
105 }
106 }
107 })
108 .detach();
109
110 Self {
111 user,
112 kind,
113 user_store,
114 }
115 }
116
117 fn dismiss(&mut self, _: &Dismiss, cx: &mut ViewContext<Self>) {
118 self.user_store.update(cx, |store, cx| {
119 store
120 .dismiss_contact_request(self.user.id, cx)
121 .detach_and_log_err(cx);
122 });
123 cx.emit(Event::Dismiss);
124 }
125
126 fn respond_to_contact_request(
127 &mut self,
128 action: &RespondToContactRequest,
129 cx: &mut ViewContext<Self>,
130 ) {
131 self.user_store
132 .update(cx, |store, cx| {
133 store.respond_to_contact_request(action.user_id, action.accept, cx)
134 })
135 .detach();
136 }
137}