From 649cdff49c44e554dad14af90baccb66503d069a Mon Sep 17 00:00:00 2001 From: reya <123083837+reyamir@users.noreply.github.com> Date: Wed, 29 Oct 2025 07:42:50 +0700 Subject: [PATCH] re add verify relay connection (#197) --- crates/coop/src/views/chat/mod.rs | 38 +++++++++++++++-- crates/coop/src/views/sidebar/list_item.rs | 4 +- crates/coop/src/views/sidebar/mod.rs | 47 ++++++++++++---------- crates/registry/src/room.rs | 42 +++++++++++++++++-- locales/app.yml | 6 +-- 5 files changed, 104 insertions(+), 33 deletions(-) diff --git a/crates/coop/src/views/chat/mod.rs b/crates/coop/src/views/chat/mod.rs index ab968bac..5dc7bc36 100644 --- a/crates/coop/src/views/chat/mod.rs +++ b/crates/coop/src/views/chat/mod.rs @@ -80,7 +80,7 @@ pub struct Chat { image_cache: Entity, _subscriptions: SmallVec<[Subscription; 3]>, - _tasks: SmallVec<[Task<()>; 2]>, + _tasks: SmallVec<[Task<()>; 3]>, } impl Chat { @@ -102,6 +102,7 @@ impl Chat { let list_state = ListState::new(messages.len(), ListAlignment::Bottom, px(1024.)); let connect = room.read(cx).connect(cx); + let verify_connections = room.read(cx).verify_connections(cx); let get_messages = room.read(cx).get_messages(cx); let mut subscriptions = smallvec![]; @@ -135,6 +136,37 @@ impl Chat { }), ); + tasks.push( + // Connect and verify all members messaging relays + cx.spawn_in(window, async move |this, cx| { + // Wait for 5 seconds before connecting and verifying + cx.background_executor().timer(Duration::from_secs(5)).await; + + let result = verify_connections.await; + + this.update_in(cx, |this, window, cx| { + match result { + Ok(data) => { + let registry = Registry::global(cx); + + for (public_key, status) in data.into_iter() { + if !status { + let profile = registry.read(cx).get_person(&public_key, cx); + let content = t!("chat.nip17_warn", u = profile.display_name()); + + this.insert_warning(content, cx); + } + } + } + Err(e) => { + window.push_notification(e.to_string(), cx); + } + }; + }) + .ok(); + }), + ); + subscriptions.push( // Subscribe to input events cx.subscribe_in( @@ -865,7 +897,7 @@ impl Chat { .flex_1() .w_full() .text_center() - .child(shared_t!("chat.nip17_not_found", u = name)), + .child(shared_t!("chat.nip17_warn", u = name)), ), ) }) @@ -886,7 +918,7 @@ impl Chat { .flex_1() .w_full() .text_center() - .child(shared_t!("chat.device_not_found", u = name)), + .child(shared_t!("chat.device_error", u = name)), ), ) }) diff --git a/crates/coop/src/views/sidebar/list_item.rs b/crates/coop/src/views/sidebar/list_item.rs index 9ec241eb..33363b1b 100644 --- a/crates/coop/src/views/sidebar/list_item.rs +++ b/crates/coop/src/views/sidebar/list_item.rs @@ -52,8 +52,8 @@ impl RoomListItem { self } - pub fn public_key(mut self, public_key: &PublicKey) -> Self { - self.public_key = Some(public_key.to_owned()); + pub fn public_key(mut self, public_key: PublicKey) -> Self { + self.public_key = Some(public_key); self } diff --git a/crates/coop/src/views/sidebar/mod.rs b/crates/coop/src/views/sidebar/mod.rs index 13adff23..4c874eeb 100644 --- a/crates/coop/src/views/sidebar/mod.rs +++ b/crates/coop/src/views/sidebar/mod.rs @@ -4,7 +4,7 @@ use std::time::Duration; use anyhow::{anyhow, Error}; use common::debounced_delay::DebouncedDelay; -use common::display::{RenderedTimestamp, TextUtils}; +use common::display::{RenderedProfile, RenderedTimestamp, TextUtils}; use gpui::prelude::FluentBuilder; use gpui::{ deferred, div, relative, uniform_list, AnyElement, App, AppContext, Context, Entity, @@ -610,28 +610,31 @@ impl Sidebar { let mut items = Vec::with_capacity(range.end - range.start); for ix in range { - if let Some(room) = rooms.get(ix) { - let this = room.read(cx); - let room_id = this.id; - let handler = cx.listener({ - move |this, _, window, cx| { - this.open_room(room_id, window, cx); - } - }); - - items.push( - RoomListItem::new(ix) - .room_id(room_id) - .name(this.display_name(cx)) - .avatar(this.display_image(proxy, cx)) - .created_at(this.created_at.to_ago()) - .public_key(&this.members[0]) - .kind(this.kind) - .on_click(handler), - ) - } else { + let Some(room) = rooms.get(ix) else { items.push(RoomListItem::new(ix)); - } + continue; + }; + + let this = room.read(cx); + let room_id = this.id; + let member = this.display_member(cx); + + let handler = cx.listener({ + move |this, _, window, cx| { + this.open_room(room_id, window, cx); + } + }); + + items.push( + RoomListItem::new(ix) + .room_id(room_id) + .name(member.display_name()) + .avatar(member.avatar(proxy)) + .public_key(member.public_key()) + .kind(this.kind) + .created_at(this.created_at.to_ago()) + .on_click(handler), + ) } items diff --git a/crates/registry/src/room.rs b/crates/registry/src/room.rs index a55b1d63..1f0ebafd 100644 --- a/crates/registry/src/room.rs +++ b/crates/registry/src/room.rs @@ -295,10 +295,10 @@ impl Room { } } - /// Get a single member to represent the room + /// Get a member to represent the room /// - /// This member is always different from the current user. - fn display_member(&self, cx: &App) -> Profile { + /// Display member is always different from the current user. + pub fn display_member(&self, cx: &App) -> Profile { let registry = Registry::global(cx); let signer_pubkey = registry.read(cx).signer_pubkey(); @@ -386,6 +386,42 @@ impl Room { }) } + pub fn verify_connections(&self, cx: &App) -> Task, Error>> { + let members = self.members(); + + cx.background_spawn(async move { + let client = app_state().client(); + let mut result = HashMap::default(); + + for member in members.into_iter() { + let filter = Filter::new() + .kind(Kind::InboxRelays) + .author(member) + .limit(1); + + if let Some(event) = client.database().query(filter).await?.first() { + let urls: Vec<&RelayUrl> = nip17::extract_relay_list(event).collect(); + + if urls.is_empty() { + result.insert(member, false); + continue; + } + + for url in urls { + client.add_relay(url).await.ok(); + client.connect_relay(url).await.ok(); + } + + result.insert(member, true); + } else { + result.insert(member, false); + } + } + + Ok(result) + }) + } + /// Get all messages belonging to the room pub fn get_messages(&self, cx: &App) -> Task, Error>> { let conversation_id = self.id.to_string(); diff --git a/locales/app.yml b/locales/app.yml index 1b1b1205..f5b3c47f 100644 --- a/locales/app.yml +++ b/locales/app.yml @@ -407,9 +407,9 @@ chat: en: "Successfully" reports: en: "Sent Reports" - nip17_not_found: - en: "%{u} has not set up Messaging Relays, so they won't receive your message." - device_not_found: + nip17_warn: + en: "%{u} has not set up Messaging Relays, they cannot receive your message." + device_error: en: "You're sending with an encryption key, but %{u} has not set up an encryption key yet. Try sending with your identity instead." sidebar: