diff --git a/src/task.rs b/src/task.rs index a2fd1b4..666e4f3 100644 --- a/src/task.rs +++ b/src/task.rs @@ -110,10 +110,7 @@ impl Task { "name" => Some(self.event.content.clone()), "desc" => self.descriptions().last().cloned(), "description" => Some(self.descriptions().join(" ")), - "hashtags" => self.filter_tags(|tag| { - tag.single_letter_tag() - .is_some_and(|sltag| sltag.character == Alphabet::T) - }), + "hashtags" => self.filter_tags(|tag| { is_hashtag(tag) }), "tags" => self.filter_tags(|_| true), "alltags" => Some(format!("{:?}", self.tags)), "props" => Some(format!( @@ -135,6 +132,11 @@ impl Task { } } +pub(crate) fn is_hashtag(tag: &Tag) -> bool { + tag.single_letter_tag() + .is_some_and(|sltag| sltag.character == Alphabet::T) +} + pub(crate) struct TaskState { state: State, name: Option, diff --git a/src/tasks.rs b/src/tasks.rs index c609662..6921326 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -8,11 +8,11 @@ use chrono::LocalResult::Single; use colored::Colorize; use itertools::Itertools; use log::{debug, error, info, trace, warn}; -use nostr_sdk::{Event, EventBuilder, EventId, Kind, PublicKey, Tag, Timestamp}; +use nostr_sdk::{Event, EventBuilder, EventId, GenericTagValue, Kind, PublicKey, Tag, Timestamp}; use nostr_sdk::Tag::Hashtag; use crate::{EventSender, TASK_KIND, TRACKING_KIND}; -use crate::task::{State, Task}; +use crate::task::{is_hashtag, State, Task}; type TaskMap = HashMap; #[derive(Debug, Clone)] @@ -464,11 +464,11 @@ impl Tasks { // Updates /// Expects sanitized input - pub(crate) fn build_task(&self, input: &str) -> EventBuilder { + pub(crate) fn parse_task(&self, input: &str) -> EventBuilder { let mut tags: Vec = self.tags.iter().cloned().collect(); self.position.inspect(|p| tags.push(Tag::event(*p))); - return match input.split_once(": ") { - None => EventBuilder::new(Kind::from(TASK_KIND), input, tags), + match input.split_once(": ") { + None => build_task(input, tags), Some(s) => { tags.append( &mut s @@ -477,14 +477,14 @@ impl Tasks { .map(|t| Hashtag(t.to_string())) .collect(), ); - EventBuilder::new(Kind::from(TASK_KIND), s.0, tags) + build_task(s.0, tags) } - }; + } } /// Sanitizes input pub(crate) fn make_task(&mut self, input: &str) -> EventId { - self.submit(self.build_task(input.trim())) + self.submit(self.parse_task(input.trim())) } pub(crate) fn build_prop( @@ -562,8 +562,7 @@ impl Tasks { self.submit(prop) } - pub(crate) fn update_state(&mut self, comment: &str, state: State) - { + pub(crate) fn update_state(&mut self, comment: &str, state: State) { self.position .map(|id| self.set_state_for(id, comment, state)); } @@ -594,6 +593,27 @@ fn display_time(format: &str, secs: u64) -> String { ) } +fn build_task(name: &str, tags: Vec) -> EventBuilder { + info!("Created task \"{name}\" with tags [{}]", tags.iter().map(|tag| format_tag(tag)).join(", ")); + EventBuilder::new(Kind::from(TASK_KIND), name, tags) +} + +fn format_tag(tag: &Tag) -> String { + tag.content().map(|c| { + match c { + GenericTagValue::PublicKey(key) => format!("Key: {}", key.to_string()[..8].to_string()), + GenericTagValue::EventId(id) => format!("Parent: {}", id.to_string()[..8].to_string()), + GenericTagValue::String(str) => { + if is_hashtag(tag) { + format!("#{str}") + } else { + str + } + } + } + }).unwrap_or_else(|| format!("Kind {}", tag.kind())) +} + pub(crate) fn join_tasks<'a>( iter: impl Iterator, include_last_id: bool,