91 lines
4.2 KiB
Markdown
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`.
|