fix(frontend): restore session context behavior in vertical slice

This commit is contained in:
2026-03-01 12:50:29 +00:00
parent 093a928e6a
commit 24a319fd8f
2 changed files with 98 additions and 8 deletions

View File

@@ -4,6 +4,17 @@ import { deriveGameplayPhase, type GameplayPhase } from './gameplay-phase-machin
export type AsyncState = 'idle' | 'loading' | 'success' | 'error';
export interface SessionContext {
sessionCode: string;
playerToken: string;
nickname: string;
}
export interface SessionContextStore {
get(): SessionContext | null;
set(context: SessionContext): void;
}
export interface VerticalSliceState {
sessionCode: string;
session: SessionDetailResponse | null;
@@ -21,9 +32,19 @@ export interface VerticalSliceController {
startRound(sessionCode: string, categorySlug: string): Promise<VerticalSliceState>;
}
export function createVerticalSliceController(api: ApiClient): VerticalSliceController {
const NOOP_SESSION_CONTEXT_STORE: SessionContextStore = {
get: () => null,
set: () => undefined
};
export function createVerticalSliceController(
api: ApiClient,
sessionContextStore: SessionContextStore = NOOP_SESSION_CONTEXT_STORE
): VerticalSliceController {
const persistedContext = sessionContextStore.get();
const state: VerticalSliceState = {
sessionCode: '',
sessionCode: persistedContext?.sessionCode ?? '',
session: null,
gameplayPhase: null,
joinState: 'idle',
@@ -37,7 +58,10 @@ export function createVerticalSliceController(api: ApiClient): VerticalSliceCont
async function hydrateLobby(sessionCode: string): Promise<VerticalSliceState> {
state.loadingSession = true;
state.errorMessage = null;
state.sessionCode = normalizeCode(sessionCode);
const normalizedRequestedCode = normalizeCode(sessionCode);
const fallbackCode = normalizeCode(state.sessionCode || persistedContext?.sessionCode || '');
state.sessionCode = normalizedRequestedCode || fallbackCode;
const result = await api.getSession(state.sessionCode);
state.loadingSession = false;
@@ -50,6 +74,12 @@ export function createVerticalSliceController(api: ApiClient): VerticalSliceCont
state.session = result.data;
state.gameplayPhase = deriveGameplayPhase(result.data);
state.sessionCode = normalizeCode(result.data.session.code);
if (persistedContext && state.sessionCode === normalizeCode(persistedContext.sessionCode)) {
sessionContextStore.set({ ...persistedContext, sessionCode: state.sessionCode });
}
return { ...state };
}
@@ -57,7 +87,11 @@ export function createVerticalSliceController(api: ApiClient): VerticalSliceCont
state.joinState = 'loading';
state.errorMessage = null;
const join = await api.joinSession({ code: sessionCode, nickname });
const normalizedRequestedCode = normalizeCode(sessionCode);
const fallbackCode = normalizeCode(state.sessionCode || persistedContext?.sessionCode || '');
const requestCode = normalizedRequestedCode || fallbackCode;
const join = await api.joinSession({ code: requestCode, nickname });
if (!join.ok) {
state.joinState = 'error';
state.errorMessage = 'Join fejlede. Tjek kode eller nickname og prøv igen.';
@@ -65,14 +99,26 @@ export function createVerticalSliceController(api: ApiClient): VerticalSliceCont
}
state.joinState = 'success';
return hydrateLobby(sessionCode);
state.sessionCode = normalizeCode(join.data.session.code || requestCode);
sessionContextStore.set({
sessionCode: state.sessionCode,
playerToken: join.data.player.session_token,
nickname: join.data.player.nickname
});
return hydrateLobby(state.sessionCode);
}
async function startRound(sessionCode: string, categorySlug: string): Promise<VerticalSliceState> {
state.startRoundState = 'loading';
state.errorMessage = null;
const start = await api.startRound(sessionCode, { category_slug: categorySlug });
const normalizedRequestedCode = normalizeCode(sessionCode);
const fallbackCode = normalizeCode(state.sessionCode || persistedContext?.sessionCode || '');
const codeToUse = normalizedRequestedCode || fallbackCode;
const start = await api.startRound(codeToUse, { category_slug: categorySlug });
if (!start.ok) {
state.startRoundState = 'error';
state.errorMessage = 'Kunne ikke starte runden. Opdatér lobbyen og prøv igen.';
@@ -80,7 +126,7 @@ export function createVerticalSliceController(api: ApiClient): VerticalSliceCont
}
state.startRoundState = 'success';
return hydrateLobby(sessionCode);
return hydrateLobby(codeToUse);
}
return {