Lay the notes screen out like a notes app
The list of notes and the note being written are one screen now, two panes: the notes on the left, the open one on the right, side by side where there is room and one at a time on a phone, where the back button returns to the list. The search box moved into the top of that list, and its results *are* the list — searching is a way of finding a note, not a separate place to be, and a tab for it was a tab too many. Emptying the box brings the whole list back. Opening a hit opens that day at the lesson that matched, rather than at the top of a day with six of them. A row has to say what the note holds, so the listing carries it: the subjects a day covers, how many lessons, and the first line actually written in it. One request for the whole list rather than one per note. `plainText` is now one rule in one place for wherever a note is shown rather than edited — the search snippet and the list row both went through their own half-copy of it, and the row's copy rendered a table as `| | |` and left `_Fazit_` wearing its markers. It strips one leading marker, not each in turn, because `## 1. Deutsch` keeps its lesson number and the list rule was eating it. Driven in Firefox at both widths: the list, the search, opening a hit, the jump to the lesson, and the phone's list-then-note. 390 unit tests, 116/117 smoke. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -742,7 +742,9 @@ console.log('\n== web app ==');
|
||||
'the shell loads the app as a module, so its imports resolve',
|
||||
/<script type="module" src="app\.js">/.test(shellText) &&
|
||||
shellText.includes('data-command="bold"') &&
|
||||
shellText.includes('id="search-form"'),
|
||||
shellText.includes('id="search-form"') &&
|
||||
// The note list and the editor are one screen now, not two tabs.
|
||||
shellText.includes('id="rail-list"'),
|
||||
);
|
||||
|
||||
const anonymousSession = await (await fetch(`${root}/app/session`)).json();
|
||||
@@ -831,6 +833,21 @@ console.log('\n== web app ==');
|
||||
`${bySubject.count} note(s)`,
|
||||
);
|
||||
|
||||
// What a row in the app's note list shows, which is why the listing carries
|
||||
// it: one request for the whole list rather than one per note.
|
||||
const listing = await (await fetch(`${root}/api/notes?limit=5`, { headers: withSession })).json();
|
||||
const dayRow = listing.notes?.find((note) => note.path === '2026/2026-09-18.md');
|
||||
check(
|
||||
'the listing says what a note holds, without its body',
|
||||
dayRow !== undefined && dayRow.text === undefined && dayRow.lessons === 1 && dayRow.subjects?.includes('Geschichte'),
|
||||
`${dayRow?.lessons} lesson(s), subjects ${dayRow?.subjects?.join('/')}`,
|
||||
);
|
||||
check(
|
||||
'and a preview that reads as prose',
|
||||
/Weimarer Republik/.test(dayRow?.preview ?? '') && !/[#*|]/.test(dayRow?.preview ?? ''),
|
||||
dayRow?.preview,
|
||||
);
|
||||
|
||||
// Full text over the files themselves — the app's search box. It reads disk,
|
||||
// so a note written seconds ago is findable without a crawl, which is the
|
||||
// whole reason it does not go through the index.
|
||||
|
||||
Reference in New Issue
Block a user