diff --git a/src/task.rs b/src/task.rs index 0319411..47fba0c 100644 --- a/src/task.rs +++ b/src/task.rs @@ -1,8 +1,9 @@ use fmt::Display; use std::cmp::Ordering; -use std::collections::{BTreeSet, HashSet}; +use std::collections::BTreeSet; use std::fmt; use std::hash::{Hash, Hasher}; +use std::iter::once; use std::string::ToString; use colored::{ColoredString, Colorize}; @@ -12,7 +13,7 @@ use log::{debug, error, info, trace, warn}; use nostr_sdk::{Event, EventId, Kind, Tag, TagStandard, Timestamp}; use crate::helpers::{format_timestamp_local, some_non_empty}; -use crate::kinds::{is_hashtag, PROCEDURE_KIND, PROCEDURE_KIND_ID, TASK_KIND}; +use crate::kinds::{is_hashtag, Prio, PRIO, PROCEDURE_KIND, PROCEDURE_KIND_ID, TASK_KIND}; pub static MARKER_PARENT: &str = "parent"; pub static MARKER_DEPENDS: &str = "depends"; @@ -102,12 +103,25 @@ impl Task { self.event.kind == TASK_KIND } - /// Whether this is an actionable task - false if stateless + /// Whether this is an actionable task - false if stateless activity pub(crate) fn is_task(&self) -> bool { self.is_task_kind() || self.props.iter().any(|event| State::try_from(event.kind).is_ok()) } + pub(crate) fn priority(&self) -> Option { + self.priority_raw().and_then(|s| s.parse().ok()) + } + + pub(crate) fn priority_raw(&self) -> Option<&str> { + self.props.iter().rev() + .chain(once(&self.event)) + .find_map(|p| { + p.tags.iter().find_map(|t| + t.content().take_if(|_| { t.kind().to_string() == PRIO })) + }) + } + fn states(&self) -> impl DoubleEndedIterator + '_ { self.props.iter().filter_map(|event| { event.kind.try_into().ok().map(|s| TaskState { @@ -180,6 +194,7 @@ impl Task { "created" => Some(format_timestamp_local(&self.event.created_at)), "kind" => Some(self.event.kind.to_string()), // Dynamic + "priority" | "prio" => self.priority_raw().map(|c| c.to_string()), "status" => self.state_label().map(|c| c.to_string()), "desc" => self.descriptions().last().cloned(), "description" => Some(self.descriptions().join(" ")), diff --git a/src/tasks.rs b/src/tasks.rs index d23ccdc..6fb6f3e 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -155,6 +155,7 @@ impl TasksRelay { properties: [ "author", + "prio", "state", "rtime", "hashtags", @@ -162,7 +163,8 @@ impl TasksRelay { "desc", ].into_iter().map(|s| s.to_string()).collect(), sorting: [ - "state", + "priority", + "status", "author", "hashtags", "rtime", @@ -537,7 +539,7 @@ impl TasksRelay { } "progress" => prog_string.clone(), - "author" => format!("{:.6}", self.get_username(&task.event.pubkey)), // FIXME temporary until proper column alignment + "author" | "creator" => format!("{:.6}", self.get_username(&task.event.pubkey)), // FIXME temporary until proper column alignment "path" => self.get_task_path(Some(task.event.id)), "rpath" => self.relative_path(task.event.id), // TODO format strings configurable @@ -874,7 +876,7 @@ impl TasksRelay { pub(crate) fn make_task_with(&mut self, input: &str, tags: impl IntoIterator, set_state: bool) -> EventId { let (input, input_tags) = extract_tags(input.trim()); let prio = - if input_tags.iter().find(|t| t.kind().to_string() == PRIO).is_some() { None } else { self.priority.map(|p| to_prio_tag(p)) }; + if input_tags.iter().any(|t| t.kind().to_string() == PRIO) { None } else { self.priority.map(|p| to_prio_tag(p)) }; let id = self.submit( build_task(&input, input_tags, None) .add_tags(self.tags.iter().cloned())