feat: enable state filtering
This commit is contained in:
parent
960a5210c6
commit
79c3174f4f
|
@ -36,10 +36,12 @@ Dots can be repeated to move to parent tasks
|
|||
- `:[IND][COL]` - add / remove property column COL to IND or end
|
||||
- `>[TEXT]` - Complete active task and move to parent, with optional state description
|
||||
- `<[TEXT]` - Close active task and move to parent, with optional state description
|
||||
- `-TEXT` - add text note (comment / description)
|
||||
- `#TAG` - filter by tag
|
||||
- `?TAG` - filter by state (type or description)
|
||||
- `-TEXT` - add text note (comment / description)
|
||||
|
||||
State descriptions can be used for example for Kanban columns.
|
||||
An active tag or state filter will also create new tasks with those corresponding attributes.
|
||||
|
||||
### Available Columns
|
||||
|
||||
|
|
44
src/main.rs
44
src/main.rs
|
@ -139,23 +139,24 @@ async fn main() {
|
|||
|
||||
println!();
|
||||
loop {
|
||||
while let Ok(notification) = notifications.try_recv() {
|
||||
if let RelayPoolNotification::Event {
|
||||
subscription_id,
|
||||
event,
|
||||
..
|
||||
} = notification
|
||||
{
|
||||
print_event(&event);
|
||||
tasks.add(*event);
|
||||
}
|
||||
}
|
||||
tasks.print_current_tasks();
|
||||
|
||||
print!(" {}) ", tasks.taskpath(tasks.get_position()));
|
||||
stdout().flush().unwrap();
|
||||
match stdin().lines().next() {
|
||||
Some(Ok(input)) => {
|
||||
while let Ok(notification) = notifications.try_recv() {
|
||||
if let RelayPoolNotification::Event {
|
||||
subscription_id,
|
||||
event,
|
||||
..
|
||||
} = notification
|
||||
{
|
||||
print_event(&event);
|
||||
tasks.add(*event);
|
||||
}
|
||||
}
|
||||
|
||||
let mut iter = input.chars();
|
||||
let op = iter.next();
|
||||
match op {
|
||||
|
@ -188,6 +189,25 @@ async fn main() {
|
|||
}
|
||||
},
|
||||
|
||||
Some('?') => {
|
||||
let arg = &input[1..];
|
||||
tasks.move_to(tasks.get_position());
|
||||
tasks.set_filter(
|
||||
tasks
|
||||
.current_tasks()
|
||||
.into_iter()
|
||||
.filter(|t| {
|
||||
if arg.is_empty() {
|
||||
t.pure_state() == State::Open
|
||||
} else {
|
||||
t.state().is_some_and(|s| s.get_label() == arg)
|
||||
}
|
||||
})
|
||||
.map(|t| t.event.id)
|
||||
.collect(),
|
||||
);
|
||||
}
|
||||
|
||||
Some('-') => tasks.add_note(&input[1..]),
|
||||
|
||||
Some('>') | Some('<') => {
|
||||
|
@ -200,7 +220,7 @@ async fn main() {
|
|||
});
|
||||
tasks.move_up()
|
||||
}
|
||||
|
||||
|
||||
Some('#') => {
|
||||
tasks.add_tag(input[1..].to_string());
|
||||
}
|
||||
|
|
31
src/task.rs
31
src/task.rs
|
@ -42,14 +42,7 @@ impl Task {
|
|||
|
||||
fn states(&self) -> impl Iterator<Item = TaskState> + '_ {
|
||||
self.props.iter().filter_map(|event| {
|
||||
match event.kind.as_u32() {
|
||||
1630 => Some(State::Open),
|
||||
1631 => Some(State::Done),
|
||||
1632 => Some(State::Closed),
|
||||
1633 => Some(State::Active),
|
||||
_ => None,
|
||||
}
|
||||
.map(|s| TaskState {
|
||||
event.kind.try_into().ok().map(|s| TaskState {
|
||||
name: if event.content.is_empty() {
|
||||
None
|
||||
} else {
|
||||
|
@ -61,7 +54,7 @@ impl Task {
|
|||
})
|
||||
}
|
||||
|
||||
fn state(&self) -> Option<TaskState> {
|
||||
pub(crate) fn state(&self) -> Option<TaskState> {
|
||||
self.states().max_by_key(|t| t.time)
|
||||
}
|
||||
|
||||
|
@ -130,11 +123,16 @@ impl Task {
|
|||
}
|
||||
}
|
||||
|
||||
struct TaskState {
|
||||
pub(crate) struct TaskState {
|
||||
name: Option<String>,
|
||||
state: State,
|
||||
time: Timestamp,
|
||||
}
|
||||
impl TaskState {
|
||||
pub(crate) fn get_label(&self) -> String {
|
||||
self.name.clone().unwrap_or_else(|| self.state.to_string())
|
||||
}
|
||||
}
|
||||
impl fmt::Display for TaskState {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
|
@ -155,6 +153,19 @@ pub(crate) enum State {
|
|||
Active,
|
||||
Done,
|
||||
}
|
||||
impl TryFrom<Kind> for State {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: Kind) -> Result<Self, Self::Error> {
|
||||
match value.as_u32() {
|
||||
1630 => Ok(State::Open),
|
||||
1631 => Ok(State::Done),
|
||||
1632 => Ok(State::Closed),
|
||||
1633 => Ok(State::Active),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl State {
|
||||
pub(crate) fn kind(&self) -> Kind {
|
||||
match self {
|
||||
|
|
Loading…
Reference in New Issue