diff --git a/src/cli/commands/issue/new.rs b/src/cli/commands/issue/new.rs index 4120f5a..e68783c 100644 --- a/src/cli/commands/issue/new.rs +++ b/src/cli/commands/issue/new.rs @@ -103,31 +103,9 @@ impl CommandRunner for NewArgs { client.add_relays(&naddrs.extract_relays()).await; let relays_list = client.user_relays_list(user_pubk).await?; - let mut write_relays = [ - options.relays, - utils::add_write_relays(relays_list.as_ref()), - client - .fetch_repos(&naddrs.into_coordinates()) - .await? - .extract_relays(), - ] - .concat(); let (subject, content) = self.issue_content()?; let content_details = client.parse_content(&content).await; - write_relays.extend(content_details.write_relays.clone()); - - // Include read relays for each repository owner (if found) - write_relays.extend( - future::join_all( - naddrs_iter - .clone() - .map(|c| client.read_relays_from_user(c.public_key)), - ) - .await - .into_iter() - .flatten(), - ); let event = EventBuilder::new_git_issue( naddrs_iter @@ -141,14 +119,31 @@ impl CommandRunner for NewArgs { )? .dedup_tags() .pow(options.pow) - .tags(content_details.into_tags()) + .tags(content_details.clone().into_tags()) // p-tag the reset of the reposotoies owners .tags(naddrs_iter.clone().map(|n| Tag::public_key(n.public_key))) // a-tag the reset of the reposotoies - .tags(naddrs_iter.map(|n| Tag::coordinate(n.coordinate, n.relays.first().cloned()))) + .tags(naddrs_iter.clone().map(|n| Tag::coordinate(n.coordinate, n.relays.first().cloned()))) .build(user_pubk); let event_id = event.id.expect("There is an id"); + let write_relays = [ + options.relays, + utils::add_write_relays(relays_list.as_ref()), + client + .fetch_repos(&naddrs.into_coordinates()) + .await? + .extract_relays(), + // Include read relays for each repository owner (if found) + future::join_all(naddrs_iter.map(|c| client.read_relays_from_user(c.public_key))) + .await + .into_iter() + .flatten() + .collect(), + content_details.write_relays.clone().into_iter().collect(), + ] + .concat(); + tracing::trace!(relays = ?write_relays, "Write relays list"); let success = client .send_event_to(event, relays_list.as_ref(), &write_relays) diff --git a/src/cli/commands/reply.rs b/src/cli/commands/reply.rs index 3c2f38b..3c32eba 100644 --- a/src/cli/commands/reply.rs +++ b/src/cli/commands/reply.rs @@ -135,13 +135,6 @@ impl CommandRunner for ReplyArgs { client.add_relays(&self.to.relays).await; - let relays_list = client.user_relays_list(user_pubk).await?; - let mut write_relays = [ - options.relays, - utils::add_write_relays(relays_list.as_ref()), - ] - .concat(); - let reply_to = client .fetch_event(Filter::new().id(self.to.event_id)) .await? @@ -157,24 +150,6 @@ impl CommandRunner for ReplyArgs { }; let repos = client.fetch_repos(&repos_coordinate).await?; - // Merge repository announcement relays into write relays - write_relays.extend(repos.extract_relays()); - // Include read relays for each repository owner (if found) - write_relays.extend( - future::join_all( - repos_coordinate - .iter() - .map(|c| client.read_relays_from_user(c.public_key)), - ) - .await - .into_iter() - .flatten(), - ); - - write_relays.extend(client.read_relays_from_user(reply_to.pubkey).await); - if let Some(root_event) = &root { - write_relays.extend(client.read_relays_from_user(root_event.pubkey).await); - } let quoted_content = if self.quote_to { Some(quote_reply_to_content(&client, &reply_to).await) @@ -184,7 +159,6 @@ impl CommandRunner for ReplyArgs { let content = utils::get_content(self.comment.as_ref(), quoted_content.as_ref(), ".txt")?; let content_details = client.parse_content(&content).await; - write_relays.extend(content_details.write_relays.clone()); let event = EventBuilder::comment( content, @@ -194,11 +168,40 @@ impl CommandRunner for ReplyArgs { ) .dedup_tags() .pow(options.pow) - .tags(content_details.into_tags()) + .tags(content_details.clone().into_tags()) .build(user_pubk); let event_id = event.id.expect("There is an id"); - let author_read_relays = utils::add_read_relays(relays_list.as_ref()); + let relays_list = client.user_relays_list(user_pubk).await?; + let author_read_relays = + utils::add_read_relays(client.user_relays_list(user_pubk).await?.as_ref()); + let write_relays = [ + options.relays, + utils::add_write_relays(relays_list.as_ref()), + // Merge repository announcement relays into write relays + repos.extract_relays(), + // Include read relays for each repository owner (if found) + future::join_all( + repos_coordinate + .iter() + .map(|c| client.read_relays_from_user(c.public_key)), + ) + .await + .into_iter() + .flatten() + .collect(), + // read relays of the root event and the reply to event + { + let (r1, r2) = future::join( + client.read_relays_from_user(reply_to.pubkey), + event_author_read_relays(&client, root.as_ref()), + ) + .await; + [r1, r2].concat() + }, + content_details.write_relays.into_iter().collect(), + ] + .concat(); tracing::trace!(relays = ?write_relays, "Write relays list"); let (success, ..) = futures::join!( @@ -278,3 +281,12 @@ fn coordinates_from_root(root: &Event) -> N34Result> { Ok(coordinates) } + +/// Returns the event author read relays if found, otherwise an empty vector +async fn event_author_read_relays(client: &NostrClient, event: Option<&Event>) -> Vec { + if let Some(root_event) = event { + client.read_relays_from_user(root_event.pubkey).await + } else { + Vec::new() + } +} diff --git a/src/cli/commands/repo/announce.rs b/src/cli/commands/repo/announce.rs index 152e6cd..73c91fe 100644 --- a/src/cli/commands/repo/announce.rs +++ b/src/cli/commands/repo/announce.rs @@ -84,28 +84,11 @@ impl CommandRunner for AnnounceArgs { let client = NostrClient::init(&options).await; let user_pubk = options.pubkey().await?; let relays_list = client.user_relays_list(user_pubk).await?; - let mut write_relays = [ - options.relays.clone(), - utils::add_write_relays(relays_list.as_ref()), - ] - .concat(); if !self.maintainers.contains(&user_pubk) { self.maintainers.insert(0, user_pubk); } - // Include read relays for each maintainer (if found) - write_relays.extend( - future::join_all( - self.maintainers - .iter() - .map(|pkey| client.read_relays_from_user(*pkey)), - ) - .await - .into_iter() - .flatten(), - ); - let naddr = utils::repo_naddr(&self.repo_id, user_pubk, &options.relays)?; let event = EventBuilder::new_git_repo( self.repo_id, @@ -114,7 +97,7 @@ impl CommandRunner for AnnounceArgs { self.web, self.clone, options.relays.clone(), - self.maintainers, + self.maintainers.clone(), self.label.into_iter().map(utils::str_trim).collect(), self.force_id, )? @@ -122,7 +105,6 @@ impl CommandRunner for AnnounceArgs { .pow(options.pow) .build(user_pubk); - let nevent = utils::new_nevent(event.id.expect("There is an id"), &write_relays)?; if self.address_file { let address_path = std::env::current_dir()?.join(NOSTR_ADDRESS_FILE); @@ -142,6 +124,23 @@ impl CommandRunner for AnnounceArgs { tracing::info!("Successfully wrote naddr to address file"); } + let write_relays = [ + options.relays.clone(), + utils::add_write_relays(relays_list.as_ref()), + // Include read relays for each maintainer (if found) + future::join_all( + self.maintainers + .iter() + .map(|pkey| client.read_relays_from_user(*pkey)), + ) + .await + .into_iter() + .flatten() + .collect(), + ] + .concat(); + let nevent = utils::new_nevent(event.id.expect("There is an id"), &write_relays)?; + client .send_event_to(event, relays_list.as_ref(), &write_relays) .await?; diff --git a/src/nostr_utils/mod.rs b/src/nostr_utils/mod.rs index 134f6cd..e0592cb 100644 --- a/src/nostr_utils/mod.rs +++ b/src/nostr_utils/mod.rs @@ -42,6 +42,7 @@ use crate::{ const CLIENT_TIMEOUT: Duration = Duration::from_millis(1500); /// Parsed content details +#[derive(Clone)] pub struct ContentDetails { /// Public keys of users mentioned in the content. pub p_tagged: HashSet,