Compare commits

...

5 Commits

Author SHA1 Message Date
semantic-release-bot
73c54a7ebc chore(release): 3.17.2 [skip ci]
## [3.17.2](https://github.com/antialias/soroban-abacus-flashcards/compare/v3.17.1...v3.17.2) (2025-10-15)

### Bug Fixes

* **room-data:** update query cache when gameConfig changes ([7cea297](7cea297095))
2025-10-15 15:01:02 +00:00
Thomas Hallock
7cea297095 fix(room-data): update query cache when gameConfig changes
The issue was that useUpdateGameConfig was saving settings to the database
but not updating the TanStack Query cache. This meant that when components
re-mounted (e.g., when switching games), they would read stale data from
the cache instead of the newly saved settings.

Changes:
- Added onSuccess callback to useUpdateGameConfig to update the cache
- Added gameConfig field to RoomData interface
- Updated all API functions to include gameConfig in returned data:
  - fetchCurrentRoom
  - createRoomApi
  - joinRoomApi
  - getRoomByCodeApi

Now when settings are saved, the cache is immediately updated, so switching
games and returning shows the correct saved settings.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 10:00:05 -05:00
semantic-release-bot
019d36a0ab chore(release): 3.17.1 [skip ci]
## [3.17.1](https://github.com/antialias/soroban-abacus-flashcards/compare/v3.17.0...v3.17.1) (2025-10-15)

### Bug Fixes

* **arcade-rooms:** navigate to invite link after room creation ([1922b21](1922b2122b))
* **memory-quiz:** scope game settings by game name for proper persistence ([3dfe54f](3dfe54f1cb))
2025-10-15 14:51:46 +00:00
Thomas Hallock
1922b2122b fix(arcade-rooms): navigate to invite link after room creation
Previously, when creating a new room, users were navigated to
/arcade-rooms/{roomId}, which is the direct room route.

Now users are navigated to /join/{code}, which is the invite link
format. This provides a better user experience as it follows the
same flow as joining via an invite link.

Changes:
- Changed router.push from /arcade-rooms/{id} to /join/{code}

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 09:50:53 -05:00
Thomas Hallock
3dfe54f1cb fix(memory-quiz): scope game settings by game name for proper persistence
Previously, settings were stored at the root of gameConfig, causing each
game to overwrite the other's settings when switching between games.

Now settings are stored under gameConfig['memory-quiz'], allowing each
game to maintain its own settings independently. When you switch from
memory-quiz to another game and back, the memory-quiz settings are
preserved exactly as you left them.

Changes:
- Load settings from gameConfig['memory-quiz'] instead of root gameConfig
- Save settings to gameConfig['memory-quiz'] to avoid overwriting other games
- Added comments explaining the scoping strategy

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 09:50:13 -05:00
5 changed files with 53 additions and 7 deletions

View File

