mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-05 22:29:05 +00:00
feat: French localization — community contribution by @OUARZA (#371)
The complete French dictionary contributed in #371 (1026 keys, zero empty values, zero placeholder mismatches) lands as the second lazy locale on the fr.ts + one static entry. The contributor's snapshot predated this week's keys, so the 121 additions (device inbox #29, backdrop guard #39, junction limits #331, lazy-editor toasts #353/#354, furniture #159) are translated in this commit and flagged in the issue for the author's review; 21 stale pre-#62 keys are dropped; key order follows en.json. The HA integration translations file ships as contributed (full parity). Wiring: loadFrench + __HOUSEPLAN_FR_RETRY_ASSET__ with the same 1/1 replacement guarantee as German; locale roles and localeRoots generalise to (de|fr); the stale-entry fallback panel (#353) gains its French branch — the r1 reviewer caught that this second hardcoded language list would have silently degraded French to English on a cached entry. French profiles (fr, fr-FR, fr-CA, fr-BE, fr-CH) select automatically. Proofs: the registry-driven parity suite covers fr by construction (1128/1128 keys); French analogues of both German-personal tests (product glossary + non-translation scan with a reviewed equal-to-English allow-list of 22 legitimate homographs); smoke_french_locale — fr-CA profile commits French from the real bundle, one lazy chunk per page, initial graph free of fr; smoke_entry_stale gains the French run; a registry mutant drops the fr entry and is killed by the smoke. Initial view: +0.5 KB (registry entry + fallback branch); the 23 KB dictionary is lazy. Issue: #371 User-Visible: yes
This commit is contained in:
+1130
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
import dictionary from './fr.json' with { type: 'json' };
|
||||
|
||||
/** Must match the entry bundle before a lazy locale can be committed. */
|
||||
export const fingerprint = '__HOUSEPLAN_SOURCE_FINGERPRINT__';
|
||||
|
||||
export { dictionary };
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
|
||||
const BUILD_FINGERPRINT = '__HOUSEPLAN_SOURCE_FINGERPRINT__';
|
||||
const GERMAN_RETRY_ASSET = '__HOUSEPLAN_DE_RETRY_ASSET__';
|
||||
const FRENCH_RETRY_ASSET = '__HOUSEPLAN_FR_RETRY_ASSET__';
|
||||
|
||||
export interface LanguageEntry {
|
||||
code: string;
|
||||
@@ -24,6 +25,13 @@ async function loadGerman(attempt: 0 | 1): Promise<LazyLanguageModule> {
|
||||
return { dictionary: module.dictionary, fingerprint: module.fingerprint };
|
||||
}
|
||||
|
||||
async function loadFrench(attempt: 0 | 1): Promise<LazyLanguageModule> {
|
||||
const module = attempt === 0
|
||||
? await import('./fr')
|
||||
: await import(/* @vite-ignore */ new URL(`${FRENCH_RETRY_ASSET}?retry`, import.meta.url).href);
|
||||
return { dictionary: module.dictionary, fingerprint: module.fingerprint };
|
||||
}
|
||||
|
||||
/**
|
||||
* The single runtime registry of shipped UI languages.
|
||||
*
|
||||
@@ -34,6 +42,7 @@ export const LANGUAGE_REGISTRY = [
|
||||
{ code: 'en', nativeLabel: 'English', dictionary: en },
|
||||
{ code: 'ru', nativeLabel: 'Русский', dictionary: ru },
|
||||
{ code: 'de', nativeLabel: 'Deutsch', loadDictionary: loadGerman },
|
||||
{ code: 'fr', nativeLabel: 'Français', loadDictionary: loadFrench },
|
||||
] as const satisfies readonly LanguageEntry[];
|
||||
|
||||
export type Lang = (typeof LANGUAGE_REGISTRY)[number]['code'];
|
||||
|
||||
Reference in New Issue
Block a user