Conversation
WalkthroughAdds a lobby presets feature: client-side preset store, UI component, integration into host and single-player modals using patch-based GameConfig flows, form-state utilities, server default config factories, tests, and a test storage shim. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Modal as HostLobbyModal / SinglePlayerModal
participant UI as LobbyPresetControls
participant Store as LobbyPresets
participant Storage as localStorage
participant Server as GameServer
User->>Modal: open modal
Modal->>Store: listPresets()
Store->>Storage: read LOBBY_PRESET_STORAGE_KEY
Storage-->>Store: JSON
Store-->>Modal: presets[]
Modal->>UI: render presets selector
User->>UI: select preset
UI->>Store: get preset by id
Store-->>UI: preset
UI-->>Modal: apply preset id
Modal->>Modal: buildGameConfigPatch()
Modal->>Modal: applyGameConfigPatch(patch)
User->>UI: save preset (name)
UI->>Modal: getConfigPatch()
Modal-->>UI: patch
UI->>Store: upsertPreset(name, config)
Store->>Storage: save LOBBY_PRESET_STORAGE_KEY
User->>Modal: create/start game
Modal->>Modal: buildFullGameConfig()
Modal->>Server: POST /createLobby (body: GameConfig)
Server-->>Modal: GameInfo
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
a19e429 to
94ca6cc
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/client/HostLobbyModal.ts`:
- Around line 1217-1229: In syncPresetsFromStore, avoid pre-selecting last-used
preset when auto-apply is off: set this.autoApplyLastUsedPreset from
store.autoApplyLastUsed first, then compute selectionId so it is
preferredSelectionId if provided, otherwise use store.lastUsedPresetId only when
store.autoApplyLastUsed is true; otherwise leave selectionId undefined. Update
assignment to this.selectedPresetId and this.presetNameInput to use that
selectionId/selectedPreset logic (references: syncPresetsFromStore,
autoApplyLastUsedPreset, preferredSelectionId, store.lastUsedPresetId,
selectedPresetId, presetNameInput).
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/client/HostLobbyModal.ts`:
- Around line 1157-1165: When the preset lookup fails in HostLobbyModal
(loadLobbyPresetStore + preset lookup using this.selectedPresetId), clear the
stale UI state: set this.selectedPresetId = undefined (already done) and also
clear any "last-used" preset state and input control bound to the preset
selection (e.g., reset lastUsedPresetId or the form input controlling the
preset) before returning; keep the existing showMessage(translateText(...),
"red") behavior so the user is notified and the UI remains consistent.
🧹 Nitpick comments (3)
src/client/LobbyPresets.ts (2)
31-51: Clear invalid stored data so future loads recover cleanly.If JSON/schema parsing fails, the bad payload stays and every load re-parses. Removing the key once avoids repeated failures and allows clean recovery.
♻️ Suggested tweak
try { const parsed = JSON.parse(raw); const result = LobbyPresetStoreSchema.safeParse(parsed); if (result.success) { return result.data; } + localStorage.removeItem(LOBBY_PRESET_STORAGE_KEY); } catch { + localStorage.removeItem(LOBBY_PRESET_STORAGE_KEY); return emptyLobbyPresetStore(); }
71-72: Return a copy to avoid accidental mutation.Returning the internal array lets callers mutate it without saving, which can create confusing state.
♻️ Suggested tweak
export function listPresets(): LobbyPreset[] { - return loadLobbyPresetStore().presets; + return [...loadLobbyPresetStore().presets]; }tests/client/LobbyPresets.test.ts (1)
1-13: Avoid hardcoding the storage key in tests.Using the shared constant prevents drift if the key changes. This needs the constant exported from LobbyPresets.
♻️ Suggested tweak
import { deletePreset, loadLobbyPresetStore, setAutoApplyLastUsed, setLastUsedPresetId, upsertPreset, + LOBBY_PRESET_STORAGE_KEY, } from "../../src/client/LobbyPresets"; @@ - localStorage.removeItem("lobbyPresets.v1"); + localStorage.removeItem(LOBBY_PRESET_STORAGE_KEY);
src/client/HostLobbyModal.ts
Outdated
| } | ||
|
|
||
| private async putGameConfig() { | ||
| private async handlePresetSelectionChange(e: Event) { |
There was a problem hiding this comment.
can the preset logic be moved into it's own lit element in client/components. Then it can be reused in singleplayer modal as well
src/client/HostLobbyModal.ts
Outdated
| import { renderUnitTypeOptions } from "./utilities/RenderUnitTypeOptions"; | ||
| import randomMap from "/images/RandomMap.webp?url"; | ||
|
|
||
| const DEFAULT_PRIVATE_GAME_CONFIG: GameConfig = { |
There was a problem hiding this comment.
Maybe all the game config storage/handling could go in its own file? One issue is that adding an new config option requires changing the code in many different places. I think if we had one registry that could make things easier.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/client/components/LobbyPresetControls.ts`:
- Around line 102-121: handlePresetSaveClick currently passes a config patch
with undefined fields which JSON.stringify will drop, so disabled toggle fields
(maxTimerValue, goldMultiplier, startingGold, spawnImmunityDuration) get lost;
before calling upsertPreset replace undefined toggle values with explicit nulls
(e.g. map any toggle-off fields to null) so the preset persists the "disabled"
intent, and update the preset schema/types and the consumers
(applyCommonGameConfigPatch / applyHostLobbyGameConfigPatch) to treat null as
the disabled sentinel when applying patches. Ensure you update upsertPreset
usage and any type definitions so stored presets can contain null for those
fields and the apply* functions check for field presence and null to clear
toggles.
61d0696 to
a9967c2
Compare
If this PR fixes an issue, link it below. If not, delete these two lines.
Resolves #2566
Description:
Please complete the following:
Please put your Discord username so you can be contacted if a bug or regression is found:
mitchfz