feat: OneNote-style notebooks, text fonts, and page navigation
All checks were successful
CI / Windows build (push) Successful in 8m42s

Add notebook.json containers with multi-member pages, fix PDF text
editing (size/bold/drag/double-tap), index SidecarText in search, and
share keyboard page shortcuts plus a PDF scrubber.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-05 20:27:35 +08:00
parent 4a6fe7d05e
commit 2b1c6ba7e0
18 changed files with 1344 additions and 112 deletions

View File

@@ -290,6 +290,24 @@ void main() {
expect(t.text, '');
expect(t.fontSize, 0.03);
expect(t.color, 0xFF000000);
expect(t.fontWeight, 400);
expect(t.fontFamily, isNull);
});
test('SidecarText fontWeight and fontFamily round-trip', () {
const tx = SidecarText(
id: 't-bold',
nx: 0.1,
ny: 0.2,
text: '粗体',
fontSize: 0.045,
fontWeight: 700,
fontFamily: 'IBM Plex Sans',
);
final decoded = SidecarText.fromJson(tx.toJson());
expect(decoded, tx);
expect(decoded.fontWeight, 700);
expect(decoded.fontFamily, 'IBM Plex Sans');
});
test('paragraph-anchored bookmark round-trips its anchor + char index', () {

View File

@@ -339,4 +339,30 @@ void main() {
expect(notes.single.title, 'Loose Note');
});
});
group('notebook container (OneNote-style)', () {
test('createNotebookContainer writes manifest + blank page', () async {
final vault = await makeService();
await vault.setVaultRoot(tempDir.path);
final c = await vault.createNotebookContainer('Linear Algebra');
expect(c.title, 'Linear Algebra');
expect(c.memberCount, 1);
final containers = await vault.scanContainers();
expect(containers.map((x) => x.folderPath), contains(c.folderPath));
// Containers are excluded from the single-doc / free-note scans.
expect(await vault.scanNotes(), isEmpty);
expect(await vault.scanNotebooks(), isEmpty);
final page = await vault.addBlankPageToContainer(
c.folderPath,
title: 'Lecture 2',
);
expect(page.title, 'Lecture 2');
final again = await vault.scanContainers();
expect(again.single.memberCount, 2);
});
});
}