* feat(sync): add per-category sync gates + Manage Sync UI
The user can now enable / disable each sync category independently
in Settings → Data Sync (User page). The map syncs across devices
via the bundled `settings` replica, defaults to enabled so the
preference is opt-out, and applies on both push (`replicaPublish`,
legacy `useSync`) and pull (`useReplicaPull`, `useSync`) without
backfilling on re-enable.
Categories:
- `book` / `progress` / `note` — gate the legacy `SyncClient` paths
- `dictionary` / `font` / `texture` / `opds_catalog` — gate the
replica-sync pulls + publishes for those kinds
- `settings` — togglable, but force-on while `dictionary` is enabled
because the dictionary's `providerOrder` / `providerEnabled` /
`webSearches` live in the bundled settings replica. The UI
shows the locked toggle as blue (enabled) with a hint instead of
greying it out, since the underlying state IS on.
UI:
- New `SyncCategoriesSection` lists every category with a
description and a daisyUI toggle.
- New `Manage Sync` blue action on the User page (second slot,
right after `Manage Subscription`); also surfaces inside the
library `Advanced Settings` menu, deep-linking via
`/user?section=sync`.
- `SyncPassphraseSection` moved into the Manage Sync panel
alongside the categories list. `Unlock now` button removed —
the gate fires automatically on first encrypted push/pull and
the manual unlock affordance was confusing.
Adjacent cleanups:
- `LangPanel` Dictionaries card gets `overflow-hidden` so the
hover highlight clips to the card's rounded corners.
- `FontPanel` gear icon replaced with a `Manage Fonts` row that
matches the `Manage Dictionaries` pattern.
i18n: extracted + translated 31 in-scope locales for the new
strings (`Manage Sync`, `Data Sync`, `Manage Fonts`, plus the
category copy block).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(i18n): translate new sync-categories strings across 30 locales
Adds translations for the four strings extracted after the latest
SyncCategoriesSection iteration:
- `App settings` — toggle label for the bundled-settings sync gate
- `Theme, highlight colours, integrations (KOSync, Readwise,
Hardcover), and dictionary order` — description under that toggle
- `Required while Dictionaries sync is enabled` — hint shown when
the toggle is locked because dictionary sync depends on settings
- `Unavailable` — `(Unavailable)` suffix on disabled translator
providers; was missing from most locales until i18next-scanner
picked it up this run
Product names (KOSync, Readwise, Hardcover) left in Latin script.
`Dictionaries` references in the third string reuse each locale's
existing translation. `pt-BR` and `uz` deliberately untouched (out
of the in-scope set).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(i18n): fill in pt-BR for the new sync-categories strings
`pt-BR` is a registered, shipped locale (Portuguese (Brasil)) that
fell through the gaps in earlier batch runs because it isn't listed
in the i18n skill's locale-reference table. The fallback chain
`pt-BR → pt → en` softened the impact, but BR-specific phrasing
needs its own translations for the 20 new keys this PR added.
`uz` stays excluded — that locale isn't registered anywhere
(missing from i18next-scanner.config.cjs, src/i18n/i18n.ts, and
TRANSLATED_LANGS), so its translation file is dead code.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(i18n): translate uz for the new sync-categories strings
`uz` is a registered locale (listed in `i18n-langs.json` and
`TRANSLATED_LANGS` as `'Oʻzbek'`) but earlier batch translation
runs excluded it because the i18n skill's static locale-reference
table was incomplete. Filling in the 20 strings this PR added.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(agent): update i18n skill
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: add passive: true to touchstart event listener when pulling to refresh
* fix: stale settings used when syncing books and move auto upload from import menu to settings menu