# 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 This is a single SolidJS + Vite + Capacitor project (no monorepo/workspace) — all app code lives directly at the repo root. - `src/api.ts` — all "business logic": scraping Ravensburger's search API/HTML for `.gme` download 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) and `DownloadsPage.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 `.gme` files on the pen, downloading GME/cover files into app-private storage via `HttpURLConnection`. - `DevPlugin.kt` — enables Capacitor live-reload against a Vite dev server (see `DEV_URL` below). - `Dockerfile.android`, `build-apk.sh` — reproducible APK build via Docker/Podman (no local Android SDK needed). Output APK lands in `apk-output/tiptoi-sync.apk`. ## Build & dev commands Run from repo root (uses `bun`): ```bash bun install # installs deps bun run dev # starts Vite dev server with --host bun run build # tsc -b && vite build bun run cap:sync # copies web build into android/ project bun run cap:android # builds & runs on connected device/emulator ``` 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. Validate changes with `bun run build`, or `bunx tsc -b --noEmit` for a faster type-only check. ### Building the Android APK ```bash ./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 ```bash DEV_URL=http://:5173 bun run cap:android ``` `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/*.ts` must stay in sync with `@PluginMethod`/`@CapacitorPlugin` definitions 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, `.gme` stripped); covers reuse the same base name with the cover's own extension. - `syncAll` in `api.ts` is the single source of truth for "what needs copying to the pen": it diffs local downloads against `listPenFiles`.