Closed thombruce closed 1 year ago
Status | Category | Percentage | Covered / Total |
---|---|---|---|
🟢 | Lines | 93.59% / 60% | 877 / 937 |
🟢 | Statements | 93.59% / 60% | 877 / 937 |
🟢 | Functions | 72.52% / 60% | 66 / 91 |
🟢 | Branches | 90% / 60% | 108 / 120 |
Must haves:
How do we determine which list to show? How do we determine which list to redirect to after deleting an active list?
Perhaps we can show a global list on the main index, comprised of all todos. When the user adds a new todo, it should be attached to... whatever their default list happens to be.
Later, they should be able to configure their default list.
Question circling my mind right now is, is that simple enough?
I want to be able to jump in and start adding todos to my list straight away (hence a default list and always showing a list).
What would be nice is to be able to simply type out a todo, and include tags in the text that could be used for sorting into lists... The todo.txt format has a concept of +projects denoted by a plus symbol that can be written inline in a todo, just like that.
Drawback to that todo.txt +project approach... It terminates on whitespace. No project names made up of more than a single word. While techy users will be satisfied with camelCase, snake_case, PascalCase or kebab-case, general users might expect to be able to call their lists things like "My Shopping List", rather than MyShoppingList.
Best way to accommodate both?
That sounds pretty good to me.
This does mean that each list has a unique shortname, somewhat making its UUID redundant except... that the UUID might remain useful if the user every connects to a server (having a unique reference distinct from other people's similarly named project tags).
Plus... if we have an additional unique reference (the UUID), we can permit the shortname to be changed by substituting one for the other... right? _If instead of storing +projectName
as part of the todo text, we substituted it for +uuid-uuid-uuid-uuid
, we wouldn't have to change the tag whenever the project shortName was changed; we would just need to decorate it at display time...?
Alternatively, we could do a broad substitution with searching and replacing when it gets updated but... the decorator approach seems better.
RegEx ideas, btw... Something like:
/(?<=^|\s)\+\S+/
(?<=^|\s)
is a lookbehind, testing for either the beginning of the string ^
or a whitespace character \s
before the matched pattern. The matched pattern \+\S+
matches a + followed by any amount of non-whitespace characters.
Actually, the plus itself probably shouldn't be part of the match. Maybe modify to:
/(?<=(?:^|\s)\+)\S+/
This makes the + part of the lookbehind. Does JS support lookbehind? Probably, I'm sure. It's regex support has come a long way since I was last playing extensively with it. This should be trivial.
Any issues? Maybe + itself shouldn't be permitted in the tag string. Maybe we should reduce the tag string to a subset of characters rather than the very, very broad \S
non-whitespace check. For certain definitions of "maybe" (i.e. DEFINITELY).
EDIT:
A project or context contains any non-whitespace character.
Source: https://github.com/todotxt/todo.txt
That's what it says. Let's support that initially and maybe add a TODO to give it more consideration a ways down the line. I mean really... ANY non-whitespace character? Really? We might have to put a limit on that if we launch a cloud version, surely... especially with regards to shared lists.
Also it seems more idiomatic to me that the @ symbol tag collaborators. In todo.txt it's a context tag.
Strictly, the inline project tagging does not need to be part of this PR. We can get lists done with UI support first of all, and deal with that after there actually are these taggable projects (Lists) to support the concept.
Just keep in mind the notion of shortNames. Maybe auto-generate shortNames for users' lists at this time with the promise of them being taggable in the future.
Maybe I should rename this concept "Projects" rather than lists... since the todos tagged like this could ultimately appear on several "lists".
Well, I'm not changing the branch or issue names. I have just renamed the PR. And I will rename 'List' to 'Project' in the code. The idea is very much to aim for compatibility with todo.txt's +project tags. While such compatibility may not be part of this PR, the idea will be that a user may tag a +project directly in their todo to have the todo be associate with it (we'll do the same for contexts after), and if they do not associate a todo with a +project in the text of the todo, we can append the +project at the end during an export to todo.txt format...
Yeah?
We can add the concept of totally distinct Lists/Workspaces later.
Actually, if a todo isn't associated with a +project via a tag, then it should just be a member of the active list... which right now, in the absence of lists, is none at all. But "Projects" should be navigable in much the same way as I would expect lists to be, so...
We don't need to do both. Not yet.
The user can take or leave the tagging approach, but if they do utilise it then it will be a lot like having distinct lists along with a super list.
We'll do this for +projects and \@contexts and we will consider this enough to mark off those "List" issues for now, with a workspaces concept reserved for future considerations... basically a separate, distinct list space, but far out of scope of what I'm discussing here and largely redundant at this time.
A todo should:
A project should:
We've got our first many-to-many association here... which probably means we need to add a join table.
Since they're fundamentally a kind of tag, maybe something like a "taggings" or "taggables" collection. Not "tags" as we may reserve that name for the concept of actual tags later.
Such a collection would have a todoId attribute and taggedById and taggedByType attributes. Might hold back on that complexity for now and just have a simpler todoId+projectId collection (this can always be expanded upon and repurposed later). Might call it... projectables
, with the idea of contextables
and taggables
to follow. These aren't names that the user should expect to see in the app in any case.
Y'know, I'm probably over-engineering this. What I need to do is think less about Toodles and start thinking about how Toodles can serve the todo.txt format as a first priority.
Think about loading in a todo.txt document; this document won't have +uuid-uuid-uuid-uuid
formatted project tags. It will have what I describe above as the decorated form: +shortName
.
Imagine a todo.txt
with a thousand items, and the unnecessary overhead of parsing, generating, substituting, etc. that would go into importing such a document.
I'm saying, forget UUIDs - identify projects by their shortName at this time (we can expand on this later). That way a todo imported from todo.txt
is already ready to go. The only decoration we need to do is a little bit of parsing at rendering time.
Todos still need IDs, but let's start simple with Projects and use the shortName concept.
Other thoughts:
I've also thought about tagging todo.txt
exported todos with things like their sum interval duration and their tally count. These cannot be converted back to our granular system of date-stamped intervals and tallies, so we should have a way of storing the values directly on the todo, no? A cache of the sum values. Because it's meaningless to record a date-stamped version when we import from such a document.
Also note that we have a similar problem with todo IDs. If we, for example, export to todo.txt and attempt to reimport either what has changed or even just sync with an existing document, unless we add an id tag to the todos, looking something like id:134a8579-1688-4864-892c-4b6556b8a2ff
which is a pretty long and hideous string... then we have no way to accurately reimport them.
Also note that without recording an updated
timestamp to the exported document, we cannot know which todo has changed more recently... maybe by checking the revision date on the document? This will result in some false positives.
So, certainly we'll add duration and tally caches to todos (and ask ourselves questions about how these might mismatch the granular records). I don't see us exporting an updated
timestamp onto todo.txt
lines. But it's difficult to conceive of us getting by without the ID. I wonder if there's a shorter alternative to UUIDv4...
Hey, to that last question... There's nanoid: https://github.com/ai/nanoid
npx nanoid
# rfVDbZtomeGSMAgF4Shcd
Means shorter IDs that could potentially go into a todo.txt document like: id:rfVDbZtomeGSMAgF4Shcd
.
Much less cumbersome than the UUID format. Obviously still not readable, but... an ideal compromise for the needs of the project.
There's a bunch left undone and/or commented out in the recent commit, but we now have Projects being created when added to the text of a todo in the form of +project
.
Next up is UI stuff. We need to:
We can't highlight a project in the todo text right now, because the todo text element is an input - I'll create a separate issue to address this. Should be a div/span instead, that is contenteditable in some regard.
All that's left to do from my list above is:
This won't be a difficult addition. We just utilise the already written parse function again, but we use it on the update action too.
Right now there is no way to delete a project when empty... or to delete a project and all of its associated todos. We'll address these in a future issue.
Gonna:
...and then call this complete.
closes #4, closes #1