This commit is contained in:
Antonio Scandurra 2022-05-09 17:06:21 +02:00
parent ca56b0d6d5
commit e4f1952657
5 changed files with 52 additions and 23 deletions

1
Cargo.lock generated
View file

@ -935,6 +935,7 @@ dependencies = [
"fuzzy", "fuzzy",
"gpui", "gpui",
"postage", "postage",
"serde",
"settings", "settings",
"theme", "theme",
"util", "util",

View file

@ -237,6 +237,14 @@ impl UserStore {
&self.outgoing_contact_requests &self.outgoing_contact_requests
} }
pub fn has_outgoing_contact_request(&self, user: &User) -> bool {
self.outgoing_contact_requests
.binary_search_by_key(&&user.github_login, |requested_user| {
&requested_user.github_login
})
.is_ok()
}
pub fn request_contact(&self, responder_id: u64) -> impl Future<Output = Result<()>> { pub fn request_contact(&self, responder_id: u64) -> impl Future<Output = Result<()>> {
let client = self.client.upgrade(); let client = self.client.upgrade();
async move { async move {

View file

@ -276,6 +276,7 @@ impl Server {
store.add_connection(connection_id, user_id); store.add_connection(connection_id, user_id);
this.peer.send(connection_id, store.build_initial_contacts_update(contacts))?; this.peer.send(connection_id, store.build_initial_contacts_update(contacts))?;
} }
// this.update_user_contacts(user_id).await?;
let handle_io = handle_io.fuse(); let handle_io = handle_io.fuse();
futures::pin_mut!(handle_io); futures::pin_mut!(handle_io);
@ -354,22 +355,8 @@ impl Server {
}); });
} }
let contacts_to_update = self self.update_user_contacts(removed_connection.user_id)
.app_state
.db
.get_contacts(removed_connection.user_id)
.await?; .await?;
let store = self.store().await;
let mut update = proto::UpdateContacts::default();
update
.contacts
.push(store.contact_for_user(removed_connection.user_id));
for user_id in contacts_to_update.current {
for connection_id in store.connection_ids_for_user(user_id) {
self.peer.send(connection_id, update.clone()).trace_err();
}
}
Ok(()) Ok(())
} }

View file

@ -18,3 +18,4 @@ util = { path = "../util" }
workspace = { path = "../workspace" } workspace = { path = "../workspace" }
futures = "0.3" futures = "0.3"
postage = { version = "0.4.1", features = ["futures-traits"] } postage = { version = "0.4.1", features = ["futures-traits"] }
serde = { version = "1", features = ["derive"] }

View file

@ -5,15 +5,19 @@ use gpui::{
anyhow, anyhow,
elements::*, elements::*,
geometry::{rect::RectF, vector::vec2f}, geometry::{rect::RectF, vector::vec2f},
impl_actions,
platform::CursorStyle, platform::CursorStyle,
Element, ElementBox, Entity, LayoutContext, ModelHandle, RenderContext, Subscription, Task, Element, ElementBox, Entity, LayoutContext, ModelHandle, RenderContext, Subscription, Task,
View, ViewContext, ViewHandle, View, ViewContext, ViewHandle,
}; };
use serde::Deserialize;
use settings::Settings; use settings::Settings;
use std::sync::Arc; use std::sync::Arc;
use util::ResultExt; use util::ResultExt;
use workspace::{AppState, JoinProject}; use workspace::{AppState, JoinProject};
impl_actions!(contacts_panel, [RequestContact]);
pub struct ContactsPanel { pub struct ContactsPanel {
list_state: ListState, list_state: ListState,
contacts: Vec<Arc<Contact>>, contacts: Vec<Arc<Contact>>,
@ -24,6 +28,9 @@ pub struct ContactsPanel {
_maintain_contacts: Subscription, _maintain_contacts: Subscription,
} }
#[derive(Clone, Deserialize)]
pub struct RequestContact(pub u64);
impl ContactsPanel { impl ContactsPanel {
pub fn new(app_state: Arc<AppState>, cx: &mut ViewContext<Self>) -> Self { pub fn new(app_state: Arc<AppState>, cx: &mut ViewContext<Self>) -> Self {
let user_query_editor = cx.add_view(|cx| { let user_query_editor = cx.add_view(|cx| {
@ -86,8 +93,10 @@ impl ContactsPanel {
} else { } else {
let potential_contact_ix = ix - 2 - this.contacts.len(); let potential_contact_ix = ix - 2 - this.contacts.len();
Self::render_potential_contact( Self::render_potential_contact(
&this.potential_contacts[potential_contact_ix], this.potential_contacts[potential_contact_ix].clone(),
this.user_store.clone(),
theme, theme,
cx,
) )
} }
} }
@ -278,7 +287,16 @@ impl ContactsPanel {
.boxed() .boxed()
} }
fn render_potential_contact(contact: &User, theme: &theme::ContactsPanel) -> ElementBox { fn render_potential_contact(
contact: Arc<User>,
user_store: ModelHandle<UserStore>,
theme: &theme::ContactsPanel,
cx: &mut LayoutContext,
) -> ElementBox {
enum RequestContactButton {}
let requested_contact = user_store.read(cx).has_outgoing_contact_request(&contact);
Flex::row() Flex::row()
.with_children(contact.avatar.clone().map(|avatar| { .with_children(contact.avatar.clone().map(|avatar| {
Image::new(avatar) Image::new(avatar)
@ -299,12 +317,26 @@ impl ContactsPanel {
.boxed(), .boxed(),
) )
.with_child( .with_child(
Label::new("+".to_string(), theme.edit_contact.text.clone()) MouseEventHandler::new::<RequestContactButton, _, _>(
.contained() contact.id as usize,
.with_style(theme.edit_contact.container) cx,
.aligned() |_, _| {
.flex_float() let label = if requested_contact { "-" } else { "+" };
.boxed(), Label::new(label.to_string(), theme.edit_contact.text.clone())
.contained()
.with_style(theme.edit_contact.container)
.aligned()
.flex_float()
.boxed()
},
)
.on_click(move |_, cx| {
if requested_contact {
} else {
cx.dispatch_action(RequestContact(contact.id));
}
})
.boxed(),
) )
.constrained() .constrained()
.with_height(theme.row_height) .with_height(theme.row_height)