Files
tiptoi-sync/.github/copilot-instructions.md
T

91 lines
4.2 KiB
Markdown

# 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 `.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 (workspace uses `bun`):
```bash
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
```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://<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/*.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`.