rust-embed refused to derive without `web/dist`, so on a fresh clone
`cargo check`, `cargo test` and rust-analyzer failed with a derive error that
did not say what was missing. With `allow_missing` the embed is empty until
the frontend is built, and the handler gives the answer it already had for
that case, "frontend not built". The release build is unchanged once
`web/dist` is there, which `make build`, the Dockerfile and CI all see to.
The browser grouped the agenda by its own midnight and remembered that it had
opened it by its own date, while the server counts due dates, mails and the
diary in `WORKSPACE_TIMEZONE`. A laptop on a trip, or a browser set to UTC,
showed a card as late that the morning mail called due today, and opened the
agenda a second time on one workspace day or not at all. A day was also taken
to be 86400 seconds, which it is not when the clocks change.
The agenda answer now carries `today`: the date in the configured timezone,
when it starts and ends, and when the seventh day after it ends, all from the
same `day_bounds` the mails use. The browser groups by those and keys the
once-a-day opening on that date. The screenshot run marks the agenda as seen
under the same date.
Three small things the docs pass turned up.
A search of nothing but punctuation — `!!!`, `--` — gave the FTS query no
terms, and the list handler then fell through to browsing with no parent,
which answered with the spaces as if they were matches. It now finds nothing.
Two spaces could have the same name: the slug was made unique (`work-2`) but
the name kept, so the bar showed two pills that read alike and `:space work`
picked the first. A new space, a space renamed, and a directory made at the
root of the mount are refused when another space has that name in any case or
that slug. Folders and documents may still share names; they are told apart by
where they sit.
A name had no ceiling. A file is called by its name on the mount, where most
filesystems stop at 255 bytes, so a document, folder, file or space is now at
most 200 characters, checked where one is made or renamed.
`PUT /api/nodes/{id}` wrote the whole node, and a field left out was taken as
empty: a rename sent without the body erased the text. The browser always sent
it, which was the other half of the trouble. To rename a document it sent the
body it had — the draft for one open here, a copy fetched a moment earlier for
any other — and without the version it had seen, so a save made in another
tab, on the phone or over the mount in between was written over, kept only as
a revision nobody was told about.
Now `name` and `body`, like the rest, change only when they are sent. A rename
sends the name alone, and for a document open in a tile the `updated_at` that
tile last saw, so a rename of a document saved elsewhere since is refused the
way `:w` is, rather than stamping a new version over it that the next autosave
would then write the draft past. Toggling a space's board sends only that.
The README grew a section per feature and is a good reference, but nothing
said where to begin. docs/wiki now has a getting-started page, a guide that
walks through one day with the workspace and explains each part where it comes
up, and a page per part of the app, each with screenshots of what it
describes.
Three pages are read out of the code rather than written, so they cannot drift
from it: the keys and commands from Help.svelte and commands.ts, the same lists
`:help` draws; the settings from .env.example, which gains a heading for the
vault, trash and history settings so they no longer sit under mail; and the
API from the README's table. `make wiki` writes them, and `--check` fails when
one is stale or a link between pages leads nowhere. `--publish` lays the pages
out for a GitHub wiki: links without `.md`, images beside them, `[[` escaped so
the wiki does not take a command's help text for a link to a page.
The screenshots are taken by `make screenshots`: the debug binary on a
temporary data directory, with a password made up for the run, filled with an
example workspace over the API, and a headless Chromium driven over the
DevTools protocol through the views the docs show. Nothing outside the
temporary directory is touched but docs/images, and the pictures are cut to
256 colours, a third of their size, which a dark UI does not show.
The README opens with the banner, a CI badge, the guide, the features grouped
by what they are for, and six of the screenshots.
The app was a ring and a dot, drawn in CSS in the bar and inlined as a data
URL for the favicon. It now has an icon of its own: the `~/` of the prompt it
is named after, with the cursor waiting beside it in the alarm colour of the
theme. It is the favicon, a full-bleed touch icon for a phone's home screen,
and the mark in the bar, on the login and on the share page, served from
`web/public` so all of them are the same file.
The banner and a 512 px copy in docs/images are for the README and the wiki.
The crate description says what the workspace is now, not the diary it was.