The project is no longer a monorepo/workspace - there is only a single
app package. Remove the redundant client/ nesting: all source, the
Capacitor Android project, config files and package.json/tsconfig now
live directly at the repo root.
- Merge client/package.json into root package.json (drop the
workspaces field and the now-unnecessary bun --cwd client wrappers).
- Merge client/bun.lock (the actual dependency lockfile) into the
root, replacing the stale workspace-only root lockfile.
- Move src/, public/, android/, index.html, vite.config.ts,
capacitor.config.ts, tsconfig.{app,node}.json to the repo root.
- Update Dockerfile.android to build from the repo root instead of
cd'ing into client/.
- Update .github/workflows/ci.yml type-check step to run bun run build
directly instead of bun --cwd client run build.
- Update README.md and .github/copilot-instructions.md to drop
references to the client/ subdirectory.
- Drop the stale server/downloads/ entry from .gitignore (leftover
from an old server-based architecture that no longer exists).
90 lines
4.0 KiB
Markdown
90 lines
4.0 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
|
|
|
|
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://<host-ip>: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`.
|