@@ -1,3 +1,18 @@
## [3.17.2](https://github.com/antialias/soroban-abacus-flashcards/compare/v3.17.1...v3.17.2) (2025-10-15)
### Bug Fixes
* **room-data:** update query cache when gameConfig changes ([7cea297](https://github.com/antialias/soroban-abacus-flashcards/commit/7cea297095b78d74f5b77ca83489ec1be684a486))
## [3.17.1](https://github.com/antialias/soroban-abacus-flashcards/compare/v3.17.0...v3.17.1) (2025-10-15)
### Bug Fixes
* **arcade-rooms:** navigate to invite link after room creation ([1922b21](https://github.com/antialias/soroban-abacus-flashcards/commit/1922b2122bb1bc4aeada7526d8c46aa89024bb00))
* **memory-quiz:** scope game settings by game name for proper persistence ([3dfe54f](https://github.com/antialias/soroban-abacus-flashcards/commit/3dfe54f1cb89bd636e763e1c5acb03776f97c011))
## [3.17.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v3.16.0...v3.17.0) (2025-10-15)

View File

@@ -70,7 +70,7 @@ export default function RoomBrowserPage() {
}
const data = await response.json()
router.push(`/arcade-rooms/${data.room.id}`)
router.push(`/join/${data.room.code}`)
} catch (err) {
console.error('Failed to create room:', err)
showError('Failed to create room', err instanceof Error ? err.message : undefined)

View File

@@ -248,11 +248,16 @@ export function RoomMemoryQuizProvider({ children }: { children: ReactNode }) {
const [localCurrentInput, setLocalCurrentInput] = useState('')
// Merge saved game config from room with initialState
// Settings are scoped by game name to preserve settings when switching games
const mergedInitialState = useMemo(() => {
const savedConfig = roomData?.gameConfig as Record<string, any> | null | undefined
const gameConfig = roomData?.gameConfig as Record<string, any> | null | undefined
if (!gameConfig) return initialState
// Get settings for this specific game (memory-quiz)
const savedConfig = gameConfig['memory-quiz'] as Record<string, any> | null | undefined
if (!savedConfig) return initialState
console.log('[RoomMemoryQuizProvider] Loading saved game config:', savedConfig)
console.log('[RoomMemoryQuizProvider] Loading saved game config for memory-quiz:', savedConfig)
return {
...initialState,
@@ -441,12 +446,20 @@ export function RoomMemoryQuizProvider({ children }: { children: ReactNode }) {
})
// Save setting to room's gameConfig for persistence
// Settings are scoped by game name to preserve settings when switching games
if (roomData?.id) {
const currentGameConfig = (roomData.gameConfig as Record<string, any>) || {}
const currentMemoryQuizConfig =
(currentGameConfig['memory-quiz'] as Record<string, any>) || {}
const updatedConfig = {
...(roomData.gameConfig as Record<string, any>),
[field]: value,
...currentGameConfig,
'memory-quiz': {
...currentMemoryQuizConfig,
[field]: value,
},
}
console.log('[RoomMemoryQuizProvider] Saving game config:', updatedConfig)
console.log('[RoomMemoryQuizProvider] Saving game config for memory-quiz:', updatedConfig)
updateGameConfig({
roomId: roomData.id,
gameConfig: updatedConfig,

View File

@@ -23,6 +23,7 @@ export interface RoomData {
name: string
code: string
gameName: string | null // Nullable to support game selection in room
gameConfig?: Record<string, unknown> | null // Game-specific settings
accessMode: 'open' | 'password' | 'approval-only' | 'restricted' | 'locked' | 'retired'
members: RoomMember[]
memberPlayers: Record<string, RoomPlayer[]> // userId -> players
@@ -71,6 +72,7 @@ async function fetchCurrentRoom(): Promise<RoomData | null> {
name: data.room.name,
code: data.room.code,
gameName: data.room.gameName,
gameConfig: data.room.gameConfig || null,
accessMode: data.room.accessMode || 'open',
members: data.members || [],
memberPlayers: data.memberPlayers || {},
@@ -105,6 +107,7 @@ async function createRoomApi(params: CreateRoomParams): Promise<RoomData> {
name: data.room.name,
code: data.room.code,
gameName: data.room.gameName,
gameConfig: data.room.gameConfig || null,
accessMode: data.room.accessMode || 'open',
members: data.members || [],
memberPlayers: data.memberPlayers || {},
@@ -141,6 +144,7 @@ async function joinRoomApi(params: {
name: data.room.name,
code: data.room.code,
gameName: data.room.gameName,
gameConfig: data.room.gameConfig || null,
accessMode: data.room.accessMode || 'open',
members: data.members || [],
memberPlayers: data.memberPlayers || {},
@@ -183,6 +187,7 @@ async function getRoomByCodeApi(code: string): Promise<RoomData> {
name: data.room.name,
code: data.room.code,
gameName: data.room.gameName,
gameConfig: data.room.gameConfig || null,
accessMode: data.room.accessMode || 'open',
members: data.members || [],
memberPlayers: data.memberPlayers || {},
@@ -692,7 +697,20 @@ async function updateGameConfigApi(params: {
* This allows games to persist their settings (e.g., difficulty, card count)
*/
export function useUpdateGameConfig() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: updateGameConfigApi,
onSuccess: (_, variables) => {
// Update the cache with the new gameConfig
queryClient.setQueryData<RoomData | null>(roomKeys.current(), (prev) => {
if (!prev) return null
return {
...prev,
gameConfig: variables.gameConfig,
}
})
console.log('[useUpdateGameConfig] Updated cache with new gameConfig:', variables.gameConfig)
},
})
}

View File

@@ -1,6 +1,6 @@
{
"name": "soroban-monorepo",
"version": "3.17.0",
"version": "3.17.2",
"private": true,
"description": "Beautiful Soroban Flashcard Generator - Monorepo",
"workspaces": [