4.2 KiB
tiptoi-sync
Android app (Capacitor + SolidJS) for searching, downloading, and syncing tiptoi
books onto a tiptoi pen. All book search/download and pen file access happens
natively on-device — there is no backend server in this repo despite what
README.md's architecture diagram describes (that README is stale/aspirational
for a self-hosted server variant; the current implementation is Android-only).
Repository layout
client/— SolidJS + Vite PWA/webview UI (workspace root's actual app code).src/api.ts— all "business logic": scraping Ravensburger's search API/HTML for.gmedownload links, orchestrating download + sync, calling the native plugin.src/native/TiptoiPlugin.ts+src/native/DevPlugin.ts— TypeScript interfaces for Capacitor native plugins (registerPlugin). Any change to the native Kotlin plugin's method signatures must be mirrored here.src/pages/—ScanPage.tsx(barcode/text search) andDownloadsPage.tsx(library + pen sync UI).android/— Capacitor Android project, checked into the repo (not generated on demand).android/app/src/main/java/com/tiptoisync/app/contains the actual native implementation:TiptoiPlugin.kt— SAF (Storage Access Framework) directory picker for the pen, listing/copying/deleting.gmefiles on the pen, downloading GME/cover files into app-private storage viaHttpURLConnection.DevPlugin.kt— enables Capacitor live-reload against a Vite dev server (seeDEV_URLbelow).
Dockerfile.android,build-apk.sh— reproducible APK build via Docker/Podman (no local Android SDK needed). Output APK lands inapk-output/tiptoi-sync.apk.
Build & dev commands
Run from repo root (workspace uses bun):
bun install # installs client workspace deps
bun run dev # starts Vite dev server (client) with --host
bun run build # tsc -b && vite build for client
bun run cap:sync # copies web build into android/ project
bun run cap:android # builds & runs on connected device/emulator
Equivalent scripts also exist directly in client/package.json (bun --cwd client run <script> or cd client && bun run <script>).
There are no unit/integration tests or linters configured in this repo — only
TypeScript's compiler (tsc -b, run as part of build) enforces correctness
on the client. Validate client changes with bun run build from the repo
root, or cd client && bunx tsc -b --noEmit for a faster type-only check.
Building the Android APK
./build-apk.sh
Wraps a multi-stage Dockerfile.android build (Bun + Android SDK + Gradle)
using Podman or Docker, with --no-cache to avoid stale layers. No local
Android SDK/Gradle install required. Result: apk-output/tiptoi-sync.apk.
Live-reload against Vite dev server on a device
DEV_URL=http://<host-ip>:5173 bun run cap:android
client/capacitor.config.ts reads DEV_URL and switches Capacitor's webview
to load from the dev server (with cleartext: true) instead of the bundled
dist/ output. DevPlugin.kt/DevPlugin.ts support activating/deactivating
this from within the running app (see DevMenu.tsx, triggered by 5 taps on
the app title within 2 seconds — see App.tsx).
Key conventions
- UI copy is German. Keep user-facing strings, comments in
api.ts, and section-divider comments (e.g.// ── Suche ──...) in German to match the existing style. - Native plugin contract: TypeScript interfaces in
src/native/*.tsmust stay in sync with@PluginMethod/@CapacitorPlugindefinitions in the corresponding Kotlin files — there's no code generation, it's manually kept in sync. - All book search scraping logic lives in
api.ts(regex-based HTML parsing of Ravensburger's site, HTML entity decoding). If Ravensburger changes their markup, this is the place to fix it. - Filenames for downloaded books derive from the last path segment of the GME
URL (decoded,
.gmestripped); covers reuse the same base name with the cover's own extension. syncAllinapi.tsis the single source of truth for "what needs copying to the pen": it diffs local downloads againstlistPenFiles.