From 86654c83485e80404075d2e09b794479f01e21d5 Mon Sep 17 00:00:00 2001 From: xeruf <27jf@pm.me> Date: Sun, 18 Aug 2024 21:33:04 +0300 Subject: [PATCH] feat: show named task authors --- src/kinds.rs | 10 +++++++++- src/main.rs | 29 ++++++++++++++++------------- src/tasks.rs | 28 +++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/kinds.rs b/src/kinds.rs index cd03dd0..2e88359 100644 --- a/src/kinds.rs +++ b/src/kinds.rs @@ -2,10 +2,18 @@ use itertools::Itertools; use log::info; use nostr_sdk::{Alphabet, EventBuilder, EventId, Kind, Tag, TagStandard}; +pub const METADATA_KIND: u16 = 0; +pub const NOTE_KIND: u16 = 1; pub const TASK_KIND: u16 = 1621; pub const PROCEDURE_KIND: u16 = 1639; pub const TRACKING_KIND: u16 = 1650; -pub const KINDS: [u16; 8] = [1, TASK_KIND, TRACKING_KIND, PROCEDURE_KIND, 1630, 1631, 1632, 1633]; +pub const KINDS: [u16; 9] = [ + METADATA_KIND, + NOTE_KIND, + TASK_KIND, + TRACKING_KIND, + PROCEDURE_KIND, + 1630, 1631, 1632, 1633]; pub const PROPERTY_COLUMNS: &str = "Available properties: - `id` diff --git a/src/main.rs b/src/main.rs index 4fee491..0859c5a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -180,21 +180,11 @@ async fn main() { }, } - let sub_id = client.subscribe(vec![Filter::new().kinds(KINDS.into_iter().map(|k| Kind::from(k)))], None).await; + let sub_id = client.subscribe(vec![ + Filter::new().kinds(KINDS.into_iter().map(|k| Kind::from(k))) + ], None).await; info!("Subscribed with {:?}", sub_id); - // TODO user data from config file or home relay? - //let metadata = Metadata::new() - // .name("username") - // .display_name("My Username") - // .about("Description") - // .picture(Url::parse("https://example.com/avatar.png")?) - // .banner(Url::parse("https://example.com/banner.png")?) - // .nip05("username@example.com") - // .lud16("yuki@getalby.com") - // .custom_field("custom_field", "my value"); - //client.set_metadata(&metadata).await?; - let mut notifications = client.notifications(); client.connect().await; @@ -207,6 +197,19 @@ async fn main() { let mut queue: Option<(Url, Vec)> = None; loop { + if let Ok(user) = var("USER") { + let metadata = Metadata::new() + .name(user); + // .display_name("My Username") + // .about("Description") + // .picture(Url::parse("https://example.com/avatar.png")?) + // .banner(Url::parse("https://example.com/banner.png")?) + // .nip05("username@example.com") + // .lud16("yuki@getalby.com") + // .custom_field("custom_field", "my value"); + or_print(client.set_metadata(&metadata).await); + } + let result_received = rx.recv_timeout(Duration::from_secs(INACTVITY_DELAY)); match result_received { Ok(MostrMessage::NewRelay(url)) => { diff --git a/src/tasks.rs b/src/tasks.rs index 15afc9d..deb83d5 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -11,7 +11,7 @@ use chrono::Local; use colored::Colorize; use itertools::Itertools; use log::{debug, error, info, trace, warn}; -use nostr_sdk::{Event, EventBuilder, EventId, Keys, Kind, PublicKey, Tag, TagStandard, Timestamp, UncheckedUrl, Url}; +use nostr_sdk::{Event, EventBuilder, EventId, JsonUtil, Keys, Kind, Metadata, PublicKey, Tag, TagStandard, Timestamp, UncheckedUrl, Url}; use nostr_sdk::prelude::Marker; use TagStandard::Hashtag; @@ -27,6 +27,8 @@ pub(crate) struct Tasks { tasks: TaskMap, /// History of active tasks by PubKey history: HashMap>, + /// Index of found users with metadata + users: HashMap, /// The task properties currently visible properties: Vec, @@ -118,6 +120,7 @@ impl Tasks { Tasks { tasks: Default::default(), history: Default::default(), + users: Default::default(), properties: vec![ "state".into(), "rtime".into(), @@ -329,12 +332,19 @@ impl Tasks { .into() } - pub(crate) fn referenced_tasks(&mut self, event: &Event, f: F) { + /// Executes the given function with each task referenced by this event. + /// Returns true if any task was found. + pub(crate) fn referenced_tasks(&mut self, event: &Event, f: F) -> bool { + let mut found = false; for tag in event.tags.iter() { if let Some(TagStandard::Event { event_id, .. }) = tag.as_standardized() { - self.tasks.get_mut(event_id).map(|t| f(t)); + self.tasks.get_mut(event_id).map(|t| { + found = true; + f(t) + }); } } + found } #[inline] @@ -462,6 +472,7 @@ impl Tasks { state.get_colored_label() }.to_string() } + "author" => self.get_author(&task.event.pubkey), "progress" => prog_string.clone(), "path" => self.get_task_path(Some(task.event.id)), "rpath" => self.relative_path(task.event.id), @@ -472,6 +483,12 @@ impl Tasks { } } + pub(crate) fn get_author(&self, pubkey: &PublicKey) -> String { + self.users.get(pubkey) + .and_then(|m| m.name.clone()) + .unwrap_or_else(|| pubkey.to_string()) + } + // Movement and Selection pub(crate) fn set_filter(&mut self, view: Vec) { @@ -760,6 +777,11 @@ impl Tasks { Some(c) => { c.insert(event); } None => { self.history.insert(event.pubkey, BTreeSet::from([event])); } }, + METADATA_KIND => + match Metadata::from_json(event.content()) { + Ok(metadata) => { self.users.insert(event.pubkey, metadata); } + Err(e) => warn!("Cannot parse metadata: {} from {:?}", e, event) + } _ => self.add_prop(&event), } }