anthodev/lapin-futepublic Fork
⑂ develop
Commits
⬇ Clone ▾
git clone https://git.rickub.com/anthodev/lapin-fute.git
git clone ssh://git@rickub.com/anthodev/lapin-fute.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

[feature] Add a configuration-page selector to override the watch app language #30

Closed@github-anthodev opened this issue Sep 19, 2026
  • @github-anthodev opened this issue · Sep 19, 2026

    Impact version

    MINOR. Add an optional user-facing setting without changing the supported languages or the watch wire protocol.


    Description

    Add a language selector to the configuration page so users can force Lapin Futé on the watch to French or English independently of the watch system language.

    Today, the companion derives the language from Pebble.getActiveWatchInfo().language. The configuration page receives that language but provides no selector, and its save payload cannot return a language preference. The phone configuration does not persist an override.


    Expected behavior

    Expose an accessible setting labelled "Watch app language", translated into French, with three choices:

    • Automatic, following the watch system language. This is the default and preserves current behavior.
    • Français, forcing French.
    • English, forcing English.

    Apply the preference through the existing Save flow. Persist it on the phone, restore it when reopening configuration, and synchronize the effective fr or en language to the watch. Selecting a value without saving must not change the active watch configuration.


    Acceptance criteria

    • The configuration page offers Automatic, Français and English through a labelled, keyboard-accessible selector usable on mobile in both existing themes.
    • Existing installations without a preference default to Automatic, preserving the current French normalization and English fallback for other or unavailable watch locales.
    • A saved explicit choice overrides the watch system language. Later system-language changes do not overwrite that choice.
    • Reopening the configuration page restores the saved choice, including the distinction between Automatic and an explicit choice matching the current system language.
    • Returning to Automatic removes the override and resolves the language from the watch at the same lifecycle points used today.
    • Saving only a language change updates the watch through the existing configuration synchronization flow. Editing favorites or credentials is not required.
    • Watch-owned copy and phone-prepared display records use the same effective language after a successful synchronization. Existing language-specific traffic caching and French translation fallback remain correct.
    • The saved choice survives companion and watch restarts. Cancelled configuration and invalid save payloads leave the previous configuration intact.
    • Configuration migration preserves favorites and the phone-local PRIM key. Older page/save payloads that omit the preference do not silently reset an existing override.
    • User-authored favorite labels, station names and other source names remain unchanged. No new translations or supported languages are introduced.
    • The selector explicitly targets the watch application. Preserve the page's existing launch-time localization behavior using the effective language; live translation of the page while editing the selector is not required.

    Affected endpoints/routes

    No new HTTP endpoint.

    • Configuration page: packages/config-page/index.html and packages/config-page/src/config-page.js.
    • Configuration launch fragment and pebblejs://close#... save payload: packages/config-page/src/config-core.js and packages/companion/src/configuration.js.
    • Companion configuration opening, save handling and synchronization: packages/companion/src/index.js.

    Tests to add

    Extend existing tests where possible. Assert observable behavior rather than control markup or internal field forwarding.

    Type Coverage
    Configuration-page unit tests Preference round-trip, missing or invalid values, preservation of Automatic versus explicit selection, save and cancellation behavior. Start with packages/config-page/test/config-page.test.ts.
    Companion unit and integration tests Migration without favorite or credential loss; persistence across restart; explicit override precedence; return to Automatic; older payload compatibility; language-only synchronization and language-specific traffic caching. Extend packages/companion/test/companion.test.js and relevant configuration suites.
    Browser smoke verification Actual mobile-sized page in French and English, keyboard operation, light/dark rendering, reopened selected value and Save payload. Desktop navigation alone does not prove delivery to the Pebble app.
    Isolated native verification Emery and Gabbro render the chosen language after a language-only save/sync and retain it after reopening. Use recorded fixtures and no live PRIM calls. Host tests alone do not certify native rendering.

    Constraints

    • Persist the preference through the companion's phone-local configuration store, not configuration-page localStorage. Keep the existing secret boundary intact.
    • Resolve Automatic on the phone. Continue sending only en or fr using the existing LANGUAGE AppMessage key 37. Do not add message IDs or change radio budgets.
    • Evolve and validate the page/phone payload and stored configuration together. Migrate prior records rather than rejecting them or discarding user data.
    • Use the existing language-aware display preparation, hashing, synchronization and cache handling. Do not implement a second localization path.
    • No polling, automatic retries, new network triggers or PRIM requests caused merely by editing the selector. Preserve the existing event-only fetching rules.
    • Do not hand-edit generated watch or configuration-page artifacts.

    Impact on existing behavior

    Automatic remains the default for existing and new users. Manual selection changes only Lapin Futé's effective application language, not the watch system settings.

    A language-only change can require re-sending display records because their hashes include the language. Reuse the current DIFF negotiation and atomic commit behavior rather than forcing a destructive FULL resynchronization.


    Technical context

    • packages/companion/src/configuration.js: normalizeLanguage and activeWatchLanguage currently resolve the watch locale. configurationPageState and configurationUrl expose it to the page, while parseCloseFragment does not accept a preference. isStoredConfiguration uses a strict allowed-key set, and recoverStoredConfiguration owns migration.
    • packages/config-page/src/config-core.js: selectLocale, copyFor and parseConfigFragment handle incoming language and page copy. packages/config-page/src/config-page.js applies that copy through applyCopy; keep the document language and localized About content consistent on reopening.
    • packages/companion/src/index.js: _onShowConfiguration, _onWebviewClosed and _sendConfiguration currently read the system language. Resolve the saved preference consistently at all three points, including language-only change detection and the fresh read before synchronization.
    • packages/companion/src/display-layout.js: prepareAppearance binds display records to their language. packages/companion/src/codec.js: encodeConfigurationStart already sends LANGUAGE.
    • packages/watch/src/embeddedjs/runtime.js: need prevents reuse of records from another language, and configCommit applies the committed language and clears stale watch traffic content. packages/watch/src/embeddedjs/storage.js already persists the effective language.

    The existing language transport and bilingual watch rendering are reusable. No new backend or catalog publication is required for this setting.

Sign in to comment.