From 5538a918007e154951a16bf4b61717610ec79f0d Mon Sep 17 00:00:00 2001 From: DEV-bot Date: Mon, 2 Mar 2026 01:01:54 +0000 Subject: [PATCH 1/2] feat(frontend): wire route locale context for host/player shells (#241) --- .../angular/src/app/session-route-context.spec.ts | 9 +++++++++ frontend/angular/src/app/session-route-context.ts | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/frontend/angular/src/app/session-route-context.spec.ts b/frontend/angular/src/app/session-route-context.spec.ts index a0fc0df..7e53b30 100644 --- a/frontend/angular/src/app/session-route-context.spec.ts +++ b/frontend/angular/src/app/session-route-context.spec.ts @@ -69,6 +69,7 @@ describe('session route context', () => { sessionCode: 'AB12', playerId: 5, token: 'tok-5', + locale: 'en', }); }); @@ -80,7 +81,15 @@ describe('session route context', () => { sessionCode: 'AB12', playerId: null, token: null, + locale: 'en', }); expect(sessionStorage.setItem).toHaveBeenCalledWith('wpp.host-session-code', 'AB12'); }); + + it('resolvers normalize and expose locale from lang query param', () => { + setWindow(storageMock(), storageMock()); + + expect(hostRouteContextResolver(route({}, { lang: 'da-DK' }) as never, {} as never).locale).toBe('da'); + expect(playerRouteContextResolver(route({}, { lang: 'EN' }) as never, {} as never).locale).toBe('en'); + }); }); diff --git a/frontend/angular/src/app/session-route-context.ts b/frontend/angular/src/app/session-route-context.ts index 449dcfb..c105ab4 100644 --- a/frontend/angular/src/app/session-route-context.ts +++ b/frontend/angular/src/app/session-route-context.ts @@ -2,11 +2,13 @@ import { inject } from '@angular/core'; import { type ActivatedRouteSnapshot, type CanActivateFn, type ResolveFn, Router, type UrlTree } from '@angular/router'; import { createSessionContextStore } from '../../../src/spa/session-context-store'; +import { normalizeLocale, setPreferredLocale } from './lobby-i18n'; export interface RouteSessionContext { sessionCode: string | null; playerId: number | null; token: string | null; + locale: string; } const HOST_STORAGE_KEY = 'wpp.host-session-code'; @@ -61,6 +63,12 @@ export function resolveSessionCode(route: ActivatedRouteSnapshot, mode: 'host' | return null; } +function resolveRouteLocale(route: ActivatedRouteSnapshot): string { + const locale = normalizeLocale(route.queryParamMap.get('lang')); + setPreferredLocale(locale); + return locale; +} + async function sessionExists(code: string): Promise { const response = await fetch(`/lobby/sessions/${encodeURIComponent(code)}`, { method: 'GET', @@ -118,23 +126,26 @@ export const playerRouteGuard: CanActivateFn = (route) => guard('player', route) export const hostRouteContextResolver: ResolveFn = (route) => { const code = resolveSessionCode(route, 'host'); + const locale = resolveRouteLocale(route); if (code) { window.sessionStorage.setItem(HOST_STORAGE_KEY, code); } - return { sessionCode: code, playerId: null, token: null }; + return { sessionCode: code, playerId: null, token: null, locale }; }; export const playerRouteContextResolver: ResolveFn = (route) => { const code = resolveSessionCode(route, 'player'); + const locale = resolveRouteLocale(route); const context = createSessionContextStore(window.localStorage).get(); if (!code || !context || normalizeCode(context.sessionCode) !== code) { - return { sessionCode: code, playerId: null, token: null }; + return { sessionCode: code, playerId: null, token: null, locale }; } return { sessionCode: code, playerId: Number.isInteger(context.playerId) && context.playerId > 0 ? context.playerId : null, token: context.token.trim() || null, + locale, }; }; -- 2.39.5 From 4b2b21fe577f44f4229d243082fc8b117bfa340e Mon Sep 17 00:00:00 2001 From: Asger Geel Weirsoee Date: Mon, 2 Mar 2026 01:05:00 +0000 Subject: [PATCH 2/2] Fix route locale resolver to only apply explicit lang param --- .../angular/src/app/session-route-context.spec.ts | 10 ++++++++++ frontend/angular/src/app/session-route-context.ts | 13 +++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/frontend/angular/src/app/session-route-context.spec.ts b/frontend/angular/src/app/session-route-context.spec.ts index 7e53b30..ee834df 100644 --- a/frontend/angular/src/app/session-route-context.spec.ts +++ b/frontend/angular/src/app/session-route-context.spec.ts @@ -92,4 +92,14 @@ describe('session route context', () => { expect(hostRouteContextResolver(route({}, { lang: 'da-DK' }) as never, {} as never).locale).toBe('da'); expect(playerRouteContextResolver(route({}, { lang: 'EN' }) as never, {} as never).locale).toBe('en'); }); + + it('does not reset persisted preferred locale when lang query param is absent', () => { + const localStorage = storageMock({ 'wpp.locale': 'da' }); + setWindow(localStorage, storageMock()); + + expect(hostRouteContextResolver(route({}, { lang: 'da' }) as never, {} as never).locale).toBe('da'); + expect(hostRouteContextResolver(route({}, {}) as never, {} as never).locale).toBe('da'); + expect(localStorage.setItem).toHaveBeenCalledTimes(1); + expect(localStorage.setItem).toHaveBeenCalledWith('wpp.locale', 'da'); + }); }); diff --git a/frontend/angular/src/app/session-route-context.ts b/frontend/angular/src/app/session-route-context.ts index c105ab4..64240c4 100644 --- a/frontend/angular/src/app/session-route-context.ts +++ b/frontend/angular/src/app/session-route-context.ts @@ -2,7 +2,7 @@ import { inject } from '@angular/core'; import { type ActivatedRouteSnapshot, type CanActivateFn, type ResolveFn, Router, type UrlTree } from '@angular/router'; import { createSessionContextStore } from '../../../src/spa/session-context-store'; -import { normalizeLocale, setPreferredLocale } from './lobby-i18n'; +import { normalizeLocale, resolvePreferredLocale, setPreferredLocale } from './lobby-i18n'; export interface RouteSessionContext { sessionCode: string | null; @@ -64,9 +64,14 @@ export function resolveSessionCode(route: ActivatedRouteSnapshot, mode: 'host' | } function resolveRouteLocale(route: ActivatedRouteSnapshot): string { - const locale = normalizeLocale(route.queryParamMap.get('lang')); - setPreferredLocale(locale); - return locale; + const langParam = route.queryParamMap.get('lang'); + if (langParam !== null) { + const locale = normalizeLocale(langParam); + setPreferredLocale(locale); + return locale; + } + + return resolvePreferredLocale(); } async function sessionExists(code: string): Promise { -- 2.39.5