fix(web): update QuestionCard to handle null selectedOptionId for timeout case #8

Open
opened 2026-04-18 08:21:41 +00:00 by forgejo-lila · 0 comments
Owner

Background

QuestionCard currently expects currentResult: AnswerResult | null where
AnswerResult.selectedOptionId is number (non-nullable). This comes from
the single-player flow where a player always selects an option before submitting.

In multiplayer, a player can time out without answering. The server sends
selectedOptionId: null in WsGameAnswerResult.results for timed-out players.

Currently in game.$code.tsx, we work around this with ?? 0 — falling back
to option 0 when the player timed out. This incorrectly highlights option 0 as
"wrong" on the score display rather than showing a neutral "timed out" state.

What needs to change

packages/shared/src/schemas/game.ts
Update AnswerResultSchema to allow selectedOptionId: number | null:

selectedOptionId: z.number().int().min(0).max(3).nullable(),

apps/web/src/components/game/QuestionCard.tsx
Update QuestionCardProps.currentResult to accept the nullable type.
Update getOptionState to handle selectedOptionId === null — in this
case no option should be highlighted as "wrong", only the correct option
should be highlighted green.

apps/api/src/controllers/gameController.ts and related
Verify the single-player flow still works with the nullable type — single-player
never produces null but the type change should be backwards compatible.

Acceptance criteria

  • AnswerResult.selectedOptionId is number | null in shared schemas.
  • QuestionCard renders correctly when selectedOptionId is null —
    only correct answer highlighted, no "wrong" highlight.
  • QuestionCard renders correctly for normal answer — correct/wrong
    highlights unchanged.
  • Single-player game flow unaffected.
  • Multiplayer timeout case shows neutral state, not incorrect "wrong" highlight.
  • packages/shared/src/schemas/game.ts
  • apps/web/src/components/game/QuestionCard.tsx
  • apps/web/src/routes/multiplayer/game.$code.tsx
## Background `QuestionCard` currently expects `currentResult: AnswerResult | null` where `AnswerResult.selectedOptionId` is `number` (non-nullable). This comes from the single-player flow where a player always selects an option before submitting. In multiplayer, a player can time out without answering. The server sends `selectedOptionId: null` in `WsGameAnswerResult.results` for timed-out players. Currently in `game.$code.tsx`, we work around this with `?? 0` — falling back to option 0 when the player timed out. This incorrectly highlights option 0 as "wrong" on the score display rather than showing a neutral "timed out" state. ## What needs to change **`packages/shared/src/schemas/game.ts`** Update `AnswerResultSchema` to allow `selectedOptionId: number | null`: ```ts selectedOptionId: z.number().int().min(0).max(3).nullable(), ``` **`apps/web/src/components/game/QuestionCard.tsx`** Update `QuestionCardProps.currentResult` to accept the nullable type. Update `getOptionState` to handle `selectedOptionId === null` — in this case no option should be highlighted as "wrong", only the correct option should be highlighted green. **`apps/api/src/controllers/gameController.ts`** and related Verify the single-player flow still works with the nullable type — single-player never produces null but the type change should be backwards compatible. ## Acceptance criteria - [ ] `AnswerResult.selectedOptionId` is `number | null` in shared schemas. - [ ] `QuestionCard` renders correctly when `selectedOptionId` is null — only correct answer highlighted, no "wrong" highlight. - [ ] `QuestionCard` renders correctly for normal answer — correct/wrong highlights unchanged. - [ ] Single-player game flow unaffected. - [ ] Multiplayer timeout case shows neutral state, not incorrect "wrong" highlight. ## Related - `packages/shared/src/schemas/game.ts` - `apps/web/src/components/game/QuestionCard.tsx` - `apps/web/src/routes/multiplayer/game.$code.tsx`
forgejo-lila added this to the lila development project 2026-04-18 08:21:41 +00:00
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: forgejo-lila/lila#8
No description provided.