Skip to content

i18n subscribe/store plumbing and stored "locale" preference are dead code after language settings removal #64

@kmch4n

Description

@kmch4n

Summary

After bab0b45 [🔥] Remove in-app language settings, the useSyncExternalStore-based subscription system in src/i18n/ is dead code, and the locale key written to app_preferences by previous builds is now an orphan row for any user who upgrades from a build that shipped the picker.

Problem

Dead subscription plumbing

// src/i18n/index.ts:20-36
const listeners = new Set<() => void>();
const version = 0;

export function getCurrentLocale(): SupportedLocale { return currentLocale; }
export function getLocaleVersion(): number { return version; }   // never increments
export function subscribeToLocale(listener: () => void): () => void {
    listeners.add(listener);
    return () => { listeners.delete(listener); };
}

version is a const that never changes; nothing ever calls each listener (listeners is added-to but never iterated). The hook still wires through useSyncExternalStore:

// src/i18n/useTranslation.ts:24-32
const version = useSyncExternalStore(subscribeToLocale, getLocaleVersion, getLocaleVersion);
const translate = useMemo(() => {
    void version;
    return (key, params) => t(key, params);
}, [version]);

This compiles and runs fine, but it advertises a re-render pathway that does not exist. Future readers will think the locale can change at runtime.

Stale preference key

bab0b45 removed all writers and readers for the locale key, but the row may still exist in the user's SQLite for anyone who upgraded from a version that shipped the picker. There is no migration to drop it. Effects:

  • Harmless functionally, but getAllPreferences() returns it during export, mismatching the documented set of keys.
  • app_preferences debug snapshots will look puzzling to future maintainers.

Relevant files

  • src/i18n/index.ts:20-36 — dead store plumbing
  • src/i18n/useTranslation.ts:24-37 — pulls through unused subscription
  • src/database/repositories/appPreferenceRepository.ts:11-13 — surfaces the orphan row in getAllPreferences
  • src/services/exportService.ts:90-91 — bundles app_preferences into backups, so the orphan key gets re-imported on hypothetical future restore

Proposed fix

  1. In src/i18n/index.ts, drop listeners, version, getLocaleVersion, subscribeToLocale. Keep t, getCurrentLocale.
  2. In src/i18n/useTranslation.ts, replace the useSyncExternalStore with a plain useMemo (or just inline t). Same return shape { t, locale }.
  3. Add a one-shot startup cleanup (or a Drizzle data migration) that deletes app_preferences rows where key = 'locale'. Cheap to implement next to seedTechniqueOptions.

Acceptance criteria

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:data-modelDatabase schema and data modelpriority:lowLow prioritytech-debtCode health and maintainability

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions