diff --git a/client/src/services/socket.js b/client/src/services/socket.js index 999d510..edc3e18 100644 --- a/client/src/services/socket.js +++ b/client/src/services/socket.js @@ -4,8 +4,6 @@ let socket = null export function useSocket() { if (!socket) { - // En dev : pointe vers localhost:3000 - // En prod Docker : connexion sur la même origine (nginx proxifie /socket.io) const url = import.meta.env.VITE_SERVER_URL || ( import.meta.env.PROD ? window.location.origin : 'http://localhost:3000' ) @@ -13,3 +11,18 @@ export function useSocket() { } return socket } + +/** + * Quitte proprement une salle et nettoie tous les listeners de jeu. + * À appeler dans onUnmounted de LobbyView et GameView. + */ +export function leaveRoom(roomId) { + if (!socket) return + socket.emit('leave-room', { roomId }) + // Retirer tous les listeners liés au jeu + const gameEvents = [ + 'room-update', 'game-start', 'game-state', + 'players-ready', 'round-result', 'game-over' + ] + gameEvents.forEach(ev => socket.off(ev)) +} diff --git a/client/src/stores/game.js b/client/src/stores/game.js index 3d4a3d5..57a14b3 100644 --- a/client/src/stores/game.js +++ b/client/src/stores/game.js @@ -3,7 +3,7 @@ import { ref } from 'vue' export const useGameStore = defineStore('game', () => { const playerName = ref('') - const players = ref([]) // { name, teamIndex, gauges:{food,war,health,diplo}, score, handSize } + const players = ref([]) const currentTurn = ref(0) const maxTurns = ref(12) const phase = ref('idle') @@ -16,20 +16,31 @@ export const useGameStore = defineStore('game', () => { } function updateState(state) { - players.value = state.players - currentTurn.value = state.currentTurn - maxTurns.value = state.maxTurns - phase.value = state.phase + players.value = state.players ?? [] + currentTurn.value = state.currentTurn ?? 0 + maxTurns.value = state.maxTurns ?? 12 + phase.value = state.phase ?? 'idle' myTeamIndex.value = state.myTeamIndex ?? 0 if (state.hand !== undefined) hand.value = state.hand } function selectCard(card) { selectedCard.value = card } - function clearSelection() { selectedCard.value = null } + function clearSelection() { selectedCard.value = null } + + /** Réinitialise tout l'état de jeu (au retour au menu) */ + function reset() { + players.value = [] + currentTurn.value = 0 + maxTurns.value = 12 + phase.value = 'idle' + hand.value = [] + myTeamIndex.value = 0 + selectedCard.value = null + } return { playerName, players, currentTurn, maxTurns, phase, hand, myTeamIndex, selectedCard, - setPlayer, updateState, selectCard, clearSelection + setPlayer, updateState, selectCard, clearSelection, reset } }) diff --git a/client/src/views/GameView.vue b/client/src/views/GameView.vue index d42e0dc..215ed5c 100644 --- a/client/src/views/GameView.vue +++ b/client/src/views/GameView.vue @@ -48,7 +48,7 @@ import { ref, onMounted, onUnmounted } from 'vue' import { useRoute } from 'vue-router' import { useGameStore } from '@/stores/game' -import { useSocket } from '@/services/socket' +import { useSocket, leaveRoom } from '@/services/socket' import { createGame } from '@/game/GameFactory' const route = useRoute() @@ -94,7 +94,8 @@ onMounted(() => { }) onUnmounted(() => { - socket.off('game-state') + leaveRoom(route.params.roomId) + gameStore.reset() if (phaserGame) phaserGame.destroy(true) }) diff --git a/client/src/views/LobbyView.vue b/client/src/views/LobbyView.vue index e95985a..1c75d4c 100644 --- a/client/src/views/LobbyView.vue +++ b/client/src/views/LobbyView.vue @@ -1,16 +1,19 @@