diff --git a/crates/signed_core/src/model.rs b/crates/signed_core/src/model.rs index fbb7261..60ada21 100644 --- a/crates/signed_core/src/model.rs +++ b/crates/signed_core/src/model.rs @@ -4,18 +4,18 @@ use nostr::prelude::*; /// Parsed NIP-34 repository announcement (plain data, ready for the UI). #[derive(Debug, Clone, PartialEq, Eq)] pub struct Announcement { + /// Repository ID (`d` tag). + pub id: String, /// Author of the announcement event. pub owner: PublicKey, /// When the announcement was published (for latest-wins resolution). pub created_at: Timestamp, - /// Repository ID (`d` tag). - pub id: String, pub name: Option, pub description: Option, /// Webpage URLs for browsing. - pub web: Vec, + pub web: Vec, /// URLs for `git clone`. - pub clone: Vec, + pub clone: Vec, /// Relays the repository monitors for patches and issues. pub relays: Vec, /// Earliest unique commit ID (`r` tag with `euc` marker). @@ -33,36 +33,25 @@ impl Announcement { return None; } - let mut id: Option = None; + let id = event.tags.identifier()?; + + let mut hashtags: Vec = Vec::new(); + hashtags.extend(event.tags.hashtags().map(|t| t.to_string())); + let mut name: Option = None; let mut description: Option = None; - let mut web: Vec = Vec::new(); - let mut clone: Vec = Vec::new(); + let mut web: Vec = Vec::new(); + let mut clone: Vec = Vec::new(); let mut relays: Vec = Vec::new(); let mut euc: Option = None; let mut maintainers: Vec = Vec::new(); - let mut hashtags: Vec = Vec::new(); for tag in event.tags.iter() { - // The `d` and `t` tags aren't part of the NIP-34 tag codec; parse them directly. - if tag.kind() == "d" { - id = tag.content().map(str::to_owned); - continue; - } - if tag.kind() == "t" { - if let Some(value) = tag.content() { - hashtags.push(value.to_owned()); - } - continue; - } - match Nip34Tag::parse(tag.as_slice()) { Ok(Nip34Tag::Name(value)) => name = Some(value.into()), Ok(Nip34Tag::Description(value)) => description = Some(value.into()), - Ok(Nip34Tag::Web(urls)) => web.extend(urls.into_iter().map(|url| url.to_string())), - Ok(Nip34Tag::Clone(urls)) => { - clone.extend(urls.into_iter().map(|url| url.to_string())) - } + Ok(Nip34Tag::Web(urls)) => web.extend(urls), + Ok(Nip34Tag::Clone(urls)) => clone.extend(urls), Ok(Nip34Tag::Relays(urls)) => relays.extend(urls), Ok(Nip34Tag::EarliestUniqueCommitId(commit)) => euc = Some(commit.to_string()), Ok(Nip34Tag::Maintainers(keys)) => maintainers.extend(keys), @@ -73,7 +62,7 @@ impl Announcement { Some(Self { owner: event.pubkey, created_at: event.created_at, - id: id?, + id, name, description, web, @@ -141,8 +130,14 @@ mod tests { announcement.description.as_deref(), Some("A test repository") ); - assert_eq!(announcement.web, vec!["https://example.com/repo"]); - assert_eq!(announcement.clone, vec!["https://example.com/repo.git"]); + assert_eq!( + announcement.web, + vec![Url::parse("https://example.com/repo").unwrap()] + ); + assert_eq!( + announcement.clone, + vec![Url::parse("https://example.com/repo.git").unwrap()] + ); assert_eq!( announcement.relays, vec![RelayUrl::parse("wss://relay.example.com").unwrap()] diff --git a/crates/workspace/src/views/repo_list.rs b/crates/workspace/src/views/repo_list.rs index 94775de..f6432fd 100644 --- a/crates/workspace/src/views/repo_list.rs +++ b/crates/workspace/src/views/repo_list.rs @@ -60,7 +60,10 @@ impl RepoListView { .clone() .unwrap_or_else(|| SharedString::from(announcement.id.clone())); - let description = announcement.description.clone().unwrap_or_default(); + let description = announcement + .description + .clone() + .unwrap_or(SharedString::from("No description")); let activity = last_activity .map(relative_time) @@ -103,8 +106,7 @@ impl RepoListView { Avatar::new() .name(owner.name()) .when_some(owner.picture(), |this, url| this.src(url)) - .small() - .border_0(), + .small(), ) .child( div()