feat: add wireframe in docs
This commit is contained in:
parent
0c71399867
commit
abbaf462e1
|
@ -125,3 +125,6 @@ devtools_options.yaml
|
||||||
test/features/*_test.dart
|
test/features/*_test.dart
|
||||||
**/app_localizations*.dart
|
**/app_localizations*.dart
|
||||||
.env
|
.env
|
||||||
|
docs/wireframe.assets/*.excalidraw.svg
|
||||||
|
docs/wireframe.assets/*.svg
|
||||||
|
node_modules/
|
|
@ -1,6 +1,6 @@
|
||||||
# pdf_signature
|
# pdf_signature
|
||||||
|
|
||||||
A GUI app to create a signature on PDF page interactively.
|
A GUI app to create signatures on PDF pages interactively.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ flutter pub get
|
||||||
# generate gherkin test
|
# generate gherkin test
|
||||||
flutter pub run build_runner build --delete-conflicting-outputs
|
flutter pub run build_runner build --delete-conflicting-outputs
|
||||||
# dart run tool/prune_unused_steps.dart --delete
|
# dart run tool/prune_unused_steps.dart --delete
|
||||||
|
# dart run tool/gen_view_wireframe_md.dart
|
||||||
|
|
||||||
# run the app
|
# run the app
|
||||||
flutter run
|
flutter run
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,981 @@
|
||||||
|
{
|
||||||
|
"type": "excalidraw",
|
||||||
|
"version": 2,
|
||||||
|
"source": "https://marketplace.visualstudio.com/items?itemName=pomdtr.excalidraw-editor",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"id": "RJI8QD55RACPAUCo2GKoo",
|
||||||
|
"type": "rectangle",
|
||||||
|
"x": -140.36046055385032,
|
||||||
|
"y": 11.486575452108639,
|
||||||
|
"width": 186.65359497070312,
|
||||||
|
"height": 588.3137512207032,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"zR9PoqVUXJn-p5Me-QWmK"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "Zy",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 230239768,
|
||||||
|
"version": 198,
|
||||||
|
"versionNonce": 1765613558,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647250652,
|
||||||
|
"link": null,
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VWdv1VE8pzad1EwZuyYgo",
|
||||||
|
"type": "text",
|
||||||
|
"x": -131.31221189953033,
|
||||||
|
"y": 29.35618978076525,
|
||||||
|
"width": 125.17988586425781,
|
||||||
|
"height": 27,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"zR9PoqVUXJn-p5Me-QWmK"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "Zz",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 530295576,
|
||||||
|
"version": 153,
|
||||||
|
"versionNonce": 748520042,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647250652,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "Recents PDFs",
|
||||||
|
"fontSize": 20,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "Recents PDFs",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "WKRHjAMR0he0xqbtoR-bH",
|
||||||
|
"type": "rectangle",
|
||||||
|
"x": 0.024998256138360375,
|
||||||
|
"y": 98.93073527018237,
|
||||||
|
"width": 741.8097795758928,
|
||||||
|
"height": 474.05282317979203,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "a0",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 1506495512,
|
||||||
|
"version": 111,
|
||||||
|
"versionNonce": 657893430,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647231508,
|
||||||
|
"link": null,
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "gtEzgCZGX1lFA4HjD_xY_",
|
||||||
|
"type": "text",
|
||||||
|
"x": 87.19040296469939,
|
||||||
|
"y": 121.50467923112484,
|
||||||
|
"width": 84.4264505231206,
|
||||||
|
"height": 30.474824347272346,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "a1",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 532285720,
|
||||||
|
"version": 103,
|
||||||
|
"versionNonce": 1545526134,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "Settings",
|
||||||
|
"fontSize": 22.57394396094248,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "Settings",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "pGsYJy75OHZYTrkjzSwnf",
|
||||||
|
"type": "text",
|
||||||
|
"x": 707.9738618906175,
|
||||||
|
"y": 115.86119324088922,
|
||||||
|
"width": 12.189847070657128,
|
||||||
|
"height": 27.42734191254511,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#111827",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "a2",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 315172376,
|
||||||
|
"version": 103,
|
||||||
|
"versionNonce": 510082794,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "×",
|
||||||
|
"fontSize": 20.31654956484823,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "×",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "blOqLsCAyD5v2UW23ped-",
|
||||||
|
"type": "text",
|
||||||
|
"x": 87.19040296469939,
|
||||||
|
"y": 166.65256715300978,
|
||||||
|
"width": 72.38740412180704,
|
||||||
|
"height": 27.42734191254511,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#111827",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "a3",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 1877779224,
|
||||||
|
"version": 103,
|
||||||
|
"versionNonce": 1306524854,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "General",
|
||||||
|
"fontSize": 20.31654956484823,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "General",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "de3wHTnwHHk_Sj716L0AD",
|
||||||
|
"type": "text",
|
||||||
|
"x": 109.76434692564192,
|
||||||
|
"y": 200.51348309442352,
|
||||||
|
"width": 84.84209960420075,
|
||||||
|
"height": 24.379859477817877,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#374151",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "a4",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 899186712,
|
||||||
|
"version": 103,
|
||||||
|
"versionNonce": 2108936618,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "Language:",
|
||||||
|
"fontSize": 18.059155168753982,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "Language:",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "u274PAAExIXPOY5MjR_Sl",
|
||||||
|
"type": "rectangle",
|
||||||
|
"x": 233.92103871082554,
|
||||||
|
"y": 191.48390551004653,
|
||||||
|
"width": 338.60915941413714,
|
||||||
|
"height": 36.118310337507964,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#6b7280",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "a5",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 1942011160,
|
||||||
|
"version": 101,
|
||||||
|
"versionNonce": 1164637686,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d97Kf0eOcwYJybE20fjfu",
|
||||||
|
"type": "text",
|
||||||
|
"x": 86.99933596770336,
|
||||||
|
"y": 269.5432989464112,
|
||||||
|
"width": 69.07583451216198,
|
||||||
|
"height": 27.42734191254511,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#111827",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "a6",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 467229208,
|
||||||
|
"version": 112,
|
||||||
|
"versionNonce": 1398803562,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "Display",
|
||||||
|
"fontSize": 20.31654956484823,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "Display",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "M1joCnME850ZafH3FL-E_",
|
||||||
|
"type": "text",
|
||||||
|
"x": 109.57327992864577,
|
||||||
|
"y": 303.40421488782493,
|
||||||
|
"width": 60.91367078245484,
|
||||||
|
"height": 24.379859477817877,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#374151",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "a7",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 1356224280,
|
||||||
|
"version": 112,
|
||||||
|
"versionNonce": 465880886,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "Theme:",
|
||||||
|
"fontSize": 18.059155168753982,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "Theme:",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8Mp1jT3NSsibB3kogMubl",
|
||||||
|
"type": "rectangle",
|
||||||
|
"x": 233.9110668529509,
|
||||||
|
"y": 279.88530391848326,
|
||||||
|
"width": 338.60915941413714,
|
||||||
|
"height": 36.118310337507964,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#6b7280",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "a8",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 925611032,
|
||||||
|
"version": 114,
|
||||||
|
"versionNonce": 87486250,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "P2kfltnFMgp1Hpns5eRsk",
|
||||||
|
"type": "text",
|
||||||
|
"x": 109.57327992864577,
|
||||||
|
"y": 337.2651308292386,
|
||||||
|
"width": 88.30944720085046,
|
||||||
|
"height": 24.379859477817877,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#374151",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "a9",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 1154314520,
|
||||||
|
"version": 112,
|
||||||
|
"versionNonce": 1095921782,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "Page view:",
|
||||||
|
"fontSize": 18.059155168753982,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "Page view:",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "vmM82c6vkYHi9E8_orBEx",
|
||||||
|
"type": "rectangle",
|
||||||
|
"x": 233.72997171382946,
|
||||||
|
"y": 328.23555324486165,
|
||||||
|
"width": 338.60915941413714,
|
||||||
|
"height": 36.118310337507964,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#6b7280",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "aA",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 288329240,
|
||||||
|
"version": 110,
|
||||||
|
"versionNonce": 128154090,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Q0v5ejctIV2msui0iDFEg",
|
||||||
|
"type": "rectangle",
|
||||||
|
"x": 414.5125903983653,
|
||||||
|
"y": 505.261726567147,
|
||||||
|
"width": 124.15669178518363,
|
||||||
|
"height": 40.63309912969646,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1f2937",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "aB",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 625347352,
|
||||||
|
"version": 101,
|
||||||
|
"versionNonce": 1373172150,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "QSD6mQUNvCKRLZtin0AHX",
|
||||||
|
"type": "text",
|
||||||
|
"x": 442.73002034954345,
|
||||||
|
"y": 514.291304151524,
|
||||||
|
"width": 55.13471219456543,
|
||||||
|
"height": 24.379859477817877,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1f2937",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "aC",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 1267001368,
|
||||||
|
"version": 103,
|
||||||
|
"versionNonce": 162573482,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "Cancel",
|
||||||
|
"fontSize": 18.059155168753982,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "Cancel",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fmP0hKBOaNa5Ge12TEwyD",
|
||||||
|
"type": "rectangle",
|
||||||
|
"x": 561.2432261444915,
|
||||||
|
"y": 505.261726567147,
|
||||||
|
"width": 146.7306357461261,
|
||||||
|
"height": 40.63309912969646,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1f2937",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "aD",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 1608525080,
|
||||||
|
"version": 101,
|
||||||
|
"versionNonce": 679299830,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "iXKBOvEPDEax0jv78PxKB",
|
||||||
|
"type": "text",
|
||||||
|
"x": 601.8763252741879,
|
||||||
|
"y": 514.291304151524,
|
||||||
|
"width": 39.54961113185798,
|
||||||
|
"height": 24.379859477817877,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1f2937",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"nQmqS53zA9IffPy8AAZwV"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "aE",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 533447192,
|
||||||
|
"version": 103,
|
||||||
|
"versionNonce": 554272618,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647235527,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "Save",
|
||||||
|
"fontSize": 18.059155168753982,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "Save",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "NjGNkNhtOARJpj03cEb51",
|
||||||
|
"type": "rectangle",
|
||||||
|
"x": -158.10173397972483,
|
||||||
|
"y": 0.8265845889135903,
|
||||||
|
"width": 992.4998779296876,
|
||||||
|
"height": 609.8372192382812,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "aF",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 668606488,
|
||||||
|
"version": 100,
|
||||||
|
"versionNonce": 1234867048,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647200609,
|
||||||
|
"link": null,
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bb7EhwFW0ROfjqxlOkqmm",
|
||||||
|
"type": "rectangle",
|
||||||
|
"x": -155.50977434430797,
|
||||||
|
"y": -69.53801908947162,
|
||||||
|
"width": 1000,
|
||||||
|
"height": 60,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"lHEbf-Drffn9NvXktYUuc"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "aG",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 1825463576,
|
||||||
|
"version": 115,
|
||||||
|
"versionNonce": 1176442904,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647163877,
|
||||||
|
"link": null,
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D19DG1HUQ57QlAvyGFl0V",
|
||||||
|
"type": "text",
|
||||||
|
"x": -135.50977434430797,
|
||||||
|
"y": -51.53801908947162,
|
||||||
|
"width": 157.46356201171875,
|
||||||
|
"height": 32.400000000000006,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"lHEbf-Drffn9NvXktYUuc"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "aH",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 1647507992,
|
||||||
|
"version": 132,
|
||||||
|
"versionNonce": 1739871512,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647163877,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "PDF Signature",
|
||||||
|
"fontSize": 24,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "PDF Signature",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PdeNL3GtypJzGH5vBfCOZ",
|
||||||
|
"type": "rectangle",
|
||||||
|
"x": 698.590328156002,
|
||||||
|
"y": -58.47743923701887,
|
||||||
|
"width": 131.2138027615017,
|
||||||
|
"height": 39.35548782348633,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"WavtKMDY86ikKkLfh5Q4r",
|
||||||
|
"lHEbf-Drffn9NvXktYUuc"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "aI",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 1526462232,
|
||||||
|
"version": 123,
|
||||||
|
"versionNonce": 2107240984,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647163877,
|
||||||
|
"link": null,
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "RzeDdJRNeKB2rEjlgqsfH",
|
||||||
|
"type": "text",
|
||||||
|
"x": 708.3768426804317,
|
||||||
|
"y": -51.69536051674481,
|
||||||
|
"width": 22.298202514648448,
|
||||||
|
"height": 32.400000000000006,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"WavtKMDY86ikKkLfh5Q4r",
|
||||||
|
"lHEbf-Drffn9NvXktYUuc"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "aJ",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 731730968,
|
||||||
|
"version": 125,
|
||||||
|
"versionNonce": 1589899032,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647163877,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "⚙",
|
||||||
|
"fontSize": 24,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "⚙",
|
||||||
|
"autoResize": false,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "hdqpl5nHgrXR_nhbDZDQ-",
|
||||||
|
"type": "text",
|
||||||
|
"x": 732.9285582285077,
|
||||||
|
"y": -50.26236931482936,
|
||||||
|
"width": 87.77992248535156,
|
||||||
|
"height": 27,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"WavtKMDY86ikKkLfh5Q4r",
|
||||||
|
"lHEbf-Drffn9NvXktYUuc"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "aK",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 2047545624,
|
||||||
|
"version": 125,
|
||||||
|
"versionNonce": 1671842840,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647163877,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "Configure",
|
||||||
|
"fontSize": 20,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "Configure",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "iIDobnzWCl-gygCOsA73n",
|
||||||
|
"type": "rectangle",
|
||||||
|
"x": 576.109131998714,
|
||||||
|
"y": -56.43111661983278,
|
||||||
|
"width": 109.23454710748254,
|
||||||
|
"height": 36.33306860750372,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"2xO--DSh2411Pyp1YG0B4"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "ac",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 1897278824,
|
||||||
|
"version": 221,
|
||||||
|
"versionNonce": 536065304,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647186276,
|
||||||
|
"link": null,
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "rectangle",
|
||||||
|
"version": 825,
|
||||||
|
"versionNonce": 921522712,
|
||||||
|
"isDeleted": false,
|
||||||
|
"id": "rumws8Xb5KM1-COUn-SjA",
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"angle": 0,
|
||||||
|
"x": 588.2383018113569,
|
||||||
|
"y": -45.08971236581036,
|
||||||
|
"strokeColor": "#000000",
|
||||||
|
"backgroundColor": "#868e96",
|
||||||
|
"width": 22.637490885793227,
|
||||||
|
"height": 13.582494531475936,
|
||||||
|
"seed": 331104360,
|
||||||
|
"groupIds": [
|
||||||
|
"1FZGUtYp_0lg0mZX7lxmQ",
|
||||||
|
"2xO--DSh2411Pyp1YG0B4"
|
||||||
|
],
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647186276,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"index": "ad",
|
||||||
|
"frameId": null,
|
||||||
|
"roundness": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "line",
|
||||||
|
"version": 842,
|
||||||
|
"versionNonce": 1454067480,
|
||||||
|
"isDeleted": false,
|
||||||
|
"id": "l8Hqi6JegDC-MxE036F3N",
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"angle": 0,
|
||||||
|
"x": 601.8207963428326,
|
||||||
|
"y": -45.08971236581036,
|
||||||
|
"strokeColor": "#000000",
|
||||||
|
"backgroundColor": "#868e96",
|
||||||
|
"width": 13.582494531475936,
|
||||||
|
"height": 4.5274981771586456,
|
||||||
|
"seed": 1042805608,
|
||||||
|
"groupIds": [
|
||||||
|
"1FZGUtYp_0lg0mZX7lxmQ",
|
||||||
|
"2xO--DSh2411Pyp1YG0B4"
|
||||||
|
],
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647186276,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"startBinding": null,
|
||||||
|
"endBinding": null,
|
||||||
|
"lastCommittedPoint": null,
|
||||||
|
"startArrowhead": null,
|
||||||
|
"endArrowhead": null,
|
||||||
|
"points": [
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-4.5274981771586456,
|
||||||
|
-4.5274981771586456
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-13.582494531475934,
|
||||||
|
-4.527498177158644
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-13.582494531475936,
|
||||||
|
-8.881784197001252e-16
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"index": "ae",
|
||||||
|
"frameId": null,
|
||||||
|
"roundness": null,
|
||||||
|
"polygon": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C8V0VrPmqft0_wEEXIh2G",
|
||||||
|
"type": "text",
|
||||||
|
"x": 624.1500441133635,
|
||||||
|
"y": -52.606675675678645,
|
||||||
|
"width": 49.27995300292969,
|
||||||
|
"height": 27,
|
||||||
|
"angle": 0,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"groupIds": [
|
||||||
|
"2xO--DSh2411Pyp1YG0B4"
|
||||||
|
],
|
||||||
|
"frameId": null,
|
||||||
|
"index": "af",
|
||||||
|
"roundness": null,
|
||||||
|
"seed": 648365672,
|
||||||
|
"version": 132,
|
||||||
|
"versionNonce": 664906776,
|
||||||
|
"isDeleted": false,
|
||||||
|
"boundElements": [],
|
||||||
|
"updated": 1756647186276,
|
||||||
|
"link": null,
|
||||||
|
"locked": false,
|
||||||
|
"text": "Open",
|
||||||
|
"fontSize": 20,
|
||||||
|
"fontFamily": 6,
|
||||||
|
"textAlign": "left",
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"containerId": null,
|
||||||
|
"originalText": "Open",
|
||||||
|
"autoResize": true,
|
||||||
|
"lineHeight": 1.35
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"appState": {
|
||||||
|
"gridSize": 20,
|
||||||
|
"gridStep": 5,
|
||||||
|
"gridModeEnabled": false,
|
||||||
|
"viewBackgroundColor": "#ffffff"
|
||||||
|
},
|
||||||
|
"files": {}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,69 @@
|
||||||
|
# Wireframes
|
||||||
|
|
||||||
|
This document contains the product wireframes drawn in Excalidraw. The editable sources live under `docs/wireframe.assets/*.excalidraw`. For easy viewing, we generate an SVG-based copy at `docs/.wireframe.md`.
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Note: `.excalidraw.svg` is a special Excalidraw-flavored SVG. We keep `.excalidraw` as the editable source and export to `.svg` for documentation preview.
|
||||||
|
Refs:
|
||||||
|
- https://github.com/excalidraw/excalidraw
|
||||||
|
- https://github.com/excalidraw/svg-to-excalidraw
|
||||||
|
-->
|
||||||
|
|
||||||
|
## 1 Welcome / First screen
|
||||||
|
|
||||||
|
Purpose: let the user open a PDF quickly via drag & drop or file picker.
|
||||||
|
Route: root
|
||||||
|
|
||||||
|
Design notes:
|
||||||
|
- Central drop zone with hint text: “Drag a PDF here or click to select”.
|
||||||
|
- Minimal top bar with app name and a gear icon for settings.
|
||||||
|
- Clean layout encouraging first action.
|
||||||
|
|
||||||
|
Illustration:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 1-Settings dialog
|
||||||
|
|
||||||
|
Purpose: provide basic configuration before/after opening a PDF.
|
||||||
|
Route: root --> settings
|
||||||
|
|
||||||
|
Design notes:
|
||||||
|
- Opened via gear icon in the top bar.
|
||||||
|
- Modal with simple sections (e.g., General, Display).
|
||||||
|
- Primary action to save, secondary to cancel.
|
||||||
|
|
||||||
|
Illustration:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## PDF opened
|
||||||
|
|
||||||
|
Purpose: view and navigate the PDF; prepare for signature placement.
|
||||||
|
Route: root --> opened
|
||||||
|
|
||||||
|
Design notes:
|
||||||
|
- Main canvas shows the current page.
|
||||||
|
- Navigation: previous/next page, zoom controls near the canvas.
|
||||||
|
- Space reserved for a future “Sign” tool in the toolbar.
|
||||||
|
- drag signature onto page
|
||||||
|
|
||||||
|
Illustration:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How to view and export
|
||||||
|
|
||||||
|
We keep links in this file pointing to `.excalidraw`. To preview the SVGs and generate `docs/.wireframe.md` with `.svg` links, run from repo root:
|
||||||
|
|
||||||
|
dart run tool/gen_view_wireframe_md.dart
|
||||||
|
|
||||||
|
This will:
|
||||||
|
- Copy `docs/wireframe.md` to `docs/.wireframe.md` and rewrite image links to `.svg`.
|
||||||
|
- Export any `*.excalidraw` under `docs/` to `*.svg` if they are new or modified.
|
||||||
|
|
||||||
|
## Next wireframes (optional)
|
||||||
|
|
||||||
|
- Save/Export result dialog and success state.
|
|
@ -0,0 +1,115 @@
|
||||||
|
// The script will
|
||||||
|
// 1. Copy `docs/wireframe.md` to `docs/.wireframe.md`.
|
||||||
|
// 2. In `docs/.wireframe.md`, replace all `*.excalidraw` paths (excluding `*.excalidraw.svg`)
|
||||||
|
// to use the `.svg` extension.
|
||||||
|
// 3. Export `*.excalidraw` files to svg `*.svg` by
|
||||||
|
// `npx --no-install excalidraw-to-svg {file_path}.excalidraw`.
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
void main(List<String> args) async {
|
||||||
|
final cwd = Directory.current;
|
||||||
|
final docsDir = Directory('${cwd.path}/docs');
|
||||||
|
final sourceMd = File('${docsDir.path}/wireframe.md');
|
||||||
|
final targetMd = File('${docsDir.path}/.wireframe.md');
|
||||||
|
|
||||||
|
if (!await docsDir.exists()) {
|
||||||
|
stderr.writeln('docs directory not found at: ${docsDir.path}');
|
||||||
|
exitCode = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!await sourceMd.exists()) {
|
||||||
|
stderr.writeln('Source markdown not found: ${sourceMd.path}');
|
||||||
|
exitCode = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1) Copy wireframe.md to .wireframe.md (overwrite to keep it up-to-date)
|
||||||
|
stdout.writeln('Copying ${sourceMd.path} -> ${targetMd.path}');
|
||||||
|
await targetMd.writeAsBytes(await sourceMd.readAsBytes(), flush: true);
|
||||||
|
|
||||||
|
// 2) Replace *.excalidraw (not already followed by .svg) with *.svg in the copied markdown
|
||||||
|
final content = await targetMd.readAsString();
|
||||||
|
final replaced = content.replaceAll(RegExp(r"\.excalidraw(?!\.svg)"), '.svg');
|
||||||
|
if (replaced != content) {
|
||||||
|
stdout.writeln('Updating links in ${targetMd.path} to use .svg');
|
||||||
|
await targetMd.writeAsString(replaced);
|
||||||
|
} else {
|
||||||
|
stdout.writeln('No link updates needed in ${targetMd.path}');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) Find all *.excalidraw files under docs and export to *.svg using excalidraw-to-svg
|
||||||
|
stdout.writeln('Scanning for .excalidraw assets under ${docsDir.path}');
|
||||||
|
final excalidrawFiles = <File>[];
|
||||||
|
await for (final entity in docsDir.list(
|
||||||
|
recursive: true,
|
||||||
|
followLinks: false,
|
||||||
|
)) {
|
||||||
|
if (entity is File && entity.path.endsWith('.excalidraw')) {
|
||||||
|
excalidrawFiles.add(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (excalidrawFiles.isEmpty) {
|
||||||
|
stdout.writeln('No .excalidraw files found. Done.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify npx availability; if missing, skip export with a clear message.
|
||||||
|
bool hasNpx = false;
|
||||||
|
try {
|
||||||
|
final npxCheck = await Process.run(
|
||||||
|
'npx',
|
||||||
|
['--version'],
|
||||||
|
runInShell: true,
|
||||||
|
workingDirectory: cwd.path,
|
||||||
|
);
|
||||||
|
hasNpx = npxCheck.exitCode == 0;
|
||||||
|
} catch (_) {
|
||||||
|
hasNpx = false;
|
||||||
|
}
|
||||||
|
if (!hasNpx) {
|
||||||
|
stderr.writeln(
|
||||||
|
'npx not found. Skipping SVG export. Install Node.js (npx) and ensure excalidraw-to-svg is available locally.',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exported = 0;
|
||||||
|
for (final src in excalidrawFiles) {
|
||||||
|
final destPath = src.path.replaceFirst(RegExp(r'\.excalidraw$'), '.svg');
|
||||||
|
final dest = File(destPath);
|
||||||
|
|
||||||
|
// Skip if up-to-date
|
||||||
|
if (await dest.exists()) {
|
||||||
|
try {
|
||||||
|
final srcStat = await src.stat();
|
||||||
|
final destStat = await dest.stat();
|
||||||
|
if (!srcStat.modified.isAfter(destStat.modified)) {
|
||||||
|
stdout.writeln('Skip (up-to-date): ${dest.path}');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
// If stats fail, proceed to export
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout.writeln('Exporting to SVG via excalidraw-to-svg: ${src.path}');
|
||||||
|
final result = await Process.run(
|
||||||
|
'npx',
|
||||||
|
['--no-install', 'excalidraw-to-svg', src.path],
|
||||||
|
runInShell: true,
|
||||||
|
workingDirectory: cwd.path,
|
||||||
|
);
|
||||||
|
if (result.exitCode == 0) {
|
||||||
|
stdout.writeln('Exported: ${dest.path}');
|
||||||
|
exported++;
|
||||||
|
} else {
|
||||||
|
stderr.writeln(
|
||||||
|
'Failed to export ${src.path} -> ${dest.path}\n${result.stderr}\n${result.stdout}',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout.writeln('Completed. ${exported} file(s) exported.');
|
||||||
|
}
|
Loading…
Reference in New Issue