feat: enable state filtering
This commit is contained in:
		
					parent
					
						
							
								960a5210c6
							
						
					
				
			
			
				commit
				
					
						79c3174f4f
					
				
			
		
					 3 changed files with 56 additions and 23 deletions
				
			
		| 
						 | 
					@ -36,10 +36,12 @@ Dots can be repeated to move to parent tasks
 | 
				
			||||||
- `:[IND][COL]` - add / remove property column COL to IND or end
 | 
					- `:[IND][COL]` - add / remove property column COL to IND or end
 | 
				
			||||||
- `>[TEXT]` - Complete active task and move to parent, with optional state description
 | 
					- `>[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]` - Close active task and move to parent, with optional state description
 | 
				
			||||||
- `-TEXT` - add text note (comment / description)
 | 
					 | 
				
			||||||
- `#TAG` - filter by tag
 | 
					- `#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.
 | 
					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
 | 
					### Available Columns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										30
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										30
									
								
								src/main.rs
									
										
									
									
									
								
							| 
						 | 
					@ -139,6 +139,12 @@ async fn main() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    println!();
 | 
					    println!();
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
 | 
					        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() {
 | 
					                while let Ok(notification) = notifications.try_recv() {
 | 
				
			||||||
                    if let RelayPoolNotification::Event {
 | 
					                    if let RelayPoolNotification::Event {
 | 
				
			||||||
                        subscription_id,
 | 
					                        subscription_id,
 | 
				
			||||||
| 
						 | 
					@ -150,12 +156,7 @@ async fn main() {
 | 
				
			||||||
                        tasks.add(*event);
 | 
					                        tasks.add(*event);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
        tasks.print_current_tasks();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print!(" {}) ", tasks.taskpath(tasks.get_position()));
 | 
					 | 
				
			||||||
        stdout().flush().unwrap();
 | 
					 | 
				
			||||||
        match stdin().lines().next() {
 | 
					 | 
				
			||||||
            Some(Ok(input)) => {
 | 
					 | 
				
			||||||
                let mut iter = input.chars();
 | 
					                let mut iter = input.chars();
 | 
				
			||||||
                let op = iter.next();
 | 
					                let op = iter.next();
 | 
				
			||||||
                match op {
 | 
					                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('-') => tasks.add_note(&input[1..]),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    Some('>') | Some('<') => {
 | 
					                    Some('>') | Some('<') => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/task.rs
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								src/task.rs
									
										
									
									
									
								
							| 
						 | 
					@ -42,14 +42,7 @@ impl Task {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn states(&self) -> impl Iterator<Item = TaskState> + '_ {
 | 
					    fn states(&self) -> impl Iterator<Item = TaskState> + '_ {
 | 
				
			||||||
        self.props.iter().filter_map(|event| {
 | 
					        self.props.iter().filter_map(|event| {
 | 
				
			||||||
            match event.kind.as_u32() {
 | 
					            event.kind.try_into().ok().map(|s| TaskState {
 | 
				
			||||||
                1630 => Some(State::Open),
 | 
					 | 
				
			||||||
                1631 => Some(State::Done),
 | 
					 | 
				
			||||||
                1632 => Some(State::Closed),
 | 
					 | 
				
			||||||
                1633 => Some(State::Active),
 | 
					 | 
				
			||||||
                _ => None,
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            .map(|s| TaskState {
 | 
					 | 
				
			||||||
                name: if event.content.is_empty() {
 | 
					                name: if event.content.is_empty() {
 | 
				
			||||||
                    None
 | 
					                    None
 | 
				
			||||||
                } else {
 | 
					                } 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)
 | 
					        self.states().max_by_key(|t| t.time)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -130,11 +123,16 @@ impl Task {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct TaskState {
 | 
					pub(crate) struct TaskState {
 | 
				
			||||||
    name: Option<String>,
 | 
					    name: Option<String>,
 | 
				
			||||||
    state: State,
 | 
					    state: State,
 | 
				
			||||||
    time: Timestamp,
 | 
					    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 {
 | 
					impl fmt::Display for TaskState {
 | 
				
			||||||
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
					    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
				
			||||||
        write!(
 | 
					        write!(
 | 
				
			||||||
| 
						 | 
					@ -155,6 +153,19 @@ pub(crate) enum State {
 | 
				
			||||||
    Active,
 | 
					    Active,
 | 
				
			||||||
    Done,
 | 
					    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 {
 | 
					impl State {
 | 
				
			||||||
    pub(crate) fn kind(&self) -> Kind {
 | 
					    pub(crate) fn kind(&self) -> Kind {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue