The self-hosted Windows runner can't reach github.com (GFW), so the previous workflow failed cloning actions/checkout and would also fail downloading the Flutter SDK and the sqlite3 native binary. - Vendor the official, SHA-256-verified sqlite3 binaries under vendor/sqlite3/ and select them via pubspec hooks.user_defines (source: test-sqlite3). Builds and tests now run fully offline — no GitHub download, no proxy, no LD_LIBRARY_PATH hack (removed .local-sqlite/). - Consolidate CI into one Windows workflow: fetch actions from the gitea.com mirror, use the runner's pre-installed Flutter (no SDK download), and use the flutter-io.cn pub/Flutter mirrors. Server tests use the Tsinghua PyPI mirror. - Document the offline build + China mirrors in README. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
85 lines
2.9 KiB
Markdown
85 lines
2.9 KiB
Markdown
# BadNote
|
|
|
|
Local-first Surface Pen note-taking app with PDF/PPT annotation.
|
|
|
|
All notes, documents, search, and OCR run on your device. No server is required to use the app.
|
|
|
|
## Features
|
|
|
|
- Ink notes with Surface Pen (pressure, stabilizer, undo/redo)
|
|
- PDF and PPT import with page-level annotation
|
|
- Full-text search over note titles, typed text, and OCR results
|
|
- **Local OCR** — handwriting recognition via Windows built-in OCR (Windows desktop)
|
|
|
|
## Build (Windows)
|
|
|
|
Prerequisites:
|
|
|
|
- Flutter SDK (3.10+)
|
|
- Visual Studio Build Tools with **Desktop development with C++**
|
|
- Developer Mode enabled (for Flutter plugin symlinks)
|
|
|
|
```powershell
|
|
flutter pub get
|
|
flutter build windows --release
|
|
```
|
|
|
|
Output: `build\windows\x64\runner\Release\badnote.exe`
|
|
|
|
The `sqlite3` native binary is **vendored** under `vendor/sqlite3/` (configured via
|
|
`hooks.user_defines` in `pubspec.yaml`), so the build does not download anything
|
|
from GitHub — it works fully offline / behind a firewall. To add another
|
|
platform or architecture, drop its official release binary from
|
|
[sqlite3.dart releases](https://github.com/simolus3/sqlite3.dart/releases) into
|
|
`vendor/sqlite3/` (the build validates each file's SHA-256).
|
|
|
|
In mainland China, point pub/Flutter at the local mirrors:
|
|
|
|
```powershell
|
|
$env:PUB_HOSTED_URL="https://pub.flutter-io.cn"
|
|
$env:FLUTTER_STORAGE_BASE_URL="https://storage.flutter-io.cn"
|
|
flutter pub get
|
|
flutter build windows --release
|
|
```
|
|
|
|
## Continuous integration
|
|
|
|
`.gitea/workflows/ci.yml` runs format + analyze + test + Windows release build on
|
|
a self-hosted **Windows** runner. It is written for runners behind the GFW:
|
|
actions come from the `gitea.com` mirror, Flutter is expected to be
|
|
pre-installed on the runner, and pub uses the `flutter-io.cn` mirror. If
|
|
`gitea.com` is unreachable too, set `DEFAULT_ACTIONS_URL=https://gitea.com` (or
|
|
your own mirror) in the runner config and use bare `actions/checkout@v4`.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
lib/
|
|
├── screens/ # UI (notes, PDF/PPT annotator, search, settings)
|
|
├── services/ # Local business logic
|
|
│ ├── database_service.dart # SQLite + FTS5
|
|
│ ├── ocr_service.dart # Local OCR orchestration
|
|
│ ├── stroke_rasterizer.dart # Ink → PNG for OCR
|
|
│ └── ocr_engine.dart # Platform OCR bridge
|
|
├── providers/ # Riverpod state
|
|
└── widgets/ # Ink canvas, toolbars, thumbnails
|
|
```
|
|
|
|
OCR flow on save:
|
|
|
|
1. Extract typed text from text-tool strokes
|
|
2. Rasterize handwriting strokes to PNG
|
|
3. Run Windows OCR on the PNG
|
|
4. Merge recognized text into the local FTS index for search
|
|
|
|
## Optional server
|
|
|
|
The `server/` directory contains an experimental FastAPI backend (sync + EasyOCR). It is **not required** for the desktop app and is kept separately for future multi-device sync experiments. See [server/README.md](server/README.md).
|
|
|
|
## Development
|
|
|
|
```bash
|
|
flutter run -d windows
|
|
flutter test
|
|
```
|