clean up
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m24s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m26s
Rust / build (macos-latest, stable) (push) Has been cancelled
Rust / build (windows-latest, stable) (push) Has been cancelled
Rust / build (macos-latest, stable) (pull_request) Has been cancelled
Rust / build (windows-latest, stable) (pull_request) Has been cancelled
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m24s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m26s
Rust / build (macos-latest, stable) (push) Has been cancelled
Rust / build (windows-latest, stable) (push) Has been cancelled
Rust / build (macos-latest, stable) (pull_request) Has been cancelled
Rust / build (windows-latest, stable) (pull_request) Has been cancelled
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1658,6 +1658,7 @@ dependencies = [
|
||||
"itertools 0.13.0",
|
||||
"log",
|
||||
"nostr-sdk",
|
||||
"person",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"smallvec",
|
||||
@@ -4658,7 +4659,6 @@ version = "0.3.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"common",
|
||||
"device",
|
||||
"flume",
|
||||
"gpui",
|
||||
"log",
|
||||
|
||||
@@ -50,11 +50,28 @@ enum Signal {
|
||||
Eose,
|
||||
}
|
||||
|
||||
/// Inbox state.
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum InboxState {
|
||||
#[default]
|
||||
Idle,
|
||||
Checking,
|
||||
RelayNotAvailable,
|
||||
RelayConfigured(Box<Event>),
|
||||
Subscribing,
|
||||
}
|
||||
|
||||
impl InboxState {
|
||||
pub fn not_configured(&self) -> bool {
|
||||
matches!(self, InboxState::RelayNotAvailable)
|
||||
}
|
||||
}
|
||||
|
||||
/// Chat Registry
|
||||
#[derive(Debug)]
|
||||
pub struct ChatRegistry {
|
||||
/// Relay state for messaging relay list
|
||||
messaging_relay_list: Entity<RelayState>,
|
||||
state: Entity<InboxState>,
|
||||
|
||||
/// Collection of all chat rooms
|
||||
rooms: Vec<Entity<Room>>,
|
||||
@@ -84,7 +101,7 @@ impl ChatRegistry {
|
||||
|
||||
/// Create a new chat registry instance
|
||||
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let messaging_relay_list = cx.new(|_| RelayState::default());
|
||||
let state = cx.new(|_| InboxState::default());
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
|
||||
let mut subscriptions = smallvec![];
|
||||
@@ -106,26 +123,28 @@ impl ChatRegistry {
|
||||
|
||||
subscriptions.push(
|
||||
// Observe the nip17 state and load chat rooms on every state change
|
||||
cx.observe(&messaging_relay_list, |this, state, cx| {
|
||||
match state.read(cx) {
|
||||
RelayState::Configured => {
|
||||
this.get_messages(cx);
|
||||
}
|
||||
_ => {
|
||||
this.get_rooms(cx);
|
||||
}
|
||||
cx.observe(&state, |this, state, cx| {
|
||||
if let InboxState::RelayConfigured(event) = state.read(cx) {
|
||||
let relay_urls: Vec<_> = nip17::extract_relay_list(event).cloned().collect();
|
||||
this.get_messages(relay_urls, cx);
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
// Run at the end of current cycle
|
||||
// Run at the end of the current cycle
|
||||
cx.defer_in(window, |this, _window, cx| {
|
||||
// Handle nostr notifications
|
||||
this.handle_notifications(cx);
|
||||
|
||||
// Track unwrap gift wrap progress
|
||||
this.tracking(cx);
|
||||
|
||||
// Load chat rooms
|
||||
this.get_rooms(cx);
|
||||
});
|
||||
|
||||
Self {
|
||||
messaging_relay_list,
|
||||
state,
|
||||
rooms: vec![],
|
||||
tracking_flag: Arc::new(AtomicBool::new(false)),
|
||||
tasks: smallvec![],
|
||||
@@ -170,8 +189,6 @@ impl ChatRegistry {
|
||||
continue;
|
||||
}
|
||||
|
||||
log::info!("Received gift wrap event: {:?}", event);
|
||||
|
||||
// Extract the rumor from the gift wrap event
|
||||
match Self::extract_rumor(&client, &device_signer, event.as_ref()).await {
|
||||
Ok(rumor) => match rumor.created_at >= initialized_at {
|
||||
@@ -238,17 +255,19 @@ impl ChatRegistry {
|
||||
}));
|
||||
}
|
||||
|
||||
/// Ensure messaging relays are set up for the current user.
|
||||
fn ensure_messaging_relays(&mut self, cx: &mut Context<Self>) {
|
||||
let state = self.messaging_relay_list.downgrade();
|
||||
let task = self.verify_relays(cx);
|
||||
|
||||
self.tasks.push(cx.spawn(async move |_this, cx| {
|
||||
// Set state to checking
|
||||
self.set_state(InboxState::Checking, cx);
|
||||
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
let result = task.await?;
|
||||
|
||||
// Update state
|
||||
state.update(cx, |this, cx| {
|
||||
*this = result;
|
||||
cx.notify();
|
||||
this.update(cx, |this, cx| {
|
||||
this.set_state(result, cx);
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
@@ -256,13 +275,12 @@ impl ChatRegistry {
|
||||
}
|
||||
|
||||
// Verify messaging relay list for current user
|
||||
fn verify_relays(&mut self, cx: &mut Context<Self>) -> Task<Result<RelayState, Error>> {
|
||||
fn verify_relays(&mut self, cx: &mut Context<Self>) -> Task<Result<InboxState, Error>> {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
|
||||
let signer = nostr.read(cx).signer();
|
||||
let public_key = signer.public_key().unwrap();
|
||||
|
||||
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
|
||||
|
||||
cx.background_spawn(async move {
|
||||
@@ -287,8 +305,7 @@ impl ChatRegistry {
|
||||
while let Some((_url, res)) = stream.next().await {
|
||||
match res {
|
||||
Ok(event) => {
|
||||
log::info!("Received relay list event: {event:?}");
|
||||
return Ok(RelayState::Configured);
|
||||
return Ok(InboxState::RelayConfigured(Box::new(event)));
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to receive relay list event: {e}");
|
||||
@@ -296,41 +313,54 @@ impl ChatRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(RelayState::NotConfigured)
|
||||
Ok(InboxState::RelayNotAvailable)
|
||||
})
|
||||
}
|
||||
|
||||
/// Get all messages for current user
|
||||
fn get_messages(&mut self, cx: &mut Context<Self>) {
|
||||
let task = self.subscribe_to_giftwrap_events(cx);
|
||||
fn get_messages<I>(&mut self, relay_urls: I, cx: &mut Context<Self>)
|
||||
where
|
||||
I: IntoIterator<Item = RelayUrl>,
|
||||
{
|
||||
let task = self.subscribe(relay_urls, cx);
|
||||
|
||||
self.tasks.push(cx.spawn(async move |_this, _cx| {
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
task.await?;
|
||||
|
||||
// Update state
|
||||
this.update(cx, |this, cx| {
|
||||
this.set_state(InboxState::Subscribing, cx);
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}));
|
||||
}
|
||||
|
||||
/// Continuously get gift wrap events for the current user in their messaging relays
|
||||
fn subscribe_to_giftwrap_events(&mut self, cx: &mut Context<Self>) -> Task<Result<(), Error>> {
|
||||
fn subscribe<I>(&mut self, urls: I, cx: &mut Context<Self>) -> Task<Result<(), Error>>
|
||||
where
|
||||
I: IntoIterator<Item = RelayUrl>,
|
||||
{
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
|
||||
let signer = nostr.read(cx).signer();
|
||||
let public_key = signer.public_key().unwrap();
|
||||
|
||||
let messaging_relays = nostr.read(cx).messaging_relays(&public_key, cx);
|
||||
let urls = urls.into_iter().collect::<Vec<_>>();
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let urls = messaging_relays.await;
|
||||
let public_key = signer.get_public_key().await?;
|
||||
let filter = Filter::new().kind(Kind::GiftWrap).pubkey(public_key);
|
||||
let id = SubscriptionId::new(USER_GIFTWRAP);
|
||||
|
||||
// Ensure relay connections
|
||||
for url in urls.iter() {
|
||||
client.add_relay(url).and_connect().await?;
|
||||
}
|
||||
|
||||
// Construct target for subscription
|
||||
let target: HashMap<&RelayUrl, Filter> =
|
||||
urls.iter().map(|relay| (relay, filter.clone())).collect();
|
||||
let target: HashMap<RelayUrl, Filter> = urls
|
||||
.into_iter()
|
||||
.map(|relay| (relay, filter.clone()))
|
||||
.collect();
|
||||
|
||||
let output = client.subscribe(target).with_id(id).await?;
|
||||
|
||||
@@ -343,9 +373,17 @@ impl ChatRegistry {
|
||||
})
|
||||
}
|
||||
|
||||
/// Set the state of the inbox
|
||||
fn set_state(&mut self, state: InboxState, cx: &mut Context<Self>) {
|
||||
self.state.update(cx, |this, cx| {
|
||||
*this = state;
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
||||
/// Get the relay state
|
||||
pub fn relay_state(&self, cx: &App) -> RelayState {
|
||||
self.messaging_relay_list.read(cx).clone()
|
||||
pub fn state(&self, cx: &App) -> InboxState {
|
||||
self.state.read(cx).clone()
|
||||
}
|
||||
|
||||
/// Get the loading status of the chat registry
|
||||
@@ -491,16 +529,21 @@ impl ChatRegistry {
|
||||
pub fn get_rooms(&mut self, cx: &mut Context<Self>) {
|
||||
let task = self.get_rooms_from_database(cx);
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
let rooms = task.await.ok()?;
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
match task.await {
|
||||
Ok(rooms) => {
|
||||
this.update(cx, |this, cx| {
|
||||
this.extend_rooms(rooms, cx);
|
||||
this.sort(cx);
|
||||
})?;
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to load rooms: {}", e);
|
||||
}
|
||||
};
|
||||
|
||||
this.update(cx, move |this, cx| {
|
||||
this.extend_rooms(rooms, cx);
|
||||
this.sort(cx);
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.detach();
|
||||
Ok(())
|
||||
}));
|
||||
}
|
||||
|
||||
/// Create a task to load rooms from the database
|
||||
|
||||
@@ -1216,25 +1216,24 @@ impl ChatPanel {
|
||||
let encryption = matches!(signer_kind, SignerKind::Encryption);
|
||||
let user = matches!(signer_kind, SignerKind::User);
|
||||
|
||||
this.check_side(ui::Side::Right)
|
||||
.menu_with_check_and_disabled(
|
||||
"Auto",
|
||||
auto,
|
||||
Box::new(Command::ChangeSigner(SignerKind::Auto)),
|
||||
auto,
|
||||
)
|
||||
.menu_with_check_and_disabled(
|
||||
"Decoupled Encryption Key",
|
||||
encryption,
|
||||
Box::new(Command::ChangeSigner(SignerKind::Encryption)),
|
||||
encryption,
|
||||
)
|
||||
.menu_with_check_and_disabled(
|
||||
"User Identity",
|
||||
user,
|
||||
Box::new(Command::ChangeSigner(SignerKind::User)),
|
||||
user,
|
||||
)
|
||||
this.menu_with_check_and_disabled(
|
||||
"Auto",
|
||||
auto,
|
||||
Box::new(Command::ChangeSigner(SignerKind::Auto)),
|
||||
auto,
|
||||
)
|
||||
.menu_with_check_and_disabled(
|
||||
"Decoupled Encryption Key",
|
||||
encryption,
|
||||
Box::new(Command::ChangeSigner(SignerKind::Encryption)),
|
||||
encryption,
|
||||
)
|
||||
.menu_with_check_and_disabled(
|
||||
"User Identity",
|
||||
user,
|
||||
Box::new(Command::ChangeSigner(SignerKind::User)),
|
||||
user,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1339,8 +1338,8 @@ impl Render for ChatPanel {
|
||||
h_flex()
|
||||
.pl_1()
|
||||
.gap_1()
|
||||
.child(self.render_encryption_menu(window, cx))
|
||||
.child(self.render_emoji_menu(window, cx))
|
||||
.child(self.render_encryption_menu(window, cx))
|
||||
.child(
|
||||
Button::new("send")
|
||||
.icon(IconName::PaperPlaneFill)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use chat::ChatRegistry;
|
||||
use chat::{ChatRegistry, InboxState};
|
||||
use gpui::prelude::FluentBuilder;
|
||||
use gpui::{
|
||||
div, relative, svg, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle,
|
||||
@@ -83,15 +83,16 @@ impl Render for GreeterPanel {
|
||||
const DESCRIPTION: &str = "Chat Freely, Stay Private on Nostr.";
|
||||
|
||||
let chat = ChatRegistry::global(cx);
|
||||
let nip17_state = chat.read(cx).relay_state(cx);
|
||||
let nip17 = chat.read(cx).state(cx);
|
||||
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let nip65_state = nostr.read(cx).relay_list_state();
|
||||
let nip65 = nostr.read(cx).relay_list_state();
|
||||
|
||||
let signer = nostr.read(cx).signer();
|
||||
let owned = signer.owned();
|
||||
|
||||
let required_actions =
|
||||
nip65_state == RelayState::NotConfigured || nip17_state == RelayState::NotConfigured;
|
||||
nip65 == RelayState::NotConfigured || nip17 == InboxState::RelayNotAvailable;
|
||||
|
||||
h_flex()
|
||||
.size_full()
|
||||
@@ -152,7 +153,7 @@ impl Render for GreeterPanel {
|
||||
v_flex()
|
||||
.gap_2()
|
||||
.w_full()
|
||||
.when(nip65_state.not_configured(), |this| {
|
||||
.when(nip65.not_configured(), |this| {
|
||||
this.child(
|
||||
Button::new("relaylist")
|
||||
.icon(Icon::new(IconName::Relay))
|
||||
@@ -170,7 +171,7 @@ impl Render for GreeterPanel {
|
||||
}),
|
||||
)
|
||||
})
|
||||
.when(nip17_state.not_configured(), |this| {
|
||||
.when(nip17.not_configured(), |this| {
|
||||
this.child(
|
||||
Button::new("import")
|
||||
.icon(Icon::new(IconName::Relay))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use chat::{ChatEvent, ChatRegistry};
|
||||
use chat::{ChatEvent, ChatRegistry, InboxState};
|
||||
use gpui::prelude::FluentBuilder;
|
||||
use gpui::{
|
||||
div, rems, App, AppContext, Axis, Context, Entity, InteractiveElement, IntoElement,
|
||||
@@ -233,13 +233,13 @@ impl Workspace {
|
||||
),
|
||||
_ => this,
|
||||
})
|
||||
.map(|this| match chat.read(cx).relay_state(cx) {
|
||||
RelayState::Checking => {
|
||||
.map(|this| match chat.read(cx).state(cx) {
|
||||
InboxState::Checking => {
|
||||
this.child(div().text_xs().text_color(cx.theme().text_muted).child(
|
||||
SharedString::from("Fetching user's messaging relay list..."),
|
||||
))
|
||||
}
|
||||
RelayState::NotConfigured => this.child(
|
||||
InboxState::RelayNotAvailable => this.child(
|
||||
h_flex()
|
||||
.h_6()
|
||||
.w_full()
|
||||
|
||||
@@ -7,6 +7,7 @@ publish.workspace = true
|
||||
[dependencies]
|
||||
common = { path = "../common" }
|
||||
state = { path = "../state" }
|
||||
person = { path = "../person" }
|
||||
|
||||
gpui.workspace = true
|
||||
nostr-sdk.workspace = true
|
||||
|
||||
@@ -4,12 +4,11 @@ use std::time::Duration;
|
||||
use anyhow::{anyhow, Context as AnyhowContext, Error};
|
||||
use gpui::{App, AppContext, Context, Entity, Global, Subscription, Task, Window};
|
||||
use nostr_sdk::prelude::*;
|
||||
use person::PersonRegistry;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use state::{app_name, NostrRegistry, RelayState, DEVICE_GIFTWRAP, TIMEOUT};
|
||||
|
||||
mod device;
|
||||
|
||||
pub use device::*;
|
||||
use state::{
|
||||
app_name, Announcement, DeviceState, NostrRegistry, RelayState, DEVICE_GIFTWRAP, TIMEOUT,
|
||||
};
|
||||
|
||||
const IDENTIFIER: &str = "coop:device";
|
||||
|
||||
@@ -218,16 +217,17 @@ impl DeviceRegistry {
|
||||
let signer = nostr.read(cx).signer();
|
||||
let public_key = signer.public_key().unwrap();
|
||||
|
||||
let messaging_relays = nostr.read(cx).messaging_relays(&public_key, cx);
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let profile = persons.read(cx).get(&public_key, cx);
|
||||
let relay_urls = profile.messaging_relays().clone();
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let relay_urls = messaging_relays.await;
|
||||
let filter = Filter::new().kind(Kind::GiftWrap).pubkey(public_key);
|
||||
let id = SubscriptionId::new(DEVICE_GIFTWRAP);
|
||||
|
||||
// Construct target for subscription
|
||||
let target: HashMap<&RelayUrl, Filter> = relay_urls
|
||||
.iter()
|
||||
let target: HashMap<RelayUrl, Filter> = relay_urls
|
||||
.into_iter()
|
||||
.map(|relay| (relay, filter.clone()))
|
||||
.collect();
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ publish.workspace = true
|
||||
[dependencies]
|
||||
common = { path = "../common" }
|
||||
state = { path = "../state" }
|
||||
device = { path = "../device" }
|
||||
|
||||
gpui.workspace = true
|
||||
nostr-sdk.workspace = true
|
||||
|
||||
@@ -5,11 +5,10 @@ use std::time::Duration;
|
||||
|
||||
use anyhow::{anyhow, Error};
|
||||
use common::EventUtils;
|
||||
use device::Announcement;
|
||||
use gpui::{App, AppContext, Context, Entity, Global, Task};
|
||||
use nostr_sdk::prelude::*;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use state::{NostrRegistry, BOOTSTRAP_RELAYS, TIMEOUT};
|
||||
use state::{Announcement, NostrRegistry, BOOTSTRAP_RELAYS, TIMEOUT};
|
||||
|
||||
mod person;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use device::Announcement;
|
||||
use gpui::SharedString;
|
||||
use nostr_sdk::prelude::*;
|
||||
use state::Announcement;
|
||||
|
||||
const IMAGE_RESIZER: &str = "https://wsrv.nl";
|
||||
|
||||
|
||||
@@ -5,10 +5,7 @@ use nostr_sdk::prelude::*;
|
||||
/// Gossip
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Gossip {
|
||||
/// Gossip relays for each public key
|
||||
relays: HashMap<PublicKey, HashSet<(RelayUrl, Option<RelayMetadata>)>>,
|
||||
/// Messaging relays for each public key
|
||||
messaging_relays: HashMap<PublicKey, HashSet<RelayUrl>>,
|
||||
}
|
||||
|
||||
impl Gossip {
|
||||
@@ -69,39 +66,5 @@ impl Gossip {
|
||||
})
|
||||
.take(3),
|
||||
);
|
||||
|
||||
log::info!("Updating gossip relays for: {}", event.pubkey);
|
||||
}
|
||||
|
||||
/// Get messaging relays for a given public key
|
||||
pub fn messaging_relays(&self, public_key: &PublicKey) -> Vec<RelayUrl> {
|
||||
self.messaging_relays
|
||||
.get(public_key)
|
||||
.cloned()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Insert messaging relays for a public key
|
||||
pub fn insert_messaging_relays(&mut self, event: &Event) {
|
||||
self.messaging_relays
|
||||
.entry(event.pubkey)
|
||||
.or_default()
|
||||
.extend(
|
||||
event
|
||||
.tags
|
||||
.iter()
|
||||
.filter_map(|tag| {
|
||||
if let Some(TagStandard::Relay(url)) = tag.as_standardized() {
|
||||
Some(url.to_owned())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.take(3),
|
||||
);
|
||||
|
||||
log::info!("Updating messaging relays for: {}", event.pubkey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,12 +11,14 @@ use nostr_lmdb::prelude::*;
|
||||
use nostr_sdk::prelude::*;
|
||||
|
||||
mod constants;
|
||||
mod device;
|
||||
mod gossip;
|
||||
mod nip05;
|
||||
mod nip96;
|
||||
mod signer;
|
||||
|
||||
pub use constants::*;
|
||||
pub use device::*;
|
||||
pub use gossip::*;
|
||||
pub use nip05::*;
|
||||
pub use nip96::*;
|
||||
@@ -181,18 +183,16 @@ impl NostrRegistry {
|
||||
} = notification
|
||||
{
|
||||
// Skip if the event has already been processed
|
||||
if !processed_events.insert(event.id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
match event.kind {
|
||||
Kind::RelayList => {
|
||||
tx.send_async(event.into_owned()).await?;
|
||||
if processed_events.insert(event.id) {
|
||||
match event.kind {
|
||||
Kind::RelayList => {
|
||||
tx.send_async(event.into_owned()).await?;
|
||||
}
|
||||
Kind::InboxRelays => {
|
||||
tx.send_async(event.into_owned()).await?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Kind::InboxRelays => {
|
||||
tx.send_async(event.into_owned()).await?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,20 +205,11 @@ impl NostrRegistry {
|
||||
|
||||
self.tasks.push(cx.spawn(async move |_this, cx| {
|
||||
while let Ok(event) = rx.recv_async().await {
|
||||
match event.kind {
|
||||
Kind::RelayList => {
|
||||
gossip.update(cx, |this, cx| {
|
||||
this.insert_relays(&event);
|
||||
cx.notify();
|
||||
})?;
|
||||
}
|
||||
Kind::InboxRelays => {
|
||||
gossip.update(cx, |this, cx| {
|
||||
this.insert_messaging_relays(&event);
|
||||
cx.notify();
|
||||
})?;
|
||||
}
|
||||
_ => {}
|
||||
if let Kind::RelayList = event.kind {
|
||||
gossip.update(cx, |this, cx| {
|
||||
this.insert_relays(&event);
|
||||
cx.notify();
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,15 +247,6 @@ impl NostrRegistry {
|
||||
self.relay_list_state.clone()
|
||||
}
|
||||
|
||||
/// Get a relay hint (messaging relay) for a given public key
|
||||
pub fn relay_hint(&self, public_key: &PublicKey, cx: &App) -> Option<RelayUrl> {
|
||||
self.gossip
|
||||
.read(cx)
|
||||
.messaging_relays(public_key)
|
||||
.first()
|
||||
.cloned()
|
||||
}
|
||||
|
||||
/// Get a list of write relays for a given public key
|
||||
pub fn write_relays(&self, public_key: &PublicKey, cx: &App) -> Task<Vec<RelayUrl>> {
|
||||
let client = self.client();
|
||||
@@ -295,21 +277,6 @@ impl NostrRegistry {
|
||||
})
|
||||
}
|
||||
|
||||
/// Get a list of messaging relays for a given public key
|
||||
pub fn messaging_relays(&self, public_key: &PublicKey, cx: &App) -> Task<Vec<RelayUrl>> {
|
||||
let client = self.client();
|
||||
let relays = self.gossip.read(cx).messaging_relays(public_key);
|
||||
|
||||
cx.background_spawn(async move {
|
||||
// Ensure relay connections
|
||||
for url in relays.iter() {
|
||||
client.add_relay(url).and_connect().await.ok();
|
||||
}
|
||||
|
||||
relays
|
||||
})
|
||||
}
|
||||
|
||||
/// Set the connected status of the client
|
||||
fn set_connected(&mut self, cx: &mut Context<Self>) {
|
||||
self.connected = true;
|
||||
|
||||
Reference in New Issue
Block a user