|
|
|
|
@@ -2,7 +2,7 @@
|
|
|
|
|
|
|
|
|
|
import { type ReactNode, useCallback, useEffect, useMemo } from 'react'
|
|
|
|
|
import { useArcadeSession } from '@/hooks/useArcadeSession'
|
|
|
|
|
import { useRoomData } from '@/hooks/useRoomData'
|
|
|
|
|
import { useRoomData, useUpdateGameConfig } from '@/hooks/useRoomData'
|
|
|
|
|
import { useViewerId } from '@/hooks/useViewerId'
|
|
|
|
|
import {
|
|
|
|
|
buildPlayerMetadata as buildPlayerMetadataUtil,
|
|
|
|
|
@@ -240,6 +240,7 @@ export function RoomMemoryPairsProvider({ children }: { children: ReactNode }) {
|
|
|
|
|
const { data: viewerId } = useViewerId()
|
|
|
|
|
const { roomData } = useRoomData() // Fetch room data for room-based play
|
|
|
|
|
const { activePlayerCount, activePlayers: activePlayerIds, players } = useGameMode()
|
|
|
|
|
const { mutate: updateGameConfig } = useUpdateGameConfig()
|
|
|
|
|
|
|
|
|
|
// Get active player IDs directly as strings (UUIDs)
|
|
|
|
|
const activePlayers = Array.from(activePlayerIds)
|
|
|
|
|
@@ -247,8 +248,44 @@ export function RoomMemoryPairsProvider({ children }: { children: ReactNode }) {
|
|
|
|
|
// Derive game mode from active player count
|
|
|
|
|
const gameMode = activePlayerCount > 1 ? 'multiplayer' : 'single'
|
|
|
|
|
|
|
|
|
|
// NO LOCAL STATE - Configuration lives in session state
|
|
|
|
|
// Changes are sent as moves and synchronized across all room members
|
|
|
|
|
// Merge saved game config from room with initialState
|
|
|
|
|
// Settings are scoped by game name to preserve settings when switching games
|
|
|
|
|
const mergedInitialState = useMemo(() => {
|
|
|
|
|
const gameConfig = roomData?.gameConfig as Record<string, any> | null | undefined
|
|
|
|
|
console.log('[RoomMemoryPairsProvider] Loading settings from database:', {
|
|
|
|
|
gameConfig,
|
|
|
|
|
roomId: roomData?.id,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (!gameConfig) {
|
|
|
|
|
console.log('[RoomMemoryPairsProvider] No gameConfig, using initialState')
|
|
|
|
|
return initialState
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get settings for this specific game (matching)
|
|
|
|
|
const savedConfig = gameConfig.matching as Record<string, any> | null | undefined
|
|
|
|
|
console.log('[RoomMemoryPairsProvider] Saved config for matching:', savedConfig)
|
|
|
|
|
|
|
|
|
|
if (!savedConfig) {
|
|
|
|
|
console.log('[RoomMemoryPairsProvider] No saved config for matching, using initialState')
|
|
|
|
|
return initialState
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const merged = {
|
|
|
|
|
...initialState,
|
|
|
|
|
// Restore settings from saved config
|
|
|
|
|
gameType: savedConfig.gameType ?? initialState.gameType,
|
|
|
|
|
difficulty: savedConfig.difficulty ?? initialState.difficulty,
|
|
|
|
|
turnTimer: savedConfig.turnTimer ?? initialState.turnTimer,
|
|
|
|
|
}
|
|
|
|
|
console.log('[RoomMemoryPairsProvider] Merged state:', {
|
|
|
|
|
gameType: merged.gameType,
|
|
|
|
|
difficulty: merged.difficulty,
|
|
|
|
|
turnTimer: merged.turnTimer,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return merged
|
|
|
|
|
}, [roomData?.gameConfig])
|
|
|
|
|
|
|
|
|
|
// Arcade session integration WITH room sync
|
|
|
|
|
const {
|
|
|
|
|
@@ -259,7 +296,7 @@ export function RoomMemoryPairsProvider({ children }: { children: ReactNode }) {
|
|
|
|
|
} = useArcadeSession<MemoryPairsState>({
|
|
|
|
|
userId: viewerId || '',
|
|
|
|
|
roomId: roomData?.id, // CRITICAL: Pass roomId for network sync across room members
|
|
|
|
|
initialState,
|
|
|
|
|
initialState: mergedInitialState,
|
|
|
|
|
applyMove: applyMoveOptimistically,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
@@ -498,6 +535,8 @@ export function RoomMemoryPairsProvider({ children }: { children: ReactNode }) {
|
|
|
|
|
|
|
|
|
|
const setGameType = useCallback(
|
|
|
|
|
(gameType: typeof state.gameType) => {
|
|
|
|
|
console.log('[RoomMemoryPairsProvider] setGameType called:', gameType)
|
|
|
|
|
|
|
|
|
|
// Use first active player as playerId, or empty string if none
|
|
|
|
|
const playerId = activePlayers[0] || ''
|
|
|
|
|
sendMove({
|
|
|
|
|
@@ -506,12 +545,38 @@ export function RoomMemoryPairsProvider({ children }: { children: ReactNode }) {
|
|
|
|
|
userId: viewerId || '',
|
|
|
|
|
data: { field: 'gameType', value: gameType },
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Save setting to room's gameConfig for persistence
|
|
|
|
|
if (roomData?.id) {
|
|
|
|
|
const currentGameConfig = (roomData.gameConfig as Record<string, any>) || {}
|
|
|
|
|
const currentMatchingConfig = (currentGameConfig.matching as Record<string, any>) || {}
|
|
|
|
|
|
|
|
|
|
const updatedConfig = {
|
|
|
|
|
...currentGameConfig,
|
|
|
|
|
matching: {
|
|
|
|
|
...currentMatchingConfig,
|
|
|
|
|
gameType,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
console.log('[RoomMemoryPairsProvider] Saving gameType to database:', {
|
|
|
|
|
roomId: roomData.id,
|
|
|
|
|
updatedConfig,
|
|
|
|
|
})
|
|
|
|
|
updateGameConfig({
|
|
|
|
|
roomId: roomData.id,
|
|
|
|
|
gameConfig: updatedConfig,
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
console.warn('[RoomMemoryPairsProvider] Cannot save gameType - no roomData.id')
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[activePlayers, sendMove, viewerId]
|
|
|
|
|
[activePlayers, sendMove, viewerId, roomData?.id, roomData?.gameConfig, updateGameConfig]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const setDifficulty = useCallback(
|
|
|
|
|
(difficulty: typeof state.difficulty) => {
|
|
|
|
|
console.log('[RoomMemoryPairsProvider] setDifficulty called:', difficulty)
|
|
|
|
|
|
|
|
|
|
const playerId = activePlayers[0] || ''
|
|
|
|
|
sendMove({
|
|
|
|
|
type: 'SET_CONFIG',
|
|
|
|
|
@@ -519,12 +584,38 @@ export function RoomMemoryPairsProvider({ children }: { children: ReactNode }) {
|
|
|
|
|
userId: viewerId || '',
|
|
|
|
|
data: { field: 'difficulty', value: difficulty },
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Save setting to room's gameConfig for persistence
|
|
|
|
|
if (roomData?.id) {
|
|
|
|
|
const currentGameConfig = (roomData.gameConfig as Record<string, any>) || {}
|
|
|
|
|
const currentMatchingConfig = (currentGameConfig.matching as Record<string, any>) || {}
|
|
|
|
|
|
|
|
|
|
const updatedConfig = {
|
|
|
|
|
...currentGameConfig,
|
|
|
|
|
matching: {
|
|
|
|
|
...currentMatchingConfig,
|
|
|
|
|
difficulty,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
console.log('[RoomMemoryPairsProvider] Saving difficulty to database:', {
|
|
|
|
|
roomId: roomData.id,
|
|
|
|
|
updatedConfig,
|
|
|
|
|
})
|
|
|
|
|
updateGameConfig({
|
|
|
|
|
roomId: roomData.id,
|
|
|
|
|
gameConfig: updatedConfig,
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
console.warn('[RoomMemoryPairsProvider] Cannot save difficulty - no roomData.id')
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[activePlayers, sendMove, viewerId]
|
|
|
|
|
[activePlayers, sendMove, viewerId, roomData?.id, roomData?.gameConfig, updateGameConfig]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const setTurnTimer = useCallback(
|
|
|
|
|
(turnTimer: typeof state.turnTimer) => {
|
|
|
|
|
console.log('[RoomMemoryPairsProvider] setTurnTimer called:', turnTimer)
|
|
|
|
|
|
|
|
|
|
const playerId = activePlayers[0] || ''
|
|
|
|
|
sendMove({
|
|
|
|
|
type: 'SET_CONFIG',
|
|
|
|
|
@@ -532,8 +623,32 @@ export function RoomMemoryPairsProvider({ children }: { children: ReactNode }) {
|
|
|
|
|
userId: viewerId || '',
|
|
|
|
|
data: { field: 'turnTimer', value: turnTimer },
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Save setting to room's gameConfig for persistence
|
|
|
|
|
if (roomData?.id) {
|
|
|
|
|
const currentGameConfig = (roomData.gameConfig as Record<string, any>) || {}
|
|
|
|
|
const currentMatchingConfig = (currentGameConfig.matching as Record<string, any>) || {}
|
|
|
|
|
|
|
|
|
|
const updatedConfig = {
|
|
|
|
|
...currentGameConfig,
|
|
|
|
|
matching: {
|
|
|
|
|
...currentMatchingConfig,
|
|
|
|
|
turnTimer,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
console.log('[RoomMemoryPairsProvider] Saving turnTimer to database:', {
|
|
|
|
|
roomId: roomData.id,
|
|
|
|
|
updatedConfig,
|
|
|
|
|
})
|
|
|
|
|
updateGameConfig({
|
|
|
|
|
roomId: roomData.id,
|
|
|
|
|
gameConfig: updatedConfig,
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
console.warn('[RoomMemoryPairsProvider] Cannot save turnTimer - no roomData.id')
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[activePlayers, sendMove, viewerId]
|
|
|
|
|
[activePlayers, sendMove, viewerId, roomData?.id, roomData?.gameConfig, updateGameConfig]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const goToSetup = useCallback(() => {
|
|
|
|
|
|