wip: onboarding

This commit is contained in:
2025-12-18 09:00:29 +07:00
parent 4dffc4de20
commit d6504a8170
17 changed files with 262 additions and 214 deletions

View File

@@ -13,7 +13,5 @@ nostr-sdk.workspace = true
anyhow.workspace = true
smallvec.workspace = true
smol.workspace = true
flume.workspace = true
log.workspace = true
serde.workspace = true
serde_json.workspace = true

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use gpui::{App, AppContext, AsyncApp, Context, Entity, Global, Task};
use nostr_sdk::prelude::*;
@@ -20,7 +20,7 @@ pub struct PersonRegistry {
pub persons: HashMap<PublicKey, Entity<Profile>>,
/// Tasks for asynchronous operations
_tasks: SmallVec<[Task<()>; 2]>,
_tasks: SmallVec<[Task<()>; 3]>,
}
impl PersonRegistry {
@@ -38,6 +38,9 @@ impl PersonRegistry {
pub(crate) fn new(cx: &mut Context<Self>) -> Self {
let mut tasks = smallvec![];
// Channel for communication between Nostr and GPUI
let (tx, rx) = flume::bounded::<Profile>(1024);
tasks.push(
// Load all user profiles from the database
cx.spawn(async move |this, cx| {
@@ -57,6 +60,47 @@ impl PersonRegistry {
}),
);
tasks.push(
// Handle nostr notifications
cx.background_spawn(async move {
let client = client();
let mut notifications = client.notifications();
let mut processed_events: HashSet<EventId> = HashSet::default();
while let Ok(notification) = notifications.recv().await {
let RelayPoolNotification::Message { message, .. } = notification else {
continue;
};
if let RelayMessage::Event { event, .. } = message {
// Skip if already processed
if !processed_events.insert(event.id) {
continue;
}
if event.kind == Kind::Metadata {
let metadata = Metadata::from_json(&event.content).unwrap_or_default();
let profile = Profile::new(event.pubkey, metadata);
tx.send_async(profile).await.ok();
}
}
}
}),
);
tasks.push(
// Update GPUI state
cx.spawn(async move |this, cx| {
while let Ok(profile) = rx.recv_async().await {
this.update(cx, |this, cx| {
this.insert_or_update(&profile, cx);
})
.ok();
}
}),
);
Self {
persons: HashMap::new(),
_tasks: tasks,
@@ -110,8 +154,7 @@ impl PersonRegistry {
pub fn get(&self, public_key: &PublicKey, cx: &App) -> Profile {
self.persons
.get(public_key)
.map(|e| e.read(cx))
.cloned()
.map(|e| e.read(cx).clone())
.unwrap_or(Profile::new(public_key.to_owned(), Metadata::default()))
}
}