Pin notes to passages in a PDF, and put the notes control with the rest
The panel beside a PDF is for notes about the document; a note that belongs to one paragraph is a different thing, and one that has to begin "on page 14, third paragraph" has already lost its place. Click Randnotiz, click the passage, write. Pins ride in the same per-page overlay as the drawings, in PDF points, so one stays on its sentence at every zoom and in the exported file. Living outside the note body has consequences that each needed handling: nothing else would index them for search, so the viewer feeds them in with their page numbers; clearing a page's ink must not take them; and "is this overlay empty?" was answered by counting strokes — in the client *and* independently in the server, so an overlay holding only pinned notes was stored as NULL and lost every note on it. They are stamped into the annotated export as a numbered marker plus a box of text, on whichever side of the pin has room. Standard PDF fonts are Latin-1, so characters outside it are replaced rather than failing the whole export. The Notizen control moves into the viewer's toolbar. A second row for one button cost reading height on every screen and put one of the document's controls somewhere none of the others were. On a phone, where the viewer is not on screen while the notes are, the way back sits in the panel. Renaming a separator no longer shifts the row: the two rules always share what is left over equally and the middle keeps one width in both states. 215 unit tests, 206 browser checks across eleven suites. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2cee00e38e
commit
6438648313
16 files changed
+1228
-170
No files matched your search
@@ -17,7 +17,7 @@ A self-hosted note-taking application with rich text editing, freehand drawing,
|
||||
- **Undo/Redo** — Full history stack for drawing operations
|
||||
- **Notebooks & Folders** — Create notebooks with custom gradient covers, organize notes by folder
|
||||
- **Star/Favorite** — Quick access to important notes
|
||||
- **PDF Reading & Annotation** — Import a PDF, read it, select its text, draw on it, write notes beside it, and export it with or without your marks
|
||||
- **PDF Reading & Annotation** — Import a PDF, read it, select its text, draw on it, pin notes to individual passages, write notes beside it, and export it with or without your marks
|
||||
- **Export** — Any note, notebook or the whole account as Markdown or PDF, entirely in the browser
|
||||
- **Import** — Markdown files, or a ZIP this app exported, come back as notes with their images
|
||||
- **Sorting** — Each notebook remembers how its notes are ordered, including an arrangement made by hand
|
||||
@@ -304,7 +304,7 @@ failure distinguished by comparing an error's `.message` to a magic string.
|
||||
Failures now carry a typed `SyncError.code`; `.message` still holds the same
|
||||
string, so the remaining JavaScript callers are unaffected.
|
||||
|
||||
The 199 unit tests concentrate on the same places, and several exist because the
|
||||
The 215 unit tests concentrate on the same places, and several exist because the
|
||||
bug they cover actually happened:
|
||||
|
||||
- a queue entry that fails must stay queued, with an attempt counter
|
||||
@@ -332,7 +332,7 @@ docker compose -f docker-compose.dev.yml up -d --build # must be running
|
||||
| `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` | 7 | strokes survive the poller, and match across four viewport widths |
|
||||
| `pdf` | 41 | import, page proportions, lazy loading, and reading with the network off |
|
||||
| `pdf` | 57 | 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` | 21 | the downloaded bytes are real Markdown, ZIP and PNG, unpacked and read back |
|
||||
@@ -753,6 +753,37 @@ its history on a change that is not to the note at all.
|
||||
|
||||
---
|
||||
|
||||
## Notes pinned to a passage
|
||||
|
||||
The panel beside a PDF is for notes about the document. A note that belongs to
|
||||
*one paragraph* is a different thing — and a note that has to begin "on page 14,
|
||||
third paragraph" has already lost its place. So a note can be pinned to a spot:
|
||||
click **Randnotiz**, click the passage, write.
|
||||
|
||||
Pins are stored in the same per-page overlay as the drawings, in **PDF points**.
|
||||
That is what keeps one on its sentence at every zoom, on every screen, and in the
|
||||
exported file — the same property the strokes have, for the same reason.
|
||||
|
||||
Being in the overlay rather than in the note body has three consequences, each of
|
||||
which needed handling rather than assuming:
|
||||
|
||||
- **Search.** Nothing else would index them, so the viewer feeds them to the
|
||||
local index itself, with their page numbers — finding the words is only half of
|
||||
finding the note.
|
||||
- **Clearing the ink.** "Seite leeren" empties the drawing. It must not take the
|
||||
notes pinned to that page: same page, different thing.
|
||||
- **"Is this overlay empty?"** The client and the server each held their own
|
||||
answer, and both counted strokes only. An overlay carrying nothing but pinned
|
||||
notes was therefore stored as `NULL` — every note on it lost on the next save.
|
||||
Both now ask about strokes *and* pins.
|
||||
|
||||
They come along when the document is exported with annotations: each becomes a
|
||||
numbered marker plus a small box with its text, placed on whichever side of the
|
||||
pin has room. Only Latin-1 survives — the standard PDF fonts cannot encode more,
|
||||
and one em dash must not cost the whole export, so anything else is replaced.
|
||||
|
||||
---
|
||||
|
||||
## Import
|
||||
|
||||
The other half of the promise that notes are not hostage to this program. A
|
||||
|
||||
Reference in new issue
Block a user