Present a blank notification upon receipt of a contact request

This commit is contained in:
Nathan Sobo 2022-05-10 18:33:39 -06:00
parent bd2ae304fa
commit 3bca1c29e2
5 changed files with 90 additions and 21 deletions

View file

@ -54,7 +54,9 @@ pub struct UserStore {
_maintain_current_user: Task<()>, _maintain_current_user: Task<()>,
} }
pub enum Event {} pub enum Event {
NotifyIncomingRequest(Arc<User>),
}
impl Entity for UserStore { impl Entity for UserStore {
type Event = Event; type Event = Event;
@ -182,12 +184,14 @@ impl UserStore {
let mut incoming_requests = Vec::new(); let mut incoming_requests = Vec::new();
for request in message.incoming_requests { for request in message.incoming_requests {
incoming_requests.push( incoming_requests.push({
this.update(&mut cx, |this, cx| { let user = this
this.fetch_user(request.requester_id, cx) .update(&mut cx, |this, cx| {
}) this.fetch_user(request.requester_id, cx)
.await?, })
); .await?;
(user, request.should_notify)
});
} }
let mut outgoing_requests = Vec::new(); let mut outgoing_requests = Vec::new();
@ -224,14 +228,18 @@ impl UserStore {
this.incoming_contact_requests this.incoming_contact_requests
.retain(|user| !removed_incoming_requests.contains(&user.id)); .retain(|user| !removed_incoming_requests.contains(&user.id));
// Update existing incoming requests and insert new ones // Update existing incoming requests and insert new ones
for request in incoming_requests { for (user, should_notify) in incoming_requests {
if should_notify {
cx.emit(Event::NotifyIncomingRequest(user.clone()));
}
match this match this
.incoming_contact_requests .incoming_contact_requests
.binary_search_by_key(&&request.github_login, |contact| { .binary_search_by_key(&&user.github_login, |contact| {
&contact.github_login &contact.github_login
}) { }) {
Ok(ix) => this.incoming_contact_requests[ix] = request, Ok(ix) => this.incoming_contact_requests[ix] = user,
Err(ix) => this.incoming_contact_requests.insert(ix, request), Err(ix) => this.incoming_contact_requests.insert(ix, user),
} }
} }

View file

@ -1,4 +1,5 @@
mod contact_finder; mod contact_finder;
mod notifications;
use client::{Contact, User, UserStore}; use client::{Contact, User, UserStore};
use editor::{Cancel, Editor}; use editor::{Cancel, Editor};
@ -9,13 +10,14 @@ use gpui::{
impl_actions, impl_actions,
platform::CursorStyle, platform::CursorStyle,
Element, ElementBox, Entity, LayoutContext, ModelHandle, MutableAppContext, RenderContext, Element, ElementBox, Entity, LayoutContext, ModelHandle, MutableAppContext, RenderContext,
Subscription, View, ViewContext, ViewHandle, Subscription, View, ViewContext, ViewHandle, WeakViewHandle,
}; };
use notifications::IncomingRequestNotification;
use serde::Deserialize; use serde::Deserialize;
use settings::Settings; use settings::Settings;
use std::sync::Arc; use std::sync::Arc;
use theme::IconButton; use theme::IconButton;
use workspace::{AppState, JoinProject}; use workspace::{AppState, JoinProject, Workspace};
impl_actions!( impl_actions!(
contacts_panel, contacts_panel,
@ -60,7 +62,11 @@ pub fn init(cx: &mut MutableAppContext) {
} }
impl ContactsPanel { impl ContactsPanel {
pub fn new(app_state: Arc<AppState>, cx: &mut ViewContext<Self>) -> Self { pub fn new(
app_state: Arc<AppState>,
workspace: WeakViewHandle<Workspace>,
cx: &mut ViewContext<Self>,
) -> Self {
let user_query_editor = cx.add_view(|cx| { let user_query_editor = cx.add_view(|cx| {
let mut editor = Editor::single_line( let mut editor = Editor::single_line(
Some(|theme| theme.contacts_panel.user_query_editor.clone()), Some(|theme| theme.contacts_panel.user_query_editor.clone()),
@ -77,6 +83,28 @@ impl ContactsPanel {
}) })
.detach(); .detach();
cx.subscribe(&app_state.user_store, {
let user_store = app_state.user_store.clone();
move |_, _, event, cx| match event {
client::Event::NotifyIncomingRequest(user) => {
if let Some(workspace) = workspace.upgrade(cx) {
workspace.update(cx, |workspace, cx| {
workspace.show_notification(
cx.add_view(|_| {
IncomingRequestNotification::new(
user.clone(),
user_store.clone(),
)
}),
cx,
)
})
}
}
}
})
.detach();
let mut this = Self { let mut this = Self {
list_state: ListState::new(0, Orientation::Top, 1000., { list_state: ListState::new(0, Orientation::Top, 1000., {
let this = cx.weak_handle(); let this = cx.weak_handle();

View file

@ -0,0 +1,36 @@
use client::{User, UserStore};
use gpui::{color::Color, elements::*, Entity, ModelHandle, View};
use std::sync::Arc;
use workspace::Notification;
pub struct IncomingRequestNotification {
user: Arc<User>,
user_store: ModelHandle<UserStore>,
}
impl Entity for IncomingRequestNotification {
type Event = ();
}
impl View for IncomingRequestNotification {
fn ui_name() -> &'static str {
"IncomingRequestNotification"
}
fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> ElementBox {
Empty::new()
.constrained()
.with_height(200.)
.contained()
.with_background_color(Color::red())
.boxed()
}
}
impl Notification for IncomingRequestNotification {}
impl IncomingRequestNotification {
pub fn new(user: Arc<User>, user_store: ModelHandle<UserStore>) -> Self {
Self { user, user_store }
}
}

View file

@ -1732,11 +1732,7 @@ impl Workspace {
} }
} }
fn render_notifications( fn render_notifications(&self, theme: &theme::Workspace) -> Option<ElementBox> {
&self,
theme: &theme::Workspace,
cx: &mut RenderContext<Self>,
) -> Option<ElementBox> {
if self.notifications.is_empty() { if self.notifications.is_empty() {
None None
} else { } else {
@ -2094,7 +2090,7 @@ impl View for Workspace {
.top() .top()
.boxed() .boxed()
})) }))
.with_children(self.render_notifications(&theme.workspace, cx)) .with_children(self.render_notifications(&theme.workspace))
.flex(1.0, true) .flex(1.0, true)
.boxed(), .boxed(),
) )

View file

@ -172,7 +172,8 @@ pub fn build_workspace(
}); });
let project_panel = ProjectPanel::new(project, cx); let project_panel = ProjectPanel::new(project, cx);
let contact_panel = cx.add_view(|cx| ContactsPanel::new(app_state.clone(), cx)); let contact_panel =
cx.add_view(|cx| ContactsPanel::new(app_state.clone(), workspace.weak_handle(), cx));
workspace.left_sidebar().update(cx, |sidebar, cx| { workspace.left_sidebar().update(cx, |sidebar, cx| {
sidebar.add_item("icons/folder-tree-solid-14.svg", project_panel.into(), cx) sidebar.add_item("icons/folder-tree-solid-14.svg", project_panel.into(), cx)