chore: improve handling of user profiles (#146)

* resubscribe metadata for all pubkeys

* .
This commit is contained in:
reya
2025-09-10 10:06:45 +07:00
committed by GitHub
parent 4ec7530b91
commit 2ea5feaf4b
7 changed files with 87 additions and 30 deletions

View File

@@ -2,7 +2,7 @@ use std::sync::Mutex;
use gpui::{actions, App};
actions!(coop, [DarkMode, Settings, Logout, Quit]);
actions!(coop, [ReloadMetadata, DarkMode, Settings, Logout, Quit]);
actions!(sidebar, [Reload, RelayStatus]);
pub fn load_embedded_fonts(cx: &App) {

View File

@@ -42,7 +42,7 @@ use ui::notification::Notification;
use ui::popup_menu::PopupMenuExt;
use ui::{h_flex, v_flex, ContextModal, Disableable, IconName, Root, Sizable, StyledExt};
use crate::actions::{DarkMode, Logout, Settings};
use crate::actions::{DarkMode, Logout, ReloadMetadata, Settings};
use crate::views::compose::compose_button;
use crate::views::setup_relay::setup_nip17_relay;
use crate::views::{
@@ -439,7 +439,10 @@ impl ChatSpace {
}
}
Kind::Metadata => {
ingester.send(Signal::Metadata(event.into_owned())).await;
if let Ok(metadata) = Metadata::from_json(&event.content) {
let profile = Profile::new(event.pubkey, metadata);
ingester.send(Signal::Metadata(profile)).await;
}
}
Kind::GiftWrap => {
Self::unwrap_gift_wrap(&event, pubkey_tx).await;
@@ -558,9 +561,9 @@ impl ChatSpace {
this.set_unwrapping_status(status, cx);
});
}
Signal::Metadata(event) => {
Signal::Metadata(profile) => {
registry.update(cx, |this, cx| {
this.insert_or_update_person(event, cx);
this.insert_or_update_person(profile, cx);
});
}
Signal::Message((gift_wrap_id, event)) => {
@@ -1090,6 +1093,50 @@ impl ChatSpace {
}
}
fn on_reload_metadata(
&mut self,
_ev: &ReloadMetadata,
window: &mut Window,
cx: &mut Context<Self>,
) {
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
let client = nostr_client();
let css = css();
let filter = Filter::new().kind(Kind::PrivateDirectMessage);
let pubkeys: Vec<PublicKey> = client
.database()
.query(filter)
.await?
.into_iter()
.flat_map(|event| event.all_pubkeys())
.unique()
.collect();
let filter = Filter::new()
.kind(Kind::Metadata)
.limit(pubkeys.len())
.authors(pubkeys);
client
.subscribe_to(BOOTSTRAP_RELAYS, filter, css.auto_close_opts)
.await?;
Ok(())
});
cx.spawn_in(window, async move |_, cx| {
if task.await.is_ok() {
cx.update(|window, cx| {
window.push_notification(t!("common.refreshed"), cx);
})
.ok();
}
})
.detach();
}
fn on_sign_out(&mut self, _e: &Logout, _window: &mut Window, cx: &mut Context<Self>) {
cx.background_spawn(async move {
let client = nostr_client();
@@ -1309,6 +1356,8 @@ impl ChatSpace {
this.menu(t!("user.dark_mode"), Box::new(DarkMode))
.menu(t!("user.settings"), Box::new(Settings))
.separator()
.menu(t!("user.reload_metadata"), Box::new(ReloadMetadata))
.separator()
.menu(t!("user.sign_out"), Box::new(Logout))
}),
)
@@ -1429,6 +1478,7 @@ impl Render for ChatSpace {
.on_action(cx.listener(Self::on_dark_mode))
.on_action(cx.listener(Self::on_sign_out))
.on_action(cx.listener(Self::on_open_profile))
.on_action(cx.listener(Self::on_reload_metadata))
.relative()
.size_full()
.child(

View File

@@ -164,7 +164,7 @@ impl EditProfile {
.detach();
}
pub fn set_metadata(&mut self, cx: &mut Context<Self>) -> Task<Result<Option<Event>, Error>> {
pub fn set_metadata(&mut self, cx: &mut Context<Self>) -> Task<Result<Option<Profile>, Error>> {
let avatar = self.avatar_input.read(cx).value().to_string();
let name = self.name_input.read(cx).value().to_string();
let bio = self.bio_input.read(cx).value().to_string();
@@ -189,7 +189,14 @@ impl EditProfile {
cx.background_spawn(async move {
let client = nostr_client();
let output = client.set_metadata(&new_metadata).await?;
let event = client.database().event_by_id(&output.val).await?;
let event = client
.database()
.event_by_id(&output.val)
.await?
.map(|event| {
let metadata = Metadata::from_json(&event.content).unwrap_or_default();
Profile::new(event.pubkey, metadata)
});
Ok(event)
})

View File

@@ -41,28 +41,28 @@ impl Preferences {
fn open_edit_profile(&self, window: &mut Window, cx: &mut Context<Self>) {
let view = edit_profile::init(window, cx);
let weak_view = view.downgrade();
let title = SharedString::new(t!("profile.title"));
window.open_modal(cx, move |modal, _window, _cx| {
let weak_view = weak_view.clone();
modal
.confirm()
.title(title.clone())
.title(shared_t!("profile.title"))
.child(view.clone())
.button_props(ModalButtonProps::default().ok_text(t!("common.update")))
.on_ok(move |_, window, cx| {
weak_view
.update(cx, |this, cx| {
let set_metadata = this.set_metadata(cx);
let registry = Registry::global(cx);
cx.spawn_in(window, async move |_, cx| {
match set_metadata.await {
Ok(event) => {
if let Some(event) = event {
Ok(profile) => {
if let Some(profile) = profile {
cx.update(|_, cx| {
Registry::global(cx).update(cx, |this, cx| {
this.insert_or_update_person(event, cx);
registry.update(cx, |this, cx| {
this.insert_or_update_person(profile, cx);
});
})
.ok();

View File

@@ -68,8 +68,8 @@ pub enum Signal {
/// A signal to notify UI that the browser proxy service is down
ProxyDown,
/// A signal to notify UI that a new metadata event has been received
Metadata(Event),
/// A signal to notify UI that a new profile has been received
Metadata(Profile),
/// A signal to notify UI that a new gift wrap event has been received
Message((EventId, Event)),

View File

@@ -155,21 +155,19 @@ impl Registry {
}
/// Insert or update a person
pub fn insert_or_update_person(&mut self, event: Event, cx: &mut App) {
let public_key = event.pubkey;
let Ok(metadata) = Metadata::from_json(event.content) else {
// Invalid metadata, no need to process further.
return;
};
pub fn insert_or_update_person(&mut self, profile: Profile, cx: &mut App) {
let public_key = profile.public_key();
if let Some(person) = self.persons.get(&public_key) {
person.update(cx, |this, cx| {
*this = Profile::new(public_key, metadata);
cx.notify();
});
} else {
self.persons
.insert(public_key, cx.new(|_| Profile::new(public_key, metadata)));
match self.persons.get(&public_key) {
Some(person) => {
person.update(cx, |this, cx| {
*this = profile;
cx.notify();
});
}
None => {
self.persons.insert(public_key, cx.new(|_| profile));
}
}
}

View File

@@ -58,9 +58,11 @@ auto_update:
user:
dark_mode:
en: "Dark Mode"
en: "Dark mode"
settings:
en: "Settings"
reload_metadata:
en: "Reload metadata"
sign_out:
en: "Sign out"