On-device config panel #6

Merged
365DevNet merged 0 commits from refs/pull/6/head into main 2026-07-14 19:06:48 +02:00
365DevNet commented 2026-07-14 19:04:06 +02:00 (Migrated from codeberg.org)

Finishes Phase 1: the app can now be set up on the device, instead of by hand-placing a JSON file over USB. A missing config used to print /mnt/ext1/system/config/kavita-sync.json and stop — a path you can't do anything about from the reader, which is the whole reason this phase exists.

A two-step wizard: server + credentials, then library picks. Reached by a Setup button in the header, and it opens itself on first run. A rejected key or unreachable server now offers Fix setup.

Verified on the device

  • First run opens straight into Setup. Works.
  • API-key path signs in, lists libraries, saves. Works.
  • Unticking every library disables Done and shows the hint. Works.
  • Load/unload still works; taps land on their own rows.
  • Username/password sign-in failed. See below.

Known open: the login path is the default and is unverified

Ambiguous, and deliberately not treated as 'login is broken': login() returns empty both for a 401 and for a 200 whose body lacks apiKey, and the screen prints the same message for either — so a mistyped password is indistinguishable from a bad response shape, and typing on the e-ink keyboard is what prompted the login path to begin with. scripts/probe.sh with KAVITA_USER/KAVITA_PASS settles it from the Mac in seconds. If login works: split the error messages. If not: flip the default to Mode::ApiKey, one line. Shipping as-is by choice — the device already holds a working config.

Design notes

  • SetupWizard is host-tested with no inkview and no HttpClient: the screen makes the network call and feeds results back. 52 tests run on the Mac in milliseconds; anything the host can't reach costs a Docker cross-build and a cable.
  • canFinish() lives in the wizard, not the screen, and gates both the greying of Done and its hit-test. Empty libraryIds means 'all libraries' on read, so a wizard able to save 'none' would silently sync everything. It can't.
  • Two real bugs came out of review, both originating in the plan rather than the implementation: a draw/hit-test divergence on the mode link (~40px, fixed by hoisting geometry into one shared helper), and untrimmed credentials — a trailing space passed validation, went out raw as ?apiKey=GUID%20, 401'd, and was persisted, so a correct key read as 'rejected' forever.

Three gaps deferred, recorded in the spec's Known gaps section.

Finishes Phase 1: the app can now be set up on the device, instead of by hand-placing a JSON file over USB. A missing config used to print /mnt/ext1/system/config/kavita-sync.json and stop — a path you can't do anything about from the reader, which is the whole reason this phase exists. A two-step wizard: server + credentials, then library picks. Reached by a Setup button in the header, and it opens itself on first run. A rejected key or unreachable server now offers Fix setup. ## Verified on the device - First run opens straight into Setup. Works. - API-key path signs in, lists libraries, saves. Works. - Unticking every library disables Done and shows the hint. Works. - Load/unload still works; taps land on their own rows. - **Username/password sign-in failed.** See below. ## Known open: the login path is the default and is unverified Ambiguous, and deliberately not treated as 'login is broken': login() returns empty both for a 401 and for a 200 whose body lacks apiKey, and the screen prints the same message for either — so a mistyped password is indistinguishable from a bad response shape, and typing on the e-ink keyboard is what prompted the login path to begin with. scripts/probe.sh with KAVITA_USER/KAVITA_PASS settles it from the Mac in seconds. If login works: split the error messages. If not: flip the default to Mode::ApiKey, one line. Shipping as-is by choice — the device already holds a working config. ## Design notes - SetupWizard is host-tested with no inkview and no HttpClient: the screen makes the network call and feeds results back. 52 tests run on the Mac in milliseconds; anything the host can't reach costs a Docker cross-build and a cable. - canFinish() lives in the wizard, not the screen, and gates both the greying of Done and its hit-test. Empty libraryIds means 'all libraries' on read, so a wizard able to save 'none' would silently sync everything. It can't. - Two real bugs came out of review, both originating in the plan rather than the implementation: a draw/hit-test divergence on the mode link (~40px, fixed by hoisting geometry into one shared helper), and untrimmed credentials — a trailing space passed validation, went out raw as ?apiKey=GUID%20, 401'd, and was persisted, so a correct key read as 'rejected' forever. Three gaps deferred, recorded in the spec's Known gaps section.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
365DevNet/PocketBook_Kavita_sync!6
No description provided.