diff --git a/src/main.rs b/src/main.rs index 15a4066..be7134d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -177,6 +177,10 @@ async fn main() { } } Err(_) => { + if input.chars().nth(1) == Some(':') { + tasks.recursive = !tasks.recursive; + continue + } let prop = &input[1..]; let pos = tasks.properties.iter().position(|s| s == &prop); match pos { @@ -211,6 +215,8 @@ async fn main() { let slice = &input[dots..]; if !slice.is_empty() { pos = EventId::parse(slice).ok().or_else(|| { + // TODO check what is more intuitive: + // currently resets filters before filtering again, maybe keep them tasks.move_to(pos); let filtered: Vec = tasks .current_tasks() diff --git a/src/tasks.rs b/src/tasks.rs index ecf349d..5dada47 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::iter::once; use nostr_sdk::{Event, EventBuilder, EventId, Kind, Tag}; @@ -8,13 +9,17 @@ use crate::task::{State, Task}; type TaskMap = HashMap; pub(crate) struct Tasks { /// The Tasks - pub(crate) tasks: TaskMap, + tasks: TaskMap, /// The task properties currently visible pub(crate) properties: Vec, + // TODO: plain, recursive, only leafs + pub(crate) recursive: bool, + /// The task currently selected. position: Option, /// A filtered view of the current tasks view: Vec, + sender: EventSender } @@ -25,6 +30,7 @@ impl Tasks { properties: vec!["id".into(), "name".into(), "state".into(), "ttime".into()], position: None, view: Default::default(), + recursive: false, sender } } @@ -50,18 +56,30 @@ impl Tasks { self.view = view } + fn resolve_tasks<'a>(&self, iter: impl IntoIterator) -> Vec<&Task> { + iter.into_iter().filter_map(|id| self.tasks.get(&id)).flat_map(|task| { + if self.recursive { + self.resolve_tasks(task.children.iter()).into_iter().chain(once(task)).collect() + } else { + vec![task] + } + }).collect() + } + pub(crate) fn current_tasks(&self) -> Vec<&Task> { - let res: Vec<&Task> = self.view.iter().filter_map(|id| self.tasks.get(id)).collect(); + let res: Vec<&Task> = self.resolve_tasks(self.view.iter()); if res.len() > 0 { return res; } self.position.map_or_else( - || self.tasks.values().collect(), - |p| { - self.tasks - .get(&p) - .map_or(Vec::new(), |t| t.children.iter().filter_map(|id| self.tasks.get(id)).collect()) + || { + if self.recursive { + self.tasks.values().collect() + } else { + self.tasks.values().filter(|t| t.parent_id() == None).collect() + } }, + |p| self.tasks.get(&p).map_or(Vec::new(), |t| self.resolve_tasks(t.children.iter())), ) }