fix: enable real-time player name updates across room members

When a player's name (or other properties) is updated, emit a
'players-updated' socket event to notify all room members. This triggers
the server to broadcast the updated player data via 'room-players-updated',
which all room members receive and use to update their local state.

Changes:
- Add notifyRoomOfPlayerUpdate() function to useRoomData hook
- Call it after successful player mutations (create, update, delete, setActive)
- This ensures all room members see player changes immediately without page reload

Fixes real-time synchronization of player names in the mini app nav.

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock
2025-10-09 07:38:34 -05:00
parent fc9eb253ad
commit 5171be3d37
2 changed files with 45 additions and 5 deletions

View File

@@ -68,7 +68,7 @@ export function GameModeProvider({ children }: { children: ReactNode }) {
const { mutate: createPlayer } = useCreatePlayer()
const { mutate: updatePlayerMutation } = useUpdatePlayer()
const { mutate: deletePlayer } = useDeletePlayer()
const { roomData } = useRoomData()
const { roomData, notifyRoomOfPlayerUpdate } = useRoomData()
const { data: viewerId } = useViewerId()
const [isInitialized, setIsInitialized] = useState(false)
@@ -167,14 +167,27 @@ export function GameModeProvider({ children }: { children: ReactNode }) {
isActive: playerData?.isActive ?? false,
}
createPlayer(newPlayer)
createPlayer(newPlayer, {
onSuccess: () => {
// Notify room members if in a room
notifyRoomOfPlayerUpdate()
},
})
}
const updatePlayer = (id: string, updates: Partial<Player>) => {
const player = players.get(id)
// Only allow updating local players
if (player?.isLocal) {
updatePlayerMutation({ id, updates })
updatePlayerMutation(
{ id, updates },
{
onSuccess: () => {
// Notify room members if in a room
notifyRoomOfPlayerUpdate()
},
}
)
} else {
console.warn('[GameModeContext] Cannot update remote player:', id)
}
@@ -184,7 +197,12 @@ export function GameModeProvider({ children }: { children: ReactNode }) {
const player = players.get(id)
// Only allow removing local players
if (player?.isLocal) {
deletePlayer(id)
deletePlayer(id, {
onSuccess: () => {
// Notify room members if in a room
notifyRoomOfPlayerUpdate()
},
})
} else {
console.warn('[GameModeContext] Cannot remove remote player:', id)
}
@@ -194,7 +212,15 @@ export function GameModeProvider({ children }: { children: ReactNode }) {
const player = players.get(id)
// Only allow changing active status of local players
if (player?.isLocal) {
updatePlayerMutation({ id, updates: { isActive: active } })
updatePlayerMutation(
{ id, updates: { isActive: active } },
{
onSuccess: () => {
// Notify room members if in a room
notifyRoomOfPlayerUpdate()
},
}
)
} else {
console.warn('[GameModeContext] Cannot change active status of remote player:', id)
}
@@ -227,6 +253,11 @@ export function GameModeProvider({ children }: { children: ReactNode }) {
isActive: index === 0,
})
})
// Notify room members after reset (slight delay to ensure mutations complete)
setTimeout(() => {
notifyRoomOfPlayerUpdate()
}, 100)
}
const activePlayerCount = activePlayers.size

View File

@@ -196,10 +196,19 @@ export function useRoomData() {
}
}, [socket, roomData?.id])
// Function to notify room members of player updates
const notifyRoomOfPlayerUpdate = () => {
if (socket && roomData?.id && userId) {
console.log('[useRoomData] Notifying room of player update')
socket.emit('players-updated', { roomId: roomData.id, userId })
}
}
return {
roomData,
// Loading if: userId is pending, currently fetching, or have userId but haven't tried fetching yet
isLoading: isUserIdPending || isLoading || (!!userId && !hasAttemptedFetch),
isInRoom: !!roomData,
notifyRoomOfPlayerUpdate,
}
}