Web: eight more UI languages behind a single language registry

Adds Swiss German, French, Italian, Dutch, Danish, Norwegian, Swedish and
Finnish — ten selectable languages, each complete at 418/418 keys with
matching placeholders and date arrays.

A language used to be registered in four unrelated places (dictionary,
settings dropdown, date-picker locale ternary, resolver fallback), so
adding one meant touching all of them. LANGUAGES in i18n.js is now the
single source of truth: adding a language is one entry plus one
dictionary, and the dropdown derives from it.

The registry also separates the stored code from the BCP-47 tag used for
formatting. That distinction is what makes 'ch' safe — "ch" is a country,
not a language, and would throw if handed to Intl; it maps to de-CH.

Fixes locale handling along the way: fmtTime/fmtDatetime in calendar.js,
month.js and week.js hardcoded 'de', so English users saw German-formatted
times, and two toLocaleDateString() calls silently used the browser locale
instead of the app language. All formatting now goes through getLocale().
Missing keys fall back language → English → German rather than straight to
German, and the dead per-dictionary `locale` key is gone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-08-06 14:58:03 +02:00
parent c632dabc31
commit a45bf6ea73
8 changed files with 3229 additions and 34 deletions

View File

@@ -1,5 +1,5 @@
import { isPast, eventTitle, birthdayIconSvg } from '../utils.js';
import { t, getLang } from '../i18n.js';
import { t, getLocale } from '../i18n.js';
export function renderAgenda(container, currentDate, events, onEventClick) {
if (!events.length) {
@@ -94,7 +94,7 @@ function isTodayDate(d) {
}
function fmtTime(d) {
return d.toLocaleTimeString(getLang(), { hour: '2-digit', minute: '2-digit' });
return d.toLocaleTimeString(getLocale(), { hour: '2-digit', minute: '2-digit' });
}
function escHtml(s) {