feat(pdf): anchored scratch links replace board
Some checks failed
CI / Windows build (push) Has been cancelled

Replace the rejected standalone sticky-card board with the real
feature: place a link anchor anywhere on a PDF page, tap it to open
split view whose right pane is THAT anchor's own infinite scratchpad
(keyed by anchor id) — like a paper sticky-note tab.

- ScratchLink model + scratch_links table (id, doc, page, nx, ny).
- PDF editor: "place link" tool drops/loads/shows tappable markers;
  tap opens SplitViewScreen for that anchor; long-press deletes.
- SplitViewScreen rebuilt on pdfrx (was syncfusion), right scratchpad
  keyed by scratchLinkId, new brush palette (was AnnotationToolbar).
- Remove board_screen + its test + the home board entry.

analyze clean, tests green.
This commit is contained in:
2026-06-24 20:02:12 +08:00
parent f757701391
commit 9bb5c483d6
13 changed files with 759 additions and 1076 deletions

View File

@@ -63,6 +63,9 @@
"nextPage": "Next page",
"toolSelectText": "Select text",
"actionHighlightSelection": "Highlight selection",
"toolPlaceScratchLink": "Place scratch link",
"scratchLinkDeleteTitle": "Delete scratch link?",
"scratchLinkDeleteBody": "This removes the anchor and its private scratchpad.",
"failedToOpenPdf": "Failed to open PDF:\n{error}",
"@failedToOpenPdf": {
"placeholders": { "error": { "type": "String" } }

View File

@@ -422,6 +422,24 @@ abstract class AppLocalizations {
/// **'Highlight selection'**
String get actionHighlightSelection;
/// No description provided for @toolPlaceScratchLink.
///
/// In en, this message translates to:
/// **'Place scratch link'**
String get toolPlaceScratchLink;
/// No description provided for @scratchLinkDeleteTitle.
///
/// In en, this message translates to:
/// **'Delete scratch link?'**
String get scratchLinkDeleteTitle;
/// No description provided for @scratchLinkDeleteBody.
///
/// In en, this message translates to:
/// **'This removes the anchor and its private scratchpad.'**
String get scratchLinkDeleteBody;
/// No description provided for @failedToOpenPdf.
///
/// In en, this message translates to:

View File

@@ -176,6 +176,16 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get actionHighlightSelection => 'Highlight selection';
@override
String get toolPlaceScratchLink => 'Place scratch link';
@override
String get scratchLinkDeleteTitle => 'Delete scratch link?';
@override
String get scratchLinkDeleteBody =>
'This removes the anchor and its private scratchpad.';
@override
String failedToOpenPdf(String error) {
return 'Failed to open PDF:\n$error';

View File

@@ -176,6 +176,15 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get actionHighlightSelection => '高亮所选';
@override
String get toolPlaceScratchLink => '放置便签链接';
@override
String get scratchLinkDeleteTitle => '删除便签链接?';
@override
String get scratchLinkDeleteBody => '这会移除锚点及其专属草稿纸。';
@override
String failedToOpenPdf(String error) {
return '打开 PDF 失败:\n$error';

View File

@@ -54,6 +54,9 @@
"nextPage": "下一页",
"toolSelectText": "选择文字",
"actionHighlightSelection": "高亮所选",
"toolPlaceScratchLink": "放置便签链接",
"scratchLinkDeleteTitle": "删除便签链接?",
"scratchLinkDeleteBody": "这会移除锚点及其专属草稿纸。",
"failedToOpenPdf": "打开 PDF 失败:\n{error}",
"pdfNoPages": "PDF 没有任何页面。",
"pageOfPages": "{current} / {total}",