Colour, a page you can see the edge of, and a document on its own
Five of the nine things on the list, and one finding that came out of them. Colour: a marker pen and an ink colour, written as marks here rather than installed — the schema of a note decides what can be stored in it forever. A highlight is a <mark> so a reader that drops the colour still shows the word as marked, and marked text is painted dark whatever the theme. Both travel as HTML in Markdown, like underline, and both are read back. The PDF fills the screen: the browser's own full screen for the window frame, an overlay for the sidebar and the list, Escape and a visible button for the way out. The dashboard leads with the recent notes, sorted by time whatever order the notebooks are in. A tap on the blank part of a page puts the caret at the nearest position instead of nowhere. A drag from the left edge shows the sidebar. The page has an edge on a phone, where it had none. The finding: at the speed a robot types, a long note loses keystrokes between the editor and the pagination measuring after each one — 87 of 220 paragraphs. Nothing is lost at 50 characters a second, so the page-count check now pastes its bulk text rather than measuring typing throughput. And the history suite asked for "the first note in the list" without waiting for the note to reach the server; it asks by name now. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c9148540a8
commit
9507761bce
23 files changed
+1091
-109
No files matched your search
@@ -613,12 +613,13 @@ docker compose -f docker-compose.dev.yml up -d --build # must be running
|
||||
| Suite | Checks | What it holds down |
|
||||
| --- | --- | --- |
|
||||
| `admin` | 15 | no sign-up anywhere; `/api/admin/*` refused for non-admins even when called directly |
|
||||
| `shell` | 9 | the frame around the writing: what the dashboard leads with, the sidebar answering a drag from the edge, a tap on blank paper putting the caret there, and the page having a visible edge on a phone |
|
||||
| `oidc` | 40 | the whole redirect journey against a provider that signs real tokens — and the four ways it must fail: a refusal, a replayed ticket, a token signed with an unpublished key, a token addressed to another client |
|
||||
| `editor` | 45 | tables and their right-click menu, task lists, note links, backlinks — and that each survives a reload |
|
||||
| `editor` | 52 | tables and their right-click menu, task lists, note links, backlinks — and that each survives a reload |
|
||||
| `search-attachments` | 12 | body-only matches, ranking, umlauts; images as blob URLs, not inline bytes |
|
||||
| `history` | 10 | a large deletion is snapshotted, restoring works, restoring is itself undoable |
|
||||
| `drawing` | 22 | strokes survive the poller, match across four viewport widths, and stay on the page they were drawn on |
|
||||
| `pdf` | 96 | import, page proportions, lazy loading, and reading with the network off |
|
||||
| `pdf` | 101 | import, page proportions, lazy loading, and reading with the network off |
|
||||
| `attachments-lifecycle` | 10 | a picture is kept while any version shows it, and freed once none does |
|
||||
| `conflict` | 10 | a late write wins but the state it buries survives as a version |
|
||||
| `export` | 23 | the downloaded bytes are real Markdown, ZIP and PNG, unpacked and read back |
|
||||
@@ -674,6 +675,26 @@ block a meaning, which only moved the problem — the whole sheet sat hard again
|
||||
the left edge. Centred, the same leftover space reads as two margins and needs no
|
||||
explaining.
|
||||
|
||||
**The dashboard leads with what you were last writing.** The six most recently
|
||||
edited notes come first and the shelf of notebooks second, because coming back to
|
||||
a note is the common case and choosing a notebook is the occasional one. "Recent"
|
||||
is sorted by time here whatever order the notebooks themselves are in — it is a
|
||||
question about time, and a hand-made arrangement is the wrong answer to it.
|
||||
|
||||
**Tapping the blank part of a page starts writing there.** The text is only as
|
||||
tall as what has been written, so most of a fresh page is *beside* the editable
|
||||
area rather than in it; a tap down there used to land on nothing at all — no
|
||||
caret, and on a phone no keyboard. The caret goes to the position nearest the
|
||||
tap, not simply to the end, because on a page with several paragraphs "nearest"
|
||||
is what the tap meant.
|
||||
|
||||
**Dragging in from the left edge shows the sidebar** on a phone or tablet, and
|
||||
dragging it back hides it. The button that opens it sits in the top corner, which
|
||||
is the one part of a tall screen a thumb cannot reach. The gesture has to start
|
||||
within 28px of the edge, travel 60px, and be more sideways than downwards —
|
||||
without the first rule every sideways drag inside a note opens it, and without
|
||||
the third, scrolling with a thumb near the edge does.
|
||||
|
||||
**The typeface is a per-account setting** (Account → Profile): serif, sans or
|
||||
mono. How a chapter opens is chosen there too, and light or dark, for the same
|
||||
reason — the sun used to sit in the corner of the sidebar, where it was reached
|
||||
@@ -702,6 +723,12 @@ itself. A `useLayoutEffect` runs between the DOM being built and the browser
|
||||
painting it, which is exactly the gap that flash lived in. A test samples the
|
||||
sheet's height every frame across a note switch, because one frame is all it was.
|
||||
|
||||
**The page has an edge on a phone too.** The paper there runs to the edges of the
|
||||
screen — a phone has no room for margins around a margin — but it used to be
|
||||
drawn with no border and no shadow at all, which left nothing to see where one
|
||||
page ended and the next began. It has an outline now; the shadow stays a desktop
|
||||
thing.
|
||||
|
||||
**A quote holds whole blocks.** A heading, a list and a closing line inside one
|
||||
are ordinary blocks of the document, and they are spaced like ordinary blocks:
|
||||
the rule that gives the writing its rhythm reaches only the editor's own
|
||||
@@ -824,6 +851,25 @@ to survive `document.execCommand`. Notes written before this were
|
||||
opened and rewritten in the new format on the next save, so nothing needs
|
||||
migrating up front.
|
||||
|
||||
### Colour, of two kinds
|
||||
|
||||
A marker pen and a colour for the letters, both written as marks in
|
||||
[`editor/textMarks.js`](frontend/src/editor/textMarks.js) rather than installed —
|
||||
the schema of a note decides what can be stored in it forever, and that belongs
|
||||
in files this project owns, the same reason the alignment extension is here.
|
||||
|
||||
A highlight is a `<mark>`: the element that *means* highlighted, so a reader that
|
||||
drops the colour still shows the word as marked. Marked text is painted with dark
|
||||
ink whatever the theme, the way a real marker leaves the writing alone — a
|
||||
light-grey word on pale yellow would be unreadable on the dark one. An explicit
|
||||
text colour is an inline style and still wins.
|
||||
|
||||
Both travel as HTML in Markdown, like underline, since Markdown has no colour,
|
||||
and both are read back — including a bare `<mark>` with no colour, which is what
|
||||
most other writers emit. Neither keeps its palette in the schema: what the
|
||||
toolbar offers is an interface question, while the document only has to hold what
|
||||
was chosen, including a colour picked before the palette last changed.
|
||||
|
||||
### Note links and backlinks
|
||||
|
||||
Typing `@` opens a search over notes and notebooks and inserts a `noteLink`
|
||||
@@ -880,6 +926,17 @@ page is expensive to draw and cheap to hold, so scrolling back up repaints
|
||||
nothing. Canvases are sized in device pixels and scaled down by CSS, which is
|
||||
what keeps text sharp on a high-density screen.
|
||||
|
||||
**Full screen is two things at once.** The button asks the browser for its own
|
||||
full screen — which is what puts the document past the address bar and the window
|
||||
frame, and the reason to want it on a laptop or a tablet — *and* lays the
|
||||
workspace out as an overlay over the app, which is what actually removes the
|
||||
sidebar, the note list and the title bar. Either alone is half the job, and a
|
||||
browser that refuses the first (an iPhone does) still gets the second. Escape
|
||||
leaves, and so does the button, which stays in the toolbar while full: a way out
|
||||
that is only known and not visible is not a way out. Leaving the browser's full
|
||||
screen by any other route takes the overlay with it, or the app would be left
|
||||
pretending to be full screen inside an ordinary window.
|
||||
|
||||
**Zooming holds something still.** A zoom changes how tall the document is, so
|
||||
the scroll position means something different afterwards — left alone, every step
|
||||
drifts and three presses of + leave you somewhere else in the file. What should
|
||||
|
||||
Reference in new issue
Block a user