feat: bind user metadata to per-view directories (#64)
Reviewed-on: reya/coop#64
This commit is contained in:
@@ -10,7 +10,7 @@ use gpui::{
|
||||
Window, div, px, uniform_list,
|
||||
};
|
||||
use nostr_sdk::prelude::*;
|
||||
use person::PersonRegistry;
|
||||
use person::Directory;
|
||||
use settings::AppSettings;
|
||||
use state::NostrRegistry;
|
||||
use theme::{ActiveTheme, TextStyle, Typeset as _};
|
||||
@@ -39,6 +39,8 @@ pub struct NewChat {
|
||||
input: Entity<InputState>,
|
||||
/// Current user's contacts
|
||||
contacts: Option<Vec<PublicKey>>,
|
||||
/// Person directory for contacts and selected members
|
||||
directory: Entity<Directory>,
|
||||
/// Public keys selected as members of the chat
|
||||
members: Vec<PublicKey>,
|
||||
/// Whether a NIP-05 address is being resolved
|
||||
@@ -69,6 +71,7 @@ impl NewChat {
|
||||
dock,
|
||||
input,
|
||||
contacts: None,
|
||||
directory: Directory::new(cx),
|
||||
members: Vec::new(),
|
||||
resolving: false,
|
||||
error: None,
|
||||
@@ -112,6 +115,9 @@ impl NewChat {
|
||||
match task.await {
|
||||
Ok(contacts) => {
|
||||
this.update(cx, |this, cx| {
|
||||
this.directory.update(cx, |directory, cx| {
|
||||
directory.track(contacts.iter().copied(), cx)
|
||||
});
|
||||
this.contacts = Some(contacts);
|
||||
cx.notify();
|
||||
})?;
|
||||
@@ -133,7 +139,6 @@ impl NewChat {
|
||||
return Vec::new();
|
||||
};
|
||||
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let query = self.input.read(cx).value().trim().to_lowercase();
|
||||
|
||||
if query.is_empty() {
|
||||
@@ -146,7 +151,7 @@ impl NewChat {
|
||||
if public_key.to_hex().to_lowercase().contains(&query) {
|
||||
return true;
|
||||
}
|
||||
let name = persons.read(cx).get(public_key, cx).name();
|
||||
let name = self.directory.read(cx).person(public_key, cx).name();
|
||||
name.to_lowercase().contains(&query)
|
||||
})
|
||||
.cloned()
|
||||
@@ -318,7 +323,6 @@ impl NewChat {
|
||||
contacts: &[PublicKey],
|
||||
cx: &mut Context<Self>,
|
||||
) -> Vec<AnyElement> {
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let start = range.start;
|
||||
|
||||
contacts
|
||||
@@ -327,7 +331,7 @@ impl NewChat {
|
||||
.flatten()
|
||||
.enumerate()
|
||||
.map(|(offset, public_key)| {
|
||||
let profile = persons.read(cx).get(public_key, cx);
|
||||
let profile = self.directory.read(cx).person(public_key, cx);
|
||||
let public_key = *public_key;
|
||||
|
||||
Nav::new(start + offset)
|
||||
@@ -350,13 +354,11 @@ impl NewChat {
|
||||
}
|
||||
|
||||
fn render_members(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let persons = PersonRegistry::global(cx);
|
||||
|
||||
h_flex()
|
||||
.flex_wrap()
|
||||
.gap_1()
|
||||
.children(self.members.iter().map(|public_key| {
|
||||
let profile = persons.read(cx).get(public_key, cx);
|
||||
let profile = self.directory.read(cx).person(public_key, cx);
|
||||
let public_key = *public_key;
|
||||
let id = SharedString::from(format!("m-{}", public_key.to_hex()));
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use gpui::{
|
||||
};
|
||||
use instant::Duration;
|
||||
use nostr_sdk::prelude::*;
|
||||
use person::{Person, PersonRegistry, shorten_pubkey};
|
||||
use person::{Directory, Person, PersonRegistry, shorten_pubkey};
|
||||
use settings::AppSettings;
|
||||
use state::{NostrRegistry, upload};
|
||||
use theme::{ActiveTheme, TextStyle, Typeset as _, button_radius};
|
||||
@@ -34,6 +34,8 @@ struct ProfileDialog {
|
||||
public_key: PublicKey,
|
||||
/// Whether the profile belongs to the signed-in user
|
||||
is_current_user: bool,
|
||||
/// Person directory for the profile
|
||||
directory: Entity<Directory>,
|
||||
/// Whether the metadata inputs are shown
|
||||
editing: bool,
|
||||
/// User's name text input
|
||||
@@ -74,9 +76,15 @@ impl ProfileDialog {
|
||||
.placeholder("A short introduce about you.")
|
||||
});
|
||||
|
||||
let directory = Directory::new(cx);
|
||||
directory.update(cx, |directory, cx| {
|
||||
directory.track([public_key], cx);
|
||||
});
|
||||
|
||||
Self {
|
||||
public_key,
|
||||
is_current_user,
|
||||
directory,
|
||||
editing: false,
|
||||
name_input,
|
||||
avatar_input,
|
||||
@@ -90,8 +98,7 @@ impl ProfileDialog {
|
||||
}
|
||||
|
||||
fn profile(&self, cx: &App) -> Person {
|
||||
let persons = PersonRegistry::global(cx);
|
||||
persons.read(cx).get(&self.public_key, cx)
|
||||
self.directory.read(cx).person(&self.public_key, cx)
|
||||
}
|
||||
|
||||
fn set_profile(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
@@ -238,9 +245,8 @@ impl ProfileDialog {
|
||||
}
|
||||
|
||||
fn save(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let public_key = self.public_key;
|
||||
let old_metadata = persons.read(cx).get(&public_key, cx).metadata();
|
||||
let old_metadata = self.directory.read(cx).person(&public_key, cx).metadata();
|
||||
|
||||
// Extract all new metadata fields
|
||||
let avatar = self.avatar_input.read(cx).value();
|
||||
@@ -274,9 +280,9 @@ impl ProfileDialog {
|
||||
match task.await {
|
||||
Ok(_) => {
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
// Update the registry
|
||||
persons.update(cx, |this, cx| {
|
||||
this.insert(Person::new(public_key, new_metadata), cx);
|
||||
// Publish the new metadata to every directory
|
||||
PersonRegistry::global(cx).update(cx, |registry, cx| {
|
||||
registry.insert(Person::new(public_key, new_metadata), cx);
|
||||
});
|
||||
|
||||
this.set_updating(false, cx);
|
||||
|
||||
@@ -9,7 +9,7 @@ use gpui::{
|
||||
};
|
||||
use instant::Duration;
|
||||
use nostr_sdk::prelude::*;
|
||||
use person::{Person, PersonRegistry, shorten_pubkey};
|
||||
use person::{Directory, Person, shorten_pubkey};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use state::{BOOTSTRAP_RELAYS, NostrAddress, NostrRegistry, TIMEOUT};
|
||||
use theme::{ActiveTheme, TextStyle, Typeset as _, button_radius};
|
||||
@@ -33,6 +33,8 @@ pub struct Screening {
|
||||
last_active: Option<Timestamp>,
|
||||
/// All mutual contacts of the person being screened.
|
||||
mutual_contacts: Vec<PublicKey>,
|
||||
/// Person directory for the person and their mutual contacts
|
||||
directory: Entity<Directory>,
|
||||
tasks: SmallVec<[Task<()>; 3]>,
|
||||
_subscriptions: SmallVec<[Subscription; 1]>,
|
||||
}
|
||||
@@ -53,12 +55,16 @@ impl Screening {
|
||||
this.verify_identifier(cx);
|
||||
});
|
||||
|
||||
let directory = Directory::new(cx);
|
||||
directory.update(cx, |directory, cx| directory.track([public_key], cx));
|
||||
|
||||
Self {
|
||||
public_key,
|
||||
verified: false,
|
||||
followed: false,
|
||||
last_active: None,
|
||||
mutual_contacts: vec![],
|
||||
directory,
|
||||
tasks: smallvec![],
|
||||
_subscriptions: subscriptions,
|
||||
}
|
||||
@@ -208,8 +214,7 @@ impl Screening {
|
||||
}
|
||||
|
||||
fn profile(&self, cx: &Context<Self>) -> Person {
|
||||
let persons = PersonRegistry::global(cx);
|
||||
persons.read(cx).get(&self.public_key, cx)
|
||||
self.directory.read(cx).person(&self.public_key, cx)
|
||||
}
|
||||
|
||||
fn address(&self, cx: &Context<Self>) -> Option<Nip05Address> {
|
||||
@@ -260,22 +265,23 @@ impl Screening {
|
||||
|
||||
fn mutual_contacts(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let contacts = self.mutual_contacts.clone();
|
||||
let directory = self.directory.clone();
|
||||
|
||||
window.open_dialog(cx, move |this, _window, _cx| {
|
||||
let contacts = contacts.clone();
|
||||
let directory = directory.clone();
|
||||
let total = contacts.len();
|
||||
|
||||
this.title("Mutual contacts").child(
|
||||
v_flex().gap_1().pb_2().child(
|
||||
uniform_list("contacts", total, move |range, _window, cx| {
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let mut items = Vec::with_capacity(total);
|
||||
|
||||
for ix in range {
|
||||
let Some(contact) = contacts.get(ix) else {
|
||||
continue;
|
||||
};
|
||||
let profile = persons.read(cx).get(contact, cx);
|
||||
let profile = directory.read(cx).person(contact, cx);
|
||||
|
||||
items.push(
|
||||
h_flex()
|
||||
|
||||
Reference in New Issue
Block a user