Detailed changes
@@ -54,7 +54,9 @@ pub struct UserStore {
_maintain_current_user: Task<()>,
}
-pub enum Event {}
+pub enum Event {
+ NotifyIncomingRequest(Arc<User>),
+}
impl Entity for UserStore {
type Event = Event;
@@ -182,12 +184,14 @@ impl UserStore {
let mut incoming_requests = Vec::new();
for request in message.incoming_requests {
- incoming_requests.push(
- this.update(&mut cx, |this, cx| {
- this.fetch_user(request.requester_id, cx)
- })
- .await?,
- );
+ incoming_requests.push({
+ let user = this
+ .update(&mut cx, |this, cx| {
+ this.fetch_user(request.requester_id, cx)
+ })
+ .await?;
+ (user, request.should_notify)
+ });
}
let mut outgoing_requests = Vec::new();
@@ -224,14 +228,18 @@ impl UserStore {
this.incoming_contact_requests
.retain(|user| !removed_incoming_requests.contains(&user.id));
// 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
.incoming_contact_requests
- .binary_search_by_key(&&request.github_login, |contact| {
+ .binary_search_by_key(&&user.github_login, |contact| {
&contact.github_login
}) {
- Ok(ix) => this.incoming_contact_requests[ix] = request,
- Err(ix) => this.incoming_contact_requests.insert(ix, request),
+ Ok(ix) => this.incoming_contact_requests[ix] = user,
+ Err(ix) => this.incoming_contact_requests.insert(ix, user),
}
}
@@ -1,4 +1,5 @@
mod contact_finder;
+mod notifications;
use client::{Contact, User, UserStore};
use editor::{Cancel, Editor};
@@ -9,13 +10,14 @@ use gpui::{
impl_actions,
platform::CursorStyle,
Element, ElementBox, Entity, LayoutContext, ModelHandle, MutableAppContext, RenderContext,
- Subscription, View, ViewContext, ViewHandle,
+ Subscription, View, ViewContext, ViewHandle, WeakViewHandle,
};
+use notifications::IncomingRequestNotification;
use serde::Deserialize;
use settings::Settings;
use std::sync::Arc;
use theme::IconButton;
-use workspace::{AppState, JoinProject};
+use workspace::{AppState, JoinProject, Workspace};
impl_actions!(
contacts_panel,
@@ -60,7 +62,11 @@ pub fn init(cx: &mut MutableAppContext) {
}
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 mut editor = Editor::single_line(
Some(|theme| theme.contacts_panel.user_query_editor.clone()),
@@ -77,6 +83,28 @@ impl ContactsPanel {
})
.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 {
list_state: ListState::new(0, Orientation::Top, 1000., {
let this = cx.weak_handle();
@@ -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 }
+ }
+}
@@ -1732,11 +1732,7 @@ impl Workspace {
}
}
- fn render_notifications(
- &self,
- theme: &theme::Workspace,
- cx: &mut RenderContext<Self>,
- ) -> Option<ElementBox> {
+ fn render_notifications(&self, theme: &theme::Workspace) -> Option<ElementBox> {
if self.notifications.is_empty() {
None
} else {
@@ -2094,7 +2090,7 @@ impl View for Workspace {
.top()
.boxed()
}))
- .with_children(self.render_notifications(&theme.workspace, cx))
+ .with_children(self.render_notifications(&theme.workspace))
.flex(1.0, true)
.boxed(),
)
@@ -172,7 +172,8 @@ pub fn build_workspace(
});
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| {
sidebar.add_item("icons/folder-tree-solid-14.svg", project_panel.into(), cx)