zed/crates/collab_ui/src/contact_notification.rs
Petros Amoiridis 160870c9de
Improve user notification
The message is not really true. When one declines, the other person can notice that the contact request  is not pending any more. They will know. Switching to not alerted is closer to what is really happening.
2023-01-25 19:46:51 +02:00

138 lines
3.7 KiB
Rust

use std::sync::Arc;
use crate::notifications::render_user_notification;
use client::{ContactEventKind, User, UserStore};
use gpui::{
elements::*, impl_internal_actions, Entity, ModelHandle, MutableAppContext, RenderContext,
View, ViewContext,
};
use workspace::notifications::Notification;
impl_internal_actions!(contact_notifications, [Dismiss, RespondToContactRequest]);
pub fn init(cx: &mut MutableAppContext) {
cx.add_action(ContactNotification::dismiss);
cx.add_action(ContactNotification::respond_to_contact_request);
}
pub struct ContactNotification {
user_store: ModelHandle<UserStore>,
user: Arc<User>,
kind: client::ContactEventKind,
}
#[derive(Clone, PartialEq)]
struct Dismiss(u64);
#[derive(Clone, PartialEq)]
pub struct RespondToContactRequest {
pub user_id: u64,
pub accept: bool,
}
pub enum Event {
Dismiss,
}
impl Entity for ContactNotification {
type Event = Event;
}
impl View for ContactNotification {
fn ui_name() -> &'static str {
"ContactNotification"
}
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
match self.kind {
ContactEventKind::Requested => render_user_notification(
self.user.clone(),
"wants to add you as a contact",
Some("They won't be alerted if you decline."),
Dismiss(self.user.id),
vec![
(
"Decline",
Box::new(RespondToContactRequest {
user_id: self.user.id,
accept: false,
}),
),
(
"Accept",
Box::new(RespondToContactRequest {
user_id: self.user.id,
accept: true,
}),
),
],
cx,
),
ContactEventKind::Accepted => render_user_notification(
self.user.clone(),
"accepted your contact request",
None,
Dismiss(self.user.id),
vec![],
cx,
),
_ => unreachable!(),
}
}
}
impl Notification for ContactNotification {
fn should_dismiss_notification_on_event(&self, event: &<Self as Entity>::Event) -> bool {
matches!(event, Event::Dismiss)
}
}
impl ContactNotification {
pub fn new(
user: Arc<User>,
kind: client::ContactEventKind,
user_store: ModelHandle<UserStore>,
cx: &mut ViewContext<Self>,
) -> Self {
cx.subscribe(&user_store, move |this, _, event, cx| {
if let client::Event::Contact {
kind: ContactEventKind::Cancelled,
user,
} = event
{
if user.id == this.user.id {
cx.emit(Event::Dismiss);
}
}
})
.detach();
Self {
user,
kind,
user_store,
}
}
fn dismiss(&mut self, _: &Dismiss, cx: &mut ViewContext<Self>) {
self.user_store.update(cx, |store, cx| {
store
.dismiss_contact_request(self.user.id, cx)
.detach_and_log_err(cx);
});
cx.emit(Event::Dismiss);
}
fn respond_to_contact_request(
&mut self,
action: &RespondToContactRequest,
cx: &mut ViewContext<Self>,
) {
self.user_store
.update(cx, |store, cx| {
store.respond_to_contact_request(action.user_id, action.accept, cx)
})
.detach();
}
}