docs: expand Readme and adjust code comments
This commit is contained in:
parent
8588fb9a04
commit
1e0cc319b8
82
README.md
82
README.md
|
@ -99,7 +99,7 @@ To stop time-tracking completely, simply move to the root of all tasks.
|
|||
+ match by task name prefix: if one or more tasks match, filter / activate (tries case-sensitive then case-insensitive)
|
||||
+ no match: create & activate task
|
||||
- `.2` - set view depth to `2`, which can be substituted for any number (how many subtask levels to show, default 1)
|
||||
- `/[TEXT]` - like `.`, but never creates a task
|
||||
- `/[TEXT]` - like `.`, but never creates a task and filters beyond currently visible tasks
|
||||
- `||TASK` - create and activate a new task procedure (where subtasks automatically depend on the previously created task)
|
||||
- `|[TASK]` - (un)mark current task as procedure or create a sibling task depending on the current one and move up
|
||||
|
||||
|
@ -109,12 +109,13 @@ Dots and slashes can be repeated to move to parent tasks.
|
|||
- `::[PROP]` - Sort by property PROP (multiple space-separated values allowed)
|
||||
- `([TIME]` - insert timetracking with the specified offset in minutes (empty: list tracked times)
|
||||
- `)[TIME]` - stop timetracking with the specified offset in minutes - convenience helper to move to root (empty: stop now)
|
||||
- `>[TEXT]` - complete active task and move up, with optional state description
|
||||
- `<[TEXT]` - close active task and move up, with optional state description
|
||||
- `!TEXT` - set state for current task from text and move up
|
||||
- `>[TEXT]` - complete active task and move up, with optional status description
|
||||
- `<[TEXT]` - close active task and move up, with optional status description
|
||||
- `!TEXT` - set status for current task from text and move up (empty to open)
|
||||
- `,TEXT` - add text note (comment / description)
|
||||
- TBI: `*[INT]` - set priority - can also be used in task, with any digit
|
||||
- `@` - undoes last action (moving in place or upwards or waiting a minute confirms pending actions)
|
||||
- TBI: `*[INT]` - set priority - can also be used in task creation, with any digit
|
||||
- TBI: status history and creation with attribution
|
||||
- `&` - undo last action (moving in place or upwards confirms pending actions)
|
||||
- `wss://...` - switch or subscribe to relay (prefix with space to forcibly add a new one)
|
||||
|
||||
Property Filters:
|
||||
|
@ -123,6 +124,8 @@ Property Filters:
|
|||
- `+TAG` - add tag filter
|
||||
- `-TAG` - remove tag filters
|
||||
- `?STATUS` - filter by status (type or description) - plain `?` to reset, `??` to show all
|
||||
- `@AUTHOR` - filter by author (`@` for self, id prefix, name prefix)
|
||||
- TBI: Filter by time
|
||||
|
||||
Status descriptions can be used for example for Kanban columns or review flows.
|
||||
An active tag or status filter will also set that attribute for newly created tasks.
|
||||
|
@ -148,6 +151,11 @@ An active tag or status filter will also set that attribute for newly created ta
|
|||
|
||||
For debugging: `props`, `alltags`, `descriptions`
|
||||
|
||||
### Notes
|
||||
|
||||
- TBI = To Be Implemented
|
||||
- `. TASK` - create and enter a new task even if the name matches an existing one
|
||||
|
||||
## Nostr reference
|
||||
|
||||
Mostr mainly uses the following NIPs:
|
||||
|
@ -164,17 +172,26 @@ Considering to use Calendar: https://github.com/nostr-protocol/nips/blob/master/
|
|||
|
||||
## Plans
|
||||
|
||||
- Remove state filter when moving up?
|
||||
- Local Database Cache, Negentropy Reconciliation
|
||||
-> Offline Use!
|
||||
- Scheduling
|
||||
- Remove status filter when moving up?
|
||||
- Task markdown support? - colored
|
||||
- Time tracking: Ability to postpone task and add planned timestamps (calendar entry)
|
||||
- Parse Hashtag tags from task name
|
||||
- Unified Filter object
|
||||
-> include subtasks of matched tasks
|
||||
- Relay Switching
|
||||
- Speedup: Offline caching & Expiry (no need to fetch potential years of history)
|
||||
+ Fetch most recent tasks first
|
||||
+ Relay: compress tracked time for old tasks, filter closed tasks
|
||||
+ Relay: filter out task state updates within few seconds, also on client side
|
||||
+ Relay: filter out task status updates within few seconds, also on client side
|
||||
|
||||
### Command
|
||||
|
||||
- Open Command characters: `_^\=$%~'"`, `{}[]`
|
||||
- Remove colon from task creation syntax
|
||||
- reassign undo to `&` and use `@` for people
|
||||
- maybe use `;` for sorting instead of `::`
|
||||
|
||||
### Conceptual
|
||||
|
||||
|
@ -182,9 +199,10 @@ The following features are not ready to be implemented
|
|||
because they need conceptualization.
|
||||
Suggestions welcome!
|
||||
|
||||
- Special commands: help, exit, tutorial, change log level
|
||||
- Duplicate task (subtasks? timetracking?)
|
||||
- What if I want to postpone a procedure, i.e. make it pending, or move it across kanban, does this make sense?
|
||||
- Priorities
|
||||
- Dependencies (change from tags to properties so they can be added later? or maybe as a state?)
|
||||
- Dependencies (change from tags to properties so they can be added later? or maybe as a status?)
|
||||
- Templates
|
||||
- Ownership
|
||||
- Combined formatting and recursion specifiers
|
||||
|
@ -194,11 +212,45 @@ Suggestions welcome!
|
|||
|
||||
### Interfaces
|
||||
|
||||
- TUI: Clear terminal? Refresh on empty prompt after timeout?
|
||||
- TUI: Clear Terminal? Refresh on empty prompt after timeout?
|
||||
- Kanban, GANTT, Calendar
|
||||
- Web Interface, Messenger integrations
|
||||
|
||||
## Notes
|
||||
## Exemplary Workflows
|
||||
|
||||
- TBI = To Be Implemented
|
||||
- `. TASK` - create and enter a new task even if the name matches an existing one
|
||||
- Freelancer
|
||||
- Family Chore management
|
||||
- Inter-Disciplinary Project Team -> Company with multiple projects and multiple relays
|
||||
+ Permissions via status or assignment (reassignment?)
|
||||
+ Tasks can be blocked while having a status (e.g. kanban column)
|
||||
+ A meeting can be worked on (tracked) before it starts
|
||||
+ Schedule for multiple people
|
||||
- Tracking Daily Routines / Habits
|
||||
|
||||
### Contexts
|
||||
|
||||
A context is a custom set of filters such as status, tags, assignee
|
||||
so that the visible tasks are always relevant
|
||||
and newly created tasks are less of a hassle to type out
|
||||
since they will automatically take on that context.
|
||||
By automating these contexts based on triggers, scripts or time,
|
||||
relevant tasks can be surfaced automatically.
|
||||
|
||||
#### Example
|
||||
|
||||
In the morning, your groggy brain is good at divergent thinking,
|
||||
and you like to do sports in the morning.
|
||||
So for that time, mostr can show you tasks tagged for divergent thinking,
|
||||
since you are easily distracted filter out those that require the internet,
|
||||
as well as anything sportsy.
|
||||
After you come back from sports and had breakfast,
|
||||
for example detected through a period of inactivity on your device,
|
||||
you are ready for work, so the different work projects are shown and you delve into one.
|
||||
After 90 minutes you reach a natural low in your focus,
|
||||
so mostr surfaces break activities -
|
||||
such as a short walk, a small workout, some instrument practice
|
||||
or simply grabbing a snack and drink.
|
||||
After lunch you like to take an extended afternoon break,
|
||||
so your call list pops up -
|
||||
you can give a few people a call as you make a market run,
|
||||
before going for siesta.
|
||||
|
|
|
@ -7,6 +7,7 @@ pub fn some_non_empty(str: &str) -> Option<String> {
|
|||
if str.is_empty() { None } else { Some(str.to_string()) }
|
||||
}
|
||||
|
||||
// TODO as macro so that log comes from appropriate module
|
||||
pub fn or_print<T, U: Display>(result: Result<T, U>) -> Option<T> {
|
||||
match result {
|
||||
Ok(value) => Some(value),
|
||||
|
|
|
@ -400,7 +400,7 @@ async fn main() {
|
|||
tasks.move_up();
|
||||
}
|
||||
|
||||
Some('@') => {
|
||||
Some('@') | Some('&') => {
|
||||
tasks.undo();
|
||||
}
|
||||
|
||||
|
|
17
src/tasks.rs
17
src/tasks.rs
|
@ -28,6 +28,7 @@ pub(crate) struct Tasks {
|
|||
tasks: TaskMap,
|
||||
/// History of active tasks by PubKey
|
||||
history: HashMap<PublicKey, BTreeSet<Event>>,
|
||||
|
||||
/// The task properties currently visible
|
||||
properties: Vec<String>,
|
||||
/// The task properties sorted by
|
||||
|
@ -349,9 +350,10 @@ impl Tasks {
|
|||
}
|
||||
let res: Vec<&Task> = self.resolve_tasks(self.view.iter());
|
||||
if res.len() > 0 {
|
||||
// Currently ignores filter when it matches nothing
|
||||
// Currently ignores filtered view when it matches nothing
|
||||
return res;
|
||||
}
|
||||
// TODO use ChildrenIterator
|
||||
self.resolve_tasks(self.children_of(self.position)).into_iter()
|
||||
.filter(|t| {
|
||||
// TODO apply filters in transit
|
||||
|
@ -705,7 +707,7 @@ impl Tasks {
|
|||
}
|
||||
|
||||
pub(crate) fn track_at(&mut self, time: Timestamp) -> EventId {
|
||||
info!("{} from {}", self.position.map_or(String::from("Stopping time-tracking"), |id| format!("Tracking \"{}\"", self.get_task_title(&id))), time.to_human_datetime()); // TODO omit seconds
|
||||
info!("{} from {}", self.position.map_or(String::from("Stopping time-tracking"), |id| format!("Tracking \"{}\"", self.get_task_title(&id))), time.to_human_datetime());
|
||||
let pos = self.get_position();
|
||||
let tracking = build_tracking(pos);
|
||||
// TODO this can lead to funny deletions
|
||||
|
@ -723,6 +725,7 @@ impl Tasks {
|
|||
self.submit(tracking.custom_created_at(time))
|
||||
}
|
||||
|
||||
/// Sign and queue the event to the relay, returning its id
|
||||
fn submit(&mut self, builder: EventBuilder) -> EventId {
|
||||
let event = self.sender.submit(builder).unwrap();
|
||||
let id = event.id;
|
||||
|
@ -829,7 +832,7 @@ impl Tasks {
|
|||
self.sorting = vec;
|
||||
info!("Now sorting by {:?}", self.sorting);
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn add_sorting_property(&mut self, property: String) {
|
||||
// TODO reverse order if already present
|
||||
self.sorting.push_front(property);
|
||||
|
@ -843,9 +846,11 @@ pub trait PropertyCollection<T> {
|
|||
fn add_or_remove(&mut self, value: T);
|
||||
fn add_or_remove_at(&mut self, value: T, index: usize);
|
||||
}
|
||||
impl <T> PropertyCollection<T> for Vec<T>
|
||||
where T: Display, T: Eq, T: Clone {
|
||||
fn remove_at(&mut self, index: usize) {
|
||||
impl<T> PropertyCollection<T> for Vec<T>
|
||||
where
|
||||
T: Display + Eq + Clone,
|
||||
{
|
||||
fn remove_at(&mut self, index: usize) {
|
||||
let col = self.remove(index);
|
||||
info!("Removed property column \"{col}\"");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue