re add verify relay connection (#197)

This commit is contained in:
reya
2025-10-29 07:42:50 +07:00
committed by GitHub
parent b0fa98831d
commit 649cdff49c
5 changed files with 104 additions and 33 deletions

View File

@@ -80,7 +80,7 @@ pub struct Chat {
image_cache: Entity<RetainAllImageCache>,
_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)),
),
)
})

View File

@@ -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
}

View File

@@ -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

View File

@@ -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<Result<HashMap<PublicKey, bool>, 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<Result<Vec<UnsignedEvent>, Error>> {
let conversation_id = self.id.to_string();