feat: toggle for recursive task view

This commit is contained in:
xeruf 2024-07-24 21:11:36 +03:00
parent ad65388979
commit 860c3080b2
2 changed files with 31 additions and 7 deletions

View File

@ -177,6 +177,10 @@ async fn main() {
} }
} }
Err(_) => { Err(_) => {
if input.chars().nth(1) == Some(':') {
tasks.recursive = !tasks.recursive;
continue
}
let prop = &input[1..]; let prop = &input[1..];
let pos = tasks.properties.iter().position(|s| s == &prop); let pos = tasks.properties.iter().position(|s| s == &prop);
match pos { match pos {
@ -211,6 +215,8 @@ async fn main() {
let slice = &input[dots..]; let slice = &input[dots..];
if !slice.is_empty() { if !slice.is_empty() {
pos = EventId::parse(slice).ok().or_else(|| { 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); tasks.move_to(pos);
let filtered: Vec<EventId> = tasks let filtered: Vec<EventId> = tasks
.current_tasks() .current_tasks()

View File

@ -1,4 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::iter::once;
use nostr_sdk::{Event, EventBuilder, EventId, Kind, Tag}; use nostr_sdk::{Event, EventBuilder, EventId, Kind, Tag};
@ -8,13 +9,17 @@ use crate::task::{State, Task};
type TaskMap = HashMap<EventId, Task>; type TaskMap = HashMap<EventId, Task>;
pub(crate) struct Tasks { pub(crate) struct Tasks {
/// The Tasks /// The Tasks
pub(crate) tasks: TaskMap, tasks: TaskMap,
/// The task properties currently visible /// The task properties currently visible
pub(crate) properties: Vec<String>, pub(crate) properties: Vec<String>,
// TODO: plain, recursive, only leafs
pub(crate) recursive: bool,
/// The task currently selected. /// The task currently selected.
position: Option<EventId>, position: Option<EventId>,
/// A filtered view of the current tasks /// A filtered view of the current tasks
view: Vec<EventId>, view: Vec<EventId>,
sender: EventSender sender: EventSender
} }
@ -25,6 +30,7 @@ impl Tasks {
properties: vec!["id".into(), "name".into(), "state".into(), "ttime".into()], properties: vec!["id".into(), "name".into(), "state".into(), "ttime".into()],
position: None, position: None,
view: Default::default(), view: Default::default(),
recursive: false,
sender sender
} }
} }
@ -50,18 +56,30 @@ impl Tasks {
self.view = view self.view = view
} }
fn resolve_tasks<'a>(&self, iter: impl IntoIterator<Item=&'a EventId>) -> 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> { 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 { if res.len() > 0 {
return res; return res;
} }
self.position.map_or_else( self.position.map_or_else(
|| self.tasks.values().collect(), || {
|p| { if self.recursive {
self.tasks self.tasks.values().collect()
.get(&p) } else {
.map_or(Vec::new(), |t| t.children.iter().filter_map(|id| self.tasks.get(id)).collect()) 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())),
) )
} }