forked from janek/mostr
feat: implement priority property for task
This commit is contained in:
parent
5294d9081f
commit
91b6047f9a
21
src/task.rs
21
src/task.rs
|
@ -1,8 +1,9 @@
|
||||||
use fmt::Display;
|
use fmt::Display;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::{BTreeSet, HashSet};
|
use std::collections::BTreeSet;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::iter::once;
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
|
|
||||||
use colored::{ColoredString, Colorize};
|
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 nostr_sdk::{Event, EventId, Kind, Tag, TagStandard, Timestamp};
|
||||||
|
|
||||||
use crate::helpers::{format_timestamp_local, some_non_empty};
|
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_PARENT: &str = "parent";
|
||||||
pub static MARKER_DEPENDS: &str = "depends";
|
pub static MARKER_DEPENDS: &str = "depends";
|
||||||
|
@ -102,12 +103,25 @@ impl Task {
|
||||||
self.event.kind == TASK_KIND
|
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 {
|
pub(crate) fn is_task(&self) -> bool {
|
||||||
self.is_task_kind() ||
|
self.is_task_kind() ||
|
||||||
self.props.iter().any(|event| State::try_from(event.kind).is_ok())
|
self.props.iter().any(|event| State::try_from(event.kind).is_ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn priority(&self) -> Option<Prio> {
|
||||||
|
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<Item=TaskState> + '_ {
|
fn states(&self) -> impl DoubleEndedIterator<Item=TaskState> + '_ {
|
||||||
self.props.iter().filter_map(|event| {
|
self.props.iter().filter_map(|event| {
|
||||||
event.kind.try_into().ok().map(|s| TaskState {
|
event.kind.try_into().ok().map(|s| TaskState {
|
||||||
|
@ -180,6 +194,7 @@ impl Task {
|
||||||
"created" => Some(format_timestamp_local(&self.event.created_at)),
|
"created" => Some(format_timestamp_local(&self.event.created_at)),
|
||||||
"kind" => Some(self.event.kind.to_string()),
|
"kind" => Some(self.event.kind.to_string()),
|
||||||
// Dynamic
|
// Dynamic
|
||||||
|
"priority" | "prio" => self.priority_raw().map(|c| c.to_string()),
|
||||||
"status" => self.state_label().map(|c| c.to_string()),
|
"status" => self.state_label().map(|c| c.to_string()),
|
||||||
"desc" => self.descriptions().last().cloned(),
|
"desc" => self.descriptions().last().cloned(),
|
||||||
"description" => Some(self.descriptions().join(" ")),
|
"description" => Some(self.descriptions().join(" ")),
|
||||||
|
|
|
@ -155,6 +155,7 @@ impl TasksRelay {
|
||||||
|
|
||||||
properties: [
|
properties: [
|
||||||
"author",
|
"author",
|
||||||
|
"prio",
|
||||||
"state",
|
"state",
|
||||||
"rtime",
|
"rtime",
|
||||||
"hashtags",
|
"hashtags",
|
||||||
|
@ -162,7 +163,8 @@ impl TasksRelay {
|
||||||
"desc",
|
"desc",
|
||||||
].into_iter().map(|s| s.to_string()).collect(),
|
].into_iter().map(|s| s.to_string()).collect(),
|
||||||
sorting: [
|
sorting: [
|
||||||
"state",
|
"priority",
|
||||||
|
"status",
|
||||||
"author",
|
"author",
|
||||||
"hashtags",
|
"hashtags",
|
||||||
"rtime",
|
"rtime",
|
||||||
|
@ -537,7 +539,7 @@ impl TasksRelay {
|
||||||
}
|
}
|
||||||
"progress" => prog_string.clone(),
|
"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)),
|
"path" => self.get_task_path(Some(task.event.id)),
|
||||||
"rpath" => self.relative_path(task.event.id),
|
"rpath" => self.relative_path(task.event.id),
|
||||||
// TODO format strings configurable
|
// TODO format strings configurable
|
||||||
|
@ -874,7 +876,7 @@ impl TasksRelay {
|
||||||
pub(crate) fn make_task_with(&mut self, input: &str, tags: impl IntoIterator<Item=Tag>, set_state: bool) -> EventId {
|
pub(crate) fn make_task_with(&mut self, input: &str, tags: impl IntoIterator<Item=Tag>, set_state: bool) -> EventId {
|
||||||
let (input, input_tags) = extract_tags(input.trim());
|
let (input, input_tags) = extract_tags(input.trim());
|
||||||
let prio =
|
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(
|
let id = self.submit(
|
||||||
build_task(&input, input_tags, None)
|
build_task(&input, input_tags, None)
|
||||||
.add_tags(self.tags.iter().cloned())
|
.add_tags(self.tags.iter().cloned())
|
||||||
|
|
Loading…
Reference in New Issue