A chapter you can see, in the colour you chose

A chapter did not show until the notebook had a note in it. "Nothing
here" was asked of the notes alone, so a notebook whose only contents
were chapters showed the empty-list panel with the chapters hidden
behind it — making a chapter in a fresh notebook appeared to do nothing
at all. It is asked of every row now, and a notebook with chapters but
no loose notes says so in one line rather than looking like a list that
failed to load.

The colour is chosen while the chapter is being made, in the dialog that
asks for its name. It is what tells one chapter from the next, and
having to right-click a fresh one to say which it is meant two visits
for one decision. Renaming and recolouring afterwards are one entry in
its menu and one write; the server already took the colour on create,
the client simply never sent it.

The word "here" is gone. The line along the top of the pane says which
of the two places you are in, and saying it twice was noise.

Thirteen suites green: 338 browser checks, 241 unit tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
marcandClaude Opus 5 committed 2026-08-12 19:28:57 +02:00
1 parent ebf1f1bc62
commit 165ccf3cf7
8 files changed
+197 -66

No files matched your search

+23 -14
View File
@@ -498,6 +498,16 @@ export function NoteList({
a way back. In the other two views the chapter rows stay where they are. */
const shownChapters = openChapter ? [] : chapters || [];
/* Every row this list shows, in the order it shows them.
*
* Separators are part of the manual arrangement and only mean something
* there: in "newest first" the notes would slide past a line on every edit.
* They are not shown in the other orders, and are still in place on the way
* back. */
const entries = reorderable
? mergeEntries(notes, separators, shownChapters)
: [...shownChapters.map(asChapterEntry), ...notes.map(asNoteEntry)];
return (
<div
data-list-current={isCurrent === null || isCurrent === undefined ? undefined : isCurrent ? "on" : "off"}
@@ -560,11 +570,6 @@ export function NoteList({
>
{openChapter ? openChapter.name : title}
</h2>
{/* Said in words as well as in the line above, because a coloured edge
is only a hint until you know what it means. */}
{isCurrent && (
<span style={{ fontSize: 10, color: T.accent, fontWeight: 700, flexShrink: 0 }}>· here</span>
)}
</div>
<div style={{ display: "flex", gap: 4, flexShrink: 0 }}>
{reorderable && (
@@ -712,7 +717,11 @@ export function NoteList({
onPointerDown={onFocusList}
style={{ flex: 1, overflowY: "auto", padding: 6, WebkitOverflowScrolling: "touch" }}
>
{notes.length === 0 ? (
{/* "Nothing here" means nothing at all — not "no loose notes".
Asked of the notes alone, a notebook whose only contents were
chapters showed an empty list with the chapters hidden behind it,
and a chapter made in an empty notebook appeared to do nothing. */}
{entries.length === 0 ? (
<div
style={{
display: "flex",
@@ -755,14 +764,7 @@ export function NoteList({
</div>
) : (
<>
{/* Separators are part of the manual arrangement and only mean
something there: in "newest first" the notes would slide past a
line on every edit. They are not shown in the other orders, and
are still in place on the way back. */}
{(reorderable
? mergeEntries(notes, separators, shownChapters)
: [...shownChapters.map(asChapterEntry), ...notes.map(asNoteEntry)]
).map((entry) => {
{entries.map((entry) => {
const showDropLine = moving && dnd.overId === entry.id;
/* The whole row, indicator included, is the drop target.
*
@@ -890,6 +892,13 @@ export function NoteList({
})}
{/* Dropping below the last row moves something to the end, which
otherwise needs an awkward drop onto the very last note. */}
{/* Said out loud, so a notebook holding only chapters does not read
as a list that failed to load. */}
{notes.length === 0 && !isTrashView && (
<div data-no-loose-notes style={{ padding: "12px 12px 4px", fontSize: 12, color: T.muted }}>
No notes outside the chapters yet.
</div>
)}
{moving && (
<div data-drop-end {...dnd.rowProps(END_ID)} style={{ minHeight: 56 }}>
{dnd.overId === END_ID && <DropLine T={T} />}