feat: add support for nip05 in compose modal

This commit is contained in:
2025-02-16 13:43:49 +07:00
parent 0feb69b72e
commit ea5009933c

View File

@@ -1,3 +1,4 @@
use async_utility::task::spawn;
use chats::{registry::ChatRegistry, room::Room}; use chats::{registry::ChatRegistry, room::Room};
use common::{ use common::{
profile::NostrProfile, profile::NostrProfile,
@@ -71,9 +72,13 @@ impl Compose {
subscriptions.push(cx.subscribe_in( subscriptions.push(cx.subscribe_in(
&user_input, &user_input,
window, window,
move |this, _, input_event, window, cx| { move |this, input, input_event, window, cx| {
if let InputEvent::PressEnter = input_event { if let InputEvent::PressEnter = input_event {
this.add(window, cx); if input.read(cx).text().contains("@") {
this.add_nip05(window, cx);
} else {
this.add_npub(window, cx)
}
} }
}, },
)); ));
@@ -206,14 +211,19 @@ impl Compose {
self.is_submitting self.is_submitting
} }
fn add(&mut self, window: &mut Window, cx: &mut Context<Self>) { fn add_npub(&mut self, window: &mut Window, cx: &mut Context<Self>) {
let window_handle = window.window_handle(); let window_handle = window.window_handle();
let content = self.user_input.read(cx).text().to_string(); let content = self.user_input.read(cx).text().to_string();
// Show loading spinner // Show loading spinner
self.set_loading(true, cx); self.set_loading(true, cx);
if let Ok(public_key) = PublicKey::parse(&content) { let Ok(public_key) = PublicKey::parse(&content) else {
self.set_loading(false, cx);
self.set_error(Some("Public Key is not valid".into()), cx);
return;
};
if self if self
.contacts .contacts
.read(cx) .read(cx)
@@ -224,13 +234,12 @@ impl Compose {
return; return;
}; };
cx.spawn(|this, mut cx| async move { let client = get_client();
let (tx, rx) = oneshot::channel::<Metadata>(); let (tx, rx) = oneshot::channel::<Metadata>();
cx.background_spawn(async move { cx.background_spawn(async move {
let client = get_client();
let metadata = (client let metadata = (client
.fetch_metadata(public_key, Duration::from_secs(3)) .fetch_metadata(public_key, Duration::from_secs(2))
.await) .await)
.unwrap_or_default(); .unwrap_or_default();
@@ -238,6 +247,7 @@ impl Compose {
}) })
.detach(); .detach();
cx.spawn(|this, mut cx| async move {
if let Ok(metadata) = rx.await { if let Ok(metadata) = rx.await {
_ = cx.update_window(window_handle, |_, window, cx| { _ = cx.update_window(window_handle, |_, window, cx| {
_ = this.update(cx, |this, cx| { _ = this.update(cx, |this, cx| {
@@ -264,10 +274,70 @@ impl Compose {
} }
}) })
.detach(); .detach();
} else {
self.set_loading(false, cx);
self.set_error(Some("Public Key is not valid".into()), cx);
} }
fn add_nip05(&mut self, window: &mut Window, cx: &mut Context<Self>) {
let window_handle = window.window_handle();
let content = self.user_input.read(cx).text().to_string();
// Show loading spinner
self.set_loading(true, cx);
let client = get_client();
let (tx, rx) = oneshot::channel::<Option<NostrProfile>>();
cx.background_spawn(async move {
spawn(async move {
if let Ok(profile) = nip05::profile(&content, None).await {
let metadata = (client
.fetch_metadata(profile.public_key, Duration::from_secs(2))
.await)
.unwrap_or_default();
_ = tx.send(Some(NostrProfile::new(profile.public_key, metadata)));
} else {
_ = tx.send(None);
}
});
})
.detach();
cx.spawn(|this, mut cx| async move {
if let Ok(Some(profile)) = rx.await {
_ = cx.update_window(window_handle, |_, window, cx| {
_ = this.update(cx, |this, cx| {
let public_key = profile.public_key();
this.contacts.update(cx, |this, cx| {
this.insert(0, profile);
cx.notify();
});
this.selected.update(cx, |this, cx| {
this.insert(public_key);
cx.notify();
});
// Stop loading indicator
this.set_loading(false, cx);
// Clear input
this.user_input.update(cx, |this, cx| {
this.set_text("", window, cx);
cx.notify();
});
});
});
} else {
_ = cx.update_window(window_handle, |_, _, cx| {
_ = this.update(cx, |this, cx| {
this.set_loading(false, cx);
this.set_error(Some("NIP-05 Address is not valid".into()), cx);
});
});
}
})
.detach();
} }
fn set_error(&mut self, error: Option<SharedString>, cx: &mut Context<Self>) { fn set_error(&mut self, error: Option<SharedString>, cx: &mut Context<Self>) {
@@ -372,9 +442,13 @@ impl Render for Compose {
.small() .small()
.rounded(ButtonRounded::Size(px(9999.))) .rounded(ButtonRounded::Size(px(9999.)))
.loading(self.is_loading) .loading(self.is_loading)
.on_click( .on_click(cx.listener(|this, _, window, cx| {
cx.listener(|this, _, window, cx| this.add(window, cx)), if this.user_input.read(cx).text().contains("@") {
), this.add_nip05(window, cx);
} else {
this.add_npub(window, cx);
}
})),
) )
.child(self.user_input.clone()), .child(self.user_input.clone()),
) )