.
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m40s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m50s
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m40s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m50s
This commit is contained in:
@@ -98,7 +98,7 @@ impl ChatRegistry {
|
||||
/// Create a new chat registry instance
|
||||
fn new(cx: &mut Context<Self>) -> Self {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let identity = nostr.read(cx).identity();
|
||||
let nip17_state = nostr.read(cx).nip17_state();
|
||||
|
||||
let device = DeviceRegistry::global(cx);
|
||||
let device_signer = device.read(cx).device_signer.clone();
|
||||
@@ -114,8 +114,8 @@ impl ChatRegistry {
|
||||
|
||||
subscriptions.push(
|
||||
// Observe the identity
|
||||
cx.observe(&identity, |this, state, cx| {
|
||||
if state.read(cx).messaging_relays_state() == RelayState::Set {
|
||||
cx.observe(&nip17_state, |this, state, cx| {
|
||||
if state.read(cx) == &RelayState::Configured {
|
||||
// Handle nostr notifications
|
||||
this.handle_notifications(cx);
|
||||
// Track unwrapping progress
|
||||
@@ -536,9 +536,9 @@ impl ChatRegistry {
|
||||
}
|
||||
|
||||
// Set this room is ongoing if the new message is from current user
|
||||
if author == nostr.read(cx).identity().read(cx).public_key() {
|
||||
this.set_ongoing(cx);
|
||||
}
|
||||
// if author == nostr.read(cx).identity().read(cx).public_key() {
|
||||
// this.set_ongoing(cx);
|
||||
// }
|
||||
|
||||
// Emit the new message to the room
|
||||
this.emit_message(message, cx);
|
||||
|
||||
@@ -216,28 +216,6 @@ impl Room {
|
||||
self.members.clone()
|
||||
}
|
||||
|
||||
/// Returns the members of the room with their messaging relays
|
||||
pub fn members_with_relays(&self, cx: &App) -> Task<Vec<(PublicKey, Vec<RelayUrl>)>> {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let mut tasks = vec![];
|
||||
|
||||
for member in self.members.iter() {
|
||||
let task = nostr.read(cx).messaging_relays(member, cx);
|
||||
tasks.push((*member, task));
|
||||
}
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let mut results = vec![];
|
||||
|
||||
for (public_key, task) in tasks.into_iter() {
|
||||
let urls = task.await;
|
||||
results.push((public_key, urls));
|
||||
}
|
||||
|
||||
results
|
||||
})
|
||||
}
|
||||
|
||||
/// Checks if the room has more than two members (group)
|
||||
pub fn is_group(&self) -> bool {
|
||||
self.members.len() > 2
|
||||
@@ -266,17 +244,7 @@ impl Room {
|
||||
/// Display member is always different from the current user.
|
||||
pub fn display_member(&self, cx: &App) -> Person {
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let public_key = nostr.read(cx).identity().read(cx).public_key();
|
||||
|
||||
let target_member = self
|
||||
.members
|
||||
.iter()
|
||||
.find(|&member| member != &public_key)
|
||||
.or_else(|| self.members.first())
|
||||
.expect("Room should have at least one member");
|
||||
|
||||
persons.read(cx).get(target_member, cx)
|
||||
persons.read(cx).get(&self.members[0], cx)
|
||||
}
|
||||
|
||||
/// Merge the names of the first two members of the room.
|
||||
@@ -377,68 +345,79 @@ impl Room {
|
||||
})
|
||||
}
|
||||
|
||||
/// Create a new message event (unsigned)
|
||||
pub fn create_message(&self, content: &str, replies: &[EventId], cx: &App) -> UnsignedEvent {
|
||||
/// Create a new unsigned message event
|
||||
pub fn create_message(
|
||||
&self,
|
||||
content: &str,
|
||||
replies: Vec<EventId>,
|
||||
cx: &App,
|
||||
) -> Task<Result<UnsignedEvent, Error>> {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
|
||||
// Get current user
|
||||
let public_key = nostr.read(cx).identity().read(cx).public_key();
|
||||
|
||||
// Get room's subject
|
||||
let subject = self.subject.clone();
|
||||
let content = content.to_string();
|
||||
|
||||
let mut tags = vec![];
|
||||
let mut member_and_relay_hints = HashMap::new();
|
||||
|
||||
// Add receivers
|
||||
//
|
||||
// NOTE: current user will be removed from the list of receivers
|
||||
// Populate the hashmap with member and relay hint tasks
|
||||
for member in self.members.iter() {
|
||||
// Get relay hint if available
|
||||
let relay_url = nostr.read(cx).relay_hint(member, cx);
|
||||
|
||||
// Construct a public key tag with relay hint
|
||||
let tag = TagStandard::PublicKey {
|
||||
public_key: member.to_owned(),
|
||||
relay_url,
|
||||
alias: None,
|
||||
uppercase: false,
|
||||
};
|
||||
|
||||
tags.push(Tag::from_standardized_without_cell(tag));
|
||||
let hint = nostr.read(cx).relay_hint(member, cx);
|
||||
member_and_relay_hints.insert(member.to_owned(), hint);
|
||||
}
|
||||
|
||||
// Add subject tag if it's present
|
||||
if let Some(value) = subject {
|
||||
tags.push(Tag::from_standardized_without_cell(TagStandard::Subject(
|
||||
value.to_string(),
|
||||
)));
|
||||
}
|
||||
cx.background_spawn(async move {
|
||||
let signer = client.signer().context("Signer not found")?;
|
||||
let public_key = signer.get_public_key().await?;
|
||||
|
||||
// Add reply/quote tag
|
||||
if replies.len() == 1 {
|
||||
tags.push(Tag::event(replies[0]))
|
||||
} else {
|
||||
for id in replies {
|
||||
let tag = TagStandard::Quote {
|
||||
event_id: id.to_owned(),
|
||||
relay_url: None,
|
||||
public_key: None,
|
||||
// List of event tags for each receiver
|
||||
let mut tags = vec![];
|
||||
|
||||
for (member, task) in member_and_relay_hints.into_iter() {
|
||||
// Skip current user
|
||||
if member == public_key {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get relay hint if available
|
||||
let relay_url = task.await;
|
||||
|
||||
// Construct a public key tag with relay hint
|
||||
let tag = TagStandard::PublicKey {
|
||||
public_key: member,
|
||||
relay_url,
|
||||
alias: None,
|
||||
uppercase: false,
|
||||
};
|
||||
tags.push(Tag::from_standardized_without_cell(tag))
|
||||
|
||||
tags.push(Tag::from_standardized_without_cell(tag));
|
||||
}
|
||||
}
|
||||
|
||||
// Construct a direct message event
|
||||
//
|
||||
// WARNING: never sign and send this event to relays
|
||||
let mut event = EventBuilder::new(Kind::PrivateDirectMessage, content)
|
||||
.tags(tags)
|
||||
.build(public_key);
|
||||
// Add subject tag if present
|
||||
if let Some(value) = subject {
|
||||
tags.push(Tag::from_standardized_without_cell(TagStandard::Subject(
|
||||
value.to_string(),
|
||||
)));
|
||||
}
|
||||
|
||||
// Ensure the event id has been generated
|
||||
event.ensure_id();
|
||||
// Add all reply tags
|
||||
for id in replies {
|
||||
tags.push(Tag::event(id))
|
||||
}
|
||||
|
||||
event
|
||||
// Construct a direct message event
|
||||
//
|
||||
// WARNING: never sign and send this event to relays
|
||||
// TODO
|
||||
let mut event = EventBuilder::new(Kind::PrivateDirectMessage, content)
|
||||
.tags(tags)
|
||||
.build(Keys::generate().public_key());
|
||||
|
||||
// Ensure the event ID has been generated
|
||||
event.ensure_id();
|
||||
|
||||
Ok(event)
|
||||
})
|
||||
}
|
||||
|
||||
/// Create a task to send a message to all room members
|
||||
@@ -450,46 +429,27 @@ impl Room {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
|
||||
// Get current user's public key and relays
|
||||
let current_user = nostr.read(cx).identity().read(cx).public_key();
|
||||
let current_user_relays = nostr.read(cx).messaging_relays(¤t_user, cx);
|
||||
|
||||
let mut members = self.members();
|
||||
let rumor = rumor.to_owned();
|
||||
|
||||
// Get all members and their messaging relays
|
||||
let task = self.members_with_relays(cx);
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let signer = client.signer().context("Signer not found")?;
|
||||
let current_user_relays = current_user_relays.await;
|
||||
let mut members = task.await;
|
||||
let current_user = signer.get_public_key().await?;
|
||||
|
||||
// Remove the current user's public key from the list of receivers
|
||||
// the current user will be handled separately
|
||||
members.retain(|(this, _)| this != ¤t_user);
|
||||
members.retain(|this| this != ¤t_user);
|
||||
|
||||
// Collect the send reports
|
||||
let mut reports: Vec<SendReport> = vec![];
|
||||
|
||||
for (receiver, relays) in members.into_iter() {
|
||||
// Check if there are any relays to send the message to
|
||||
if relays.is_empty() {
|
||||
reports.push(SendReport::new(receiver).relays_not_found());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ensure relay connection
|
||||
for url in relays.iter() {
|
||||
client.add_relay(url).await?;
|
||||
client.connect_relay(url).await?;
|
||||
}
|
||||
|
||||
for receiver in members.into_iter() {
|
||||
// Construct the gift wrap event
|
||||
let event =
|
||||
EventBuilder::gift_wrap(signer, &receiver, rumor.clone(), vec![]).await?;
|
||||
|
||||
// Send the gift wrap event to the messaging relays
|
||||
match client.send_event(&event).to(&relays).await {
|
||||
match client.send_event(&event).to_nip17().await {
|
||||
Ok(output) => {
|
||||
let id = output.id().to_owned();
|
||||
let auth = output.failed.iter().any(|(_, s)| s.starts_with("auth-"));
|
||||
@@ -531,20 +491,8 @@ impl Room {
|
||||
|
||||
// Only send a backup message to current user if sent successfully to others
|
||||
if reports.iter().all(|r| r.is_sent_success()) {
|
||||
// Check if there are any relays to send the event to
|
||||
if current_user_relays.is_empty() {
|
||||
reports.push(SendReport::new(current_user).relays_not_found());
|
||||
return Ok(reports);
|
||||
}
|
||||
|
||||
// Ensure relay connection
|
||||
for url in current_user_relays.iter() {
|
||||
client.add_relay(url).await?;
|
||||
client.connect_relay(url).await?;
|
||||
}
|
||||
|
||||
// Send the event to the messaging relays
|
||||
match client.send_event_to(current_user_relays, &event).await {
|
||||
match client.send_event(&event).to_nip17().await {
|
||||
Ok(output) => {
|
||||
reports.push(SendReport::new(current_user).status(output));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user