From 8f772673f90b35eebf5764eef0fdac674a3ba0cb Mon Sep 17 00:00:00 2001 From: Asger Geel Weirsoee Date: Sun, 1 Mar 2026 21:54:32 +0000 Subject: [PATCH] feat(issue-222): wire angular host/player i18n to backend shell locale --- .../app/features/host/host-shell.component.ts | 2 +- .../features/player/player-shell.component.ts | 2 +- frontend/angular/src/app/lobby-i18n.spec.ts | 16 ++++++++++++++++ frontend/angular/src/app/lobby-i18n.ts | 5 ++++- lobby/templates/lobby/spa_shell.html | 6 +++--- lobby/ui_views.py | 3 ++- shared/i18n/lobby.json | 8 ++++++++ 7 files changed, 35 insertions(+), 7 deletions(-) diff --git a/frontend/angular/src/app/features/host/host-shell.component.ts b/frontend/angular/src/app/features/host/host-shell.component.ts index f9d8c72..59087b0 100644 --- a/frontend/angular/src/app/features/host/host-shell.component.ts +++ b/frontend/angular/src/app/features/host/host-shell.component.ts @@ -55,7 +55,7 @@ type LeaderboardResponse = FinishGameResponse;
{{ scoreboardPayload }}

{{ copy('host.final_leaderboard') }}

-

{{ copy('host.winner') }}: {{ finalWinner.nickname }} ({{ finalWinner.score }} pts)

+

{{ copy('host.winner') }}: {{ finalWinner.nickname }} ({{ finalWinner.score }} {{ copy('common.points_short') }})

  1. {{ entry.nickname }}: {{ entry.score }}
diff --git a/frontend/angular/src/app/features/player/player-shell.component.ts b/frontend/angular/src/app/features/player/player-shell.component.ts index 8f0015a..1d5f16c 100644 --- a/frontend/angular/src/app/features/player/player-shell.component.ts +++ b/frontend/angular/src/app/features/player/player-shell.component.ts @@ -255,7 +255,7 @@ export class PlayerShellComponent implements OnInit, OnDestroy { if (error instanceof Error && error.message) { return error.message; } - return 'Unknown error'; + return this.copy('common.unknown_error'); } private markOnline(): void { diff --git a/frontend/angular/src/app/lobby-i18n.spec.ts b/frontend/angular/src/app/lobby-i18n.spec.ts index a9ed37b..d0d17ff 100644 --- a/frontend/angular/src/app/lobby-i18n.spec.ts +++ b/frontend/angular/src/app/lobby-i18n.spec.ts @@ -45,6 +45,22 @@ describe('lobby i18n locale propagation', () => { expect(updates).toEqual(['en', 'da']); }); + it('prefers backend-provided shell locale over browser defaults', async () => { + vi.stubGlobal('window', { + location: { search: '' }, + localStorage: storageMock(), + }); + vi.stubGlobal('document', { + body: { dataset: { wppLocale: 'da' } }, + querySelector: vi.fn(() => null), + }); + vi.stubGlobal('navigator', { language: 'en-US' }); + + const i18n = await import('./lobby-i18n'); + + expect(i18n.resolvePreferredLocale()).toBe('da'); + }); + it('falls back to default en translation when da key is intentionally missing', async () => { vi.stubGlobal('window', { location: { search: '' }, diff --git a/frontend/angular/src/app/lobby-i18n.ts b/frontend/angular/src/app/lobby-i18n.ts index 1637560..9011691 100644 --- a/frontend/angular/src/app/lobby-i18n.ts +++ b/frontend/angular/src/app/lobby-i18n.ts @@ -32,11 +32,14 @@ export function resolvePreferredLocale(): SupportedLocale { return activeLocale; } + const rootLocale = + typeof document !== 'undefined' ? document.querySelector('app-root')?.dataset?.['wppLocale'] : null; + const shellLocale = typeof document !== 'undefined' ? document.body?.dataset?.['wppLocale'] : null; const queryLocale = new URLSearchParams(window.location?.search ?? '').get('lang'); const storedLocale = window.localStorage?.getItem?.('wpp.locale'); const browserLocale = typeof navigator !== 'undefined' ? navigator.language : ''; - activeLocale = normalizeLocale(queryLocale || storedLocale || browserLocale || DEFAULT_LOCALE); + activeLocale = normalizeLocale(rootLocale || shellLocale || queryLocale || storedLocale || browserLocale || DEFAULT_LOCALE); return activeLocale; } diff --git a/lobby/templates/lobby/spa_shell.html b/lobby/templates/lobby/spa_shell.html index 7846c7a..fb51798 100644 --- a/lobby/templates/lobby/spa_shell.html +++ b/lobby/templates/lobby/spa_shell.html @@ -1,13 +1,13 @@ - + WPP SPA Shell - - Indlæser Angular app-shell… + + Indlæser Angular app-shell… diff --git a/lobby/ui_views.py b/lobby/ui_views.py index c7531d9..c1d2fcb 100644 --- a/lobby/ui_views.py +++ b/lobby/ui_views.py @@ -5,7 +5,7 @@ from django.shortcuts import render from fupogfakta.models import Category from .feature_flags import use_spa_ui -from .i18n import lobby_i18n_catalog +from .i18n import lobby_i18n_catalog, resolve_locale def _render_spa_shell(request, shell_route: str, shell_kind: str): @@ -18,6 +18,7 @@ def _render_spa_shell(request, shell_route: str, shell_kind: str): "spa_asset_base": settings.WPP_SPA_ASSET_BASE, "spa_asset_version": getattr(settings, "WPP_SPA_ASSET_VERSION", "dev"), "lobby_i18n": lobby_i18n_catalog(), + "shell_locale": resolve_locale(request), }, ) diff --git a/shared/i18n/lobby.json b/shared/i18n/lobby.json index c02c50c..2fb4e32 100644 --- a/shared/i18n/lobby.json +++ b/shared/i18n/lobby.json @@ -74,6 +74,14 @@ "round": { "en": "round", "da": "runde" + }, + "points_short": { + "en": "pts", + "da": "point" + }, + "unknown_error": { + "en": "Unknown error", + "da": "Ukendt fejl" } }, "app": {