.
This commit is contained in:
@@ -134,41 +134,21 @@ impl ChatRegistry {
|
||||
|
||||
subscriptions.push(
|
||||
// Subscribe to the signer event
|
||||
cx.subscribe_in(&nostr, window, |this, state, event, window, cx| {
|
||||
if event == &StateEvent::SignerSet {
|
||||
cx.subscribe(&nostr, |this, _state, event, cx| {
|
||||
if let StateEvent::SignerSet(public_key) = event {
|
||||
this.reset(cx);
|
||||
this.get_contact_list(cx);
|
||||
this.get_contact_list(public_key, cx);
|
||||
this.get_rooms(cx);
|
||||
|
||||
let signer = state.read(cx).signer();
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
let user_signer = signer.get().await;
|
||||
this.update(cx, |this, cx| {
|
||||
this.get_messages(user_signer, cx);
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.detach();
|
||||
this.get_messages(public_key, cx);
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
subscriptions.push(
|
||||
// Subscribe to the device event
|
||||
cx.subscribe_in(&device, window, |_this, _s, event, window, cx| {
|
||||
if event == &DeviceEvent::Set {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let signer = nostr.read(cx).signer();
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
if let Some(device_signer) = signer.get_encryption_signer().await {
|
||||
this.update(cx, |this, cx| {
|
||||
this.get_messages(device_signer, cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
cx.subscribe(&device, |this, _device, event, cx| {
|
||||
if let DeviceEvent::Set(public_key) = event {
|
||||
this.get_messages(public_key, cx);
|
||||
};
|
||||
}),
|
||||
);
|
||||
@@ -342,17 +322,17 @@ impl ChatRegistry {
|
||||
}
|
||||
|
||||
/// Get contact list from relays
|
||||
fn get_contact_list(&mut self, cx: &mut Context<Self>) {
|
||||
fn get_contact_list(&mut self, public_key: &PublicKey, cx: &mut Context<Self>) {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
let signer = nostr.read(cx).signer();
|
||||
|
||||
let Some(public_key) = signer.public_key() else {
|
||||
return;
|
||||
};
|
||||
let public_key = public_key.to_owned();
|
||||
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
|
||||
|
||||
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
||||
let urls = write_relays.await;
|
||||
let id = SubscriptionId::new("contact-list");
|
||||
|
||||
let opts = SubscribeAutoCloseOptions::default()
|
||||
.exit_policy(ReqExitPolicy::ExitOnEOSE)
|
||||
.timeout(Some(Duration::from_secs(TIMEOUT)));
|
||||
@@ -363,8 +343,13 @@ impl ChatRegistry {
|
||||
.author(public_key)
|
||||
.limit(1);
|
||||
|
||||
let target = urls
|
||||
.into_iter()
|
||||
.map(|relay| (relay, vec![filter.clone()]))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Subscribe
|
||||
client.subscribe(filter).close_on(opts).with_id(id).await?;
|
||||
client.subscribe(target).close_on(opts).with_id(id).await?;
|
||||
|
||||
Ok(())
|
||||
});
|
||||
@@ -373,11 +358,11 @@ impl ChatRegistry {
|
||||
}
|
||||
|
||||
/// Get all messages for the provided signer
|
||||
fn get_messages(&mut self, signer: Arc<dyn AsyncNostrSigner>, cx: &mut Context<Self>) {
|
||||
let task = self.subscribe_gift_wrap_events(signer, cx);
|
||||
fn get_messages(&mut self, public_key: &PublicKey, cx: &mut Context<Self>) {
|
||||
let future = self.subscribe_msg(public_key, cx);
|
||||
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
match task.await {
|
||||
match future.await {
|
||||
Ok(_) => {
|
||||
this.update(cx, |this, cx| {
|
||||
this.set_initializing(false, cx);
|
||||
@@ -399,9 +384,12 @@ impl ChatRegistry {
|
||||
let client = nostr.read(cx).client();
|
||||
let signer = nostr.read(cx).signer();
|
||||
|
||||
let public_key = signer.public_key();
|
||||
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let public_key = signer.get_public_key().await?;
|
||||
let id = SubscriptionId::new("inbox-relay");
|
||||
let urls = write_relays.await;
|
||||
|
||||
// Construct filter for inbox relays
|
||||
let filter = Filter::new()
|
||||
@@ -409,9 +397,14 @@ impl ChatRegistry {
|
||||
.author(public_key)
|
||||
.limit(1);
|
||||
|
||||
let target = urls
|
||||
.into_iter()
|
||||
.map(|relay| (relay, vec![filter.clone()]))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Stream events from user's write relays
|
||||
let mut stream = client
|
||||
.stream_events(filter)
|
||||
.stream_events(target)
|
||||
.with_id(id)
|
||||
.timeout(Duration::from_secs(TIMEOUT))
|
||||
.await?;
|
||||
@@ -428,18 +421,14 @@ impl ChatRegistry {
|
||||
}
|
||||
|
||||
/// Continuously get gift wrap events for the signer
|
||||
fn subscribe_gift_wrap_events(
|
||||
&self,
|
||||
signer: Arc<dyn AsyncNostrSigner>,
|
||||
cx: &App,
|
||||
) -> Task<Result<(), Error>> {
|
||||
fn subscribe_msg(&self, public_key: &PublicKey, cx: &App) -> Task<Result<(), Error>> {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
let urls = self.get_messaging_relays(cx);
|
||||
let public_key = public_key.to_owned();
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let urls = urls.await?;
|
||||
let public_key = signer.get_public_key().await?;
|
||||
let filter = Filter::new().kind(Kind::GiftWrap).pubkey(public_key);
|
||||
let id = SubscriptionId::new(format!("{}-msg", public_key.to_hex()));
|
||||
|
||||
@@ -468,26 +457,30 @@ impl ChatRegistry {
|
||||
/// Refresh the chat registry, fetching messages and contact list from relays.
|
||||
pub fn refresh(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.reset(cx);
|
||||
self.get_contact_list(cx);
|
||||
self.get_rooms(cx);
|
||||
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let signer = nostr.read(cx).signer();
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
self.tasks.push(cx.spawn_in(window, async move |this, cx| {
|
||||
let user_signer = signer.get().await;
|
||||
let device_signer = signer.get_encryption_signer().await;
|
||||
let user_pubkey = user_signer.get_public_key().await?;
|
||||
|
||||
this.update(cx, |this, cx| {
|
||||
this.get_messages(user_signer, cx);
|
||||
this.get_messages(&user_pubkey, cx);
|
||||
})?;
|
||||
|
||||
if let Some(device_signer) = device_signer {
|
||||
this.get_messages(device_signer, cx);
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.detach();
|
||||
let device_signer = signer.get_encryption_signer().await;
|
||||
|
||||
if let Some(device_signer) = device_signer {
|
||||
let device_pubkey = device_signer.get_public_key().await?;
|
||||
this.update(cx, |this, cx| {
|
||||
this.get_messages(&device_pubkey, cx);
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}));
|
||||
}
|
||||
|
||||
/// Set the initializing status of the chat registry
|
||||
@@ -791,14 +784,12 @@ impl ChatRegistry {
|
||||
pub fn new_message(&mut self, message: NewMessage, cx: &mut Context<Self>) {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let signer = nostr.read(cx).signer();
|
||||
let public_key = signer.public_key();
|
||||
|
||||
match self.rooms.iter().find(|e| e.read(cx).id == message.room) {
|
||||
Some(room) => {
|
||||
room.update(cx, |this, cx| {
|
||||
if this.kind == RoomKind::Request
|
||||
&& let Some(public_key) = signer.public_key()
|
||||
&& message.rumor.pubkey == public_key
|
||||
{
|
||||
if this.kind == RoomKind::Request && message.rumor.pubkey == public_key {
|
||||
this.set_ongoing(cx);
|
||||
}
|
||||
this.push_message(message, cx);
|
||||
|
||||
@@ -10,7 +10,8 @@ use itertools::Itertools;
|
||||
use nostr_sdk::prelude::*;
|
||||
use person::{Person, PersonRegistry};
|
||||
use settings::{RoomConfig, SignerKind};
|
||||
use state::{CoopSigner, NostrRegistry, TIMEOUT};
|
||||
use smol::lock::RwLock;
|
||||
use state::{CoopSigner, Gossip, NostrRegistry, TIMEOUT};
|
||||
|
||||
use crate::NewMessage;
|
||||
|
||||
@@ -427,7 +428,7 @@ impl Room {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
|
||||
// Get current user's public key
|
||||
let sender = nostr.read(cx).signer().public_key()?;
|
||||
let sender = nostr.read(cx).signer().public_key();
|
||||
|
||||
// Get all members, excluding the sender
|
||||
let members: Vec<Person> = self
|
||||
@@ -477,10 +478,11 @@ impl Room {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
|
||||
let client = nostr.read(cx).client();
|
||||
let gossip = nostr.read(cx).gossip();
|
||||
let signer = nostr.read(cx).signer();
|
||||
|
||||
// Get current user's public key
|
||||
let public_key = nostr.read(cx).signer().public_key()?;
|
||||
let public_key = nostr.read(cx).signer().public_key();
|
||||
let sender = persons.read(cx).get(&public_key, cx);
|
||||
|
||||
let config = self.config.clone();
|
||||
@@ -529,7 +531,7 @@ impl Room {
|
||||
};
|
||||
|
||||
// Send the gift wrap event and collect the report
|
||||
match send_gift_wrap(&client, &signer, &member, &rumor, use_encryption).await {
|
||||
match send(&client, &gossip, &signer, &member, &rumor, use_encryption).await {
|
||||
Ok(report) => {
|
||||
reports.push(report);
|
||||
sents += 1;
|
||||
@@ -552,7 +554,7 @@ impl Room {
|
||||
SignerKind::User => false,
|
||||
};
|
||||
|
||||
match send_gift_wrap(&client, &signer, &sender, &rumor, use_encryption).await {
|
||||
match send(&client, &gossip, &signer, &sender, &rumor, use_encryption).await {
|
||||
Ok(report) => reports.push(report),
|
||||
Err(error) => {
|
||||
let report = SendReport::new(public_key).error(error.to_string());
|
||||
@@ -567,8 +569,9 @@ impl Room {
|
||||
}
|
||||
|
||||
// Helper function to send a gift-wrapped event
|
||||
async fn send_gift_wrap(
|
||||
async fn send(
|
||||
client: &Client,
|
||||
gossip: &Arc<RwLock<Gossip>>,
|
||||
signer: &Arc<CoopSigner>,
|
||||
receiver: &Person,
|
||||
rumor: &UnsignedEvent,
|
||||
@@ -602,10 +605,15 @@ async fn send_gift_wrap(
|
||||
}
|
||||
};
|
||||
|
||||
let relays = gossip.read().await.messaging_relays(&receiver);
|
||||
for url in relays.iter() {
|
||||
client.add_relay(url).and_connect().await?;
|
||||
}
|
||||
|
||||
// Send the gift wrap event and collect the report
|
||||
let report = client
|
||||
.send_event(&event)
|
||||
.to_nip17()
|
||||
.to(relays)
|
||||
.ack_policy(AckPolicy::none())
|
||||
.await
|
||||
.map(|output| {
|
||||
|
||||
Reference in New Issue
Block a user