diff --git a/crates/chat/src/room.rs b/crates/chat/src/room.rs index f8829c1..ea69c2d 100644 --- a/crates/chat/src/room.rs +++ b/crates/chat/src/room.rs @@ -13,7 +13,6 @@ use state::{NostrRegistry, TIMEOUT}; use crate::NewMessage; -const NO_RELAY: &str = "User hasn't set up any messaging relays yet."; const NO_DEKEY: &str = "User hasn't set up a decoupled encryption key yet."; const USER_NO_DEKEY: &str = "You haven't set up a decoupled encryption key or it's not available."; @@ -501,16 +500,9 @@ impl Room { // Process each member for member in members { - let relays = member.messaging_relays(); let announcement = member.announcement(); let public_key = member.public_key(); - // Skip members with no relays - if relays.is_empty() { - reports.push(SendReport::new(public_key).error(NO_RELAY)); - continue; - } - // Handle encryption signer requirements if signer_kind.encryption() { // Receiver didn't set up a decoupled encryption key @@ -546,7 +538,7 @@ impl Room { }; // Send the gift wrap event and collect the report - match send_gift_wrap(&client, &signer, &member, &rumor, signer_kind, relays).await { + match send_gift_wrap(&client, &signer, &member, &rumor, signer_kind).await { Ok(report) => { reports.push(report); sents += 1; @@ -561,7 +553,6 @@ impl Room { // Send backup to current user if needed if backup && sents >= 1 { let public_key = sender.public_key(); - let relays = sender.messaging_relays(); // Determine the signer to use let signer = match signer_kind { @@ -582,7 +573,7 @@ impl Room { SignerKind::User => user_signer.clone(), }; - match send_gift_wrap(&client, &signer, &sender, &rumor, signer_kind, relays).await { + match send_gift_wrap(&client, &signer, &sender, &rumor, signer_kind).await { Ok(report) => reports.push(report), Err(error) => { let report = SendReport::new(public_key).error(error.to_string()); @@ -603,7 +594,6 @@ async fn send_gift_wrap( receiver: &Person, rumor: &UnsignedEvent, config: &SignerKind, - to: &[RelayUrl], ) -> Result where T: NostrSigner + 'static, @@ -634,15 +624,10 @@ where // Construct the gift wrap event let event = EventBuilder::gift_wrap(signer, &receiver, rumor.clone(), extra_tags).await?; - // Connect to each relay before sending - for url in to.iter() { - client.add_relay(url).and_connect().await.ok(); - } - // Send the gift wrap event and collect the report let report = client .send_event(&event) - .to(to) + .to_nip17() .ack_policy(AckPolicy::none()) .await .map(|output| { diff --git a/crates/chat_ui/src/lib.rs b/crates/chat_ui/src/lib.rs index 177d672..7481d35 100644 --- a/crates/chat_ui/src/lib.rs +++ b/crates/chat_ui/src/lib.rs @@ -379,9 +379,13 @@ impl ChatPanel { /// Send message in the background and wait for the response fn send_and_wait(&mut self, rumor: UnsignedEvent, window: &mut Window, cx: &mut Context) { let sent_ids = self.sent_ids.clone(); + // This can't fail, because we already ensured that the ID is set let id = rumor.id.unwrap(); + // Add empty reports + self.insert_reports(id, vec![], cx); + // Upgrade room reference let Some(room) = self.room.upgrade() else { return; @@ -430,7 +434,7 @@ impl ChatPanel { /// Insert reports fn insert_reports(&mut self, id: EventId, reports: Vec, cx: &mut Context) { self.reports_by_id.update(cx, |this, cx| { - this.insert(id, reports); + this.entry(id).or_default().extend(reports); cx.notify(); }); } @@ -924,20 +928,26 @@ impl ChatPanel { fn render_sent_reports(&self, id: &EventId, cx: &App) -> impl IntoElement { let reports = self.sent_reports(id, cx); + let pending = reports + .as_ref() + .is_some_and(|reports| reports.is_empty() || reports.iter().any(|r| r.pending())); + let success = reports .as_ref() - .is_some_and(|reports| reports.iter().any(|r| r.success())); + .is_some_and(|reports| !reports.is_empty() && reports.iter().any(|r| r.success())); let failed = reports .as_ref() - .is_some_and(|reports| reports.iter().all(|r| r.failed())); + .is_some_and(|reports| !reports.is_empty() && reports.iter().all(|r| r.failed())); let label = if success { SharedString::from("• Sent") } else if failed { - SharedString::from("• Failed") - } else { + SharedString::from("• Error") + } else if pending { SharedString::from("• Sending...") + } else { + SharedString::from("• Unknown") }; div() @@ -945,22 +955,24 @@ impl ChatPanel { .child(label) .when(failed, |this| this.text_color(cx.theme().text_danger)) .when_some(reports, |this, reports| { - this.on_click(move |_e, window, cx| { - let reports = reports.clone(); + this.when(!pending, |this| { + this.on_click(move |_e, window, cx| { + let reports = reports.clone(); - window.open_modal(cx, move |this, _window, cx| { - this.title(SharedString::from("Sent Reports")) - .show_close(true) - .child(v_flex().gap_4().children({ - let mut items = Vec::with_capacity(reports.len()); + window.open_modal(cx, move |this, _window, cx| { + this.title(SharedString::from("Sent Reports")) + .show_close(true) + .child(v_flex().gap_4().children({ + let mut items = Vec::with_capacity(reports.len()); - for report in reports.iter() { - items.push(Self::render_report(report, cx)) - } + for report in reports.iter() { + items.push(Self::render_report(report, cx)) + } - items - })) - }); + items + })) + }); + }) }) }) }