From e953babdb8b703c1af26d4b0f7aa6807f83b03b1 Mon Sep 17 00:00:00 2001 From: Resistencia Dev Date: Mon, 22 Dec 2025 18:50:02 +0100 Subject: [PATCH] fix: Corregir errores de linter y dependencias de React para Gitea - Memoizar acciones en useSocket (useMemo) - Memoizar funciones en useSessionStorage (useCallback) - Completar dependency arrays en page.tsx y dashboard/page.tsx - Resolver advertencias de 'exhaustive-deps' para asegurar builds limpios --- client/src/app/dashboard/page.tsx | 4 +- client/src/app/page.tsx | 6 +- client/src/hooks/useSessionStorage.ts | 24 +++--- client/src/hooks/useSocket.ts | 113 +++++++++++--------------- 4 files changed, 64 insertions(+), 83 deletions(-) diff --git a/client/src/app/dashboard/page.tsx b/client/src/app/dashboard/page.tsx index 1b2a53e..600488c 100644 --- a/client/src/app/dashboard/page.tsx +++ b/client/src/app/dashboard/page.tsx @@ -46,7 +46,7 @@ export default function Dashboard() { socket.off('admin_action_success'); }; } - }, [isAuthenticated, socket]); + }, [isAuthenticated, socket, setActiveGames, setGameHistory]); const handleLogin = (e: React.FormEvent) => { e.preventDefault(); @@ -308,7 +308,7 @@ export default function Dashboard() {
{entry.winner ? (entry.winner === 'resistance' ? 'RES' : 'SPIES') : 'LOGOUT'}
diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx index dd13b2d..72900e2 100644 --- a/client/src/app/page.tsx +++ b/client/src/app/page.tsx @@ -55,7 +55,7 @@ export default function Home() { setHasReconnected(true); } - }, [session, isConnected, hasReconnected]); + }, [session, isConnected, hasReconnected, actions, setPlayerName, setFullPlayerName, setView, setHasReconnected]); // Efecto para cambiar a vista de juego cuando el servidor nos une useEffect(() => { @@ -71,7 +71,7 @@ export default function Home() { updateSession({ currentView: 'lobby', roomId: undefined }); } } - }, [gameState, view, hasReconnected]); + }, [gameState, view, hasReconnected, updateSession, setView]); // Listener para errores de socket que deben expulsar al lobby useEffect(() => { @@ -88,7 +88,7 @@ export default function Home() { return () => { socket.off('error', handleError); }; - }, [socket, updateSession]); + }, [socket, updateSession, setView]); const handleLogin = (e: React.FormEvent) => { e.preventDefault(); diff --git a/client/src/hooks/useSessionStorage.ts b/client/src/hooks/useSessionStorage.ts index 445e151..1964ec4 100644 --- a/client/src/hooks/useSessionStorage.ts +++ b/client/src/hooks/useSessionStorage.ts @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useCallback } from 'react'; interface SessionData { playerName: string; @@ -25,24 +25,26 @@ export function useSessionStorage() { }, []); // Guardar sesión - const saveSession = (data: SessionData) => { + const saveSession = useCallback((data: SessionData) => { localStorage.setItem('resistencia_session', JSON.stringify(data)); setSession(data); - }; + }, []); // Actualizar sesión parcialmente - const updateSession = (partial: Partial) => { - if (session) { - const updated = { ...session, ...partial }; - saveSession(updated); - } - }; + const updateSession = useCallback((partial: Partial) => { + setSession(prev => { + if (!prev) return null; + const updated = { ...prev, ...partial }; + localStorage.setItem('resistencia_session', JSON.stringify(updated)); + return updated; + }); + }, []); // Limpiar sesión - const clearSession = () => { + const clearSession = useCallback(() => { localStorage.removeItem('resistencia_session'); setSession(null); - }; + }, []); return { session, diff --git a/client/src/hooks/useSocket.ts b/client/src/hooks/useSocket.ts index 5e09733..37de62a 100644 --- a/client/src/hooks/useSocket.ts +++ b/client/src/hooks/useSocket.ts @@ -1,7 +1,7 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useState, useMemo } from 'react'; import { io, Socket } from 'socket.io-client'; -import { GameState, Player } from '../../../shared/types'; +import { GameState } from '../../../shared/types'; const SOCKET_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000'; @@ -35,25 +35,23 @@ export const useSocket = () => { }); // Manejar propio unirse a partida - socketInstance.on('game_joined', ({ roomId, state }) => { + socketInstance.on('game_joined', ({ state }) => { setGameState(state); - // Podríamos guardar el roomId en localStorage o similar si quisiéramos persistencia }); socketInstance.on('error', (msg: string) => { - alert(msg); // Simple error handling for now + alert(msg); }); // Manejar finalización de partida por el host socketInstance.on('game_finalized', () => { console.log('La partida ha sido finalizada por el host'); - setGameState(null); // Resetear estado para volver al lobby + setGameState(null); }); // Manejar cuando un jugador abandona la partida socketInstance.on('player_left_game', ({ playerName }: { playerName: string }) => { console.log(`${playerName} ha abandonado la partida`); - // El servidor ya habrá cerrado la partida, solo mostramos mensaje }); setSocket(socketInstance); @@ -63,71 +61,52 @@ export const useSocket = () => { }; }, []); - // Funciones helper para enviar acciones - const createGame = (hostName: string, maxPlayers: number, password?: string) => { - socket?.emit('create_game', { hostName, maxPlayers, password }); - }; - - const joinGame = (roomId: string, playerName: string, password?: string) => { - socket?.emit('join_game', { roomId, playerName, password }); - }; - - const refreshRooms = () => { - socket?.emit('get_rooms'); - }; - - const startGame = () => { - socket?.emit('start_game', { roomId: gameState?.roomId }); - }; - - const proposeTeam = (teamIds: string[]) => { - socket?.emit('propose_team', { roomId: gameState?.roomId, teamIds }); - }; - - const voteTeam = (approve: boolean) => { - socket?.emit('vote_team', { roomId: gameState?.roomId, approve }); - }; - - const voteMission = (success: boolean) => { - socket?.emit('vote_mission', { roomId: gameState?.roomId, success }); - }; - - const assassinKill = (targetId: string) => { - socket?.emit('assassin_kill', { roomId: gameState?.roomId, targetId }); - }; - - const leaveGame = () => { - socket?.emit('leave_game', { roomId: gameState?.roomId }); - }; - - const reconnectSession = (sessionData: { playerName: string; roomId?: string }) => { - socket?.emit('reconnect_session', sessionData); - }; + const actions = useMemo(() => ({ + createGame: (hostName: string, maxPlayers: number, password?: string) => { + socket?.emit('create_game', { hostName, maxPlayers, password }); + }, + joinGame: (roomId: string, playerName: string, password?: string) => { + socket?.emit('join_game', { roomId, playerName, password }); + }, + refreshRooms: () => { + socket?.emit('get_rooms'); + }, + startGame: () => { + socket?.emit('start_game', { roomId: gameState?.roomId }); + }, + proposeTeam: (teamIds: string[]) => { + socket?.emit('propose_team', { roomId: gameState?.roomId, teamIds }); + }, + voteTeam: (approve: boolean) => { + socket?.emit('vote_team', { roomId: gameState?.roomId, approve }); + }, + voteMission: (success: boolean) => { + socket?.emit('vote_mission', { roomId: gameState?.roomId, success }); + }, + voteLeader: (approve: boolean) => socket?.emit('vote_leader', { roomId: gameState?.roomId, approve }), + assassinKill: (targetId: string) => { + socket?.emit('assassin_kill', { roomId: gameState?.roomId, targetId }); + }, + leaveGame: () => { + socket?.emit('leave_game', { roomId: gameState?.roomId }); + }, + reconnectSession: (sessionData: { playerName: string; roomId?: string }) => { + socket?.emit('reconnect_session', sessionData); + }, + finishIntro: () => socket?.emit('finish_intro', { roomId: gameState?.roomId }), + finishReveal: () => socket?.emit('finish_reveal', { roomId: gameState?.roomId }), + finishRollCall: () => socket?.emit('finish_roll_call', { roomId: gameState?.roomId }), + finishMissionReveal: () => socket?.emit('finish_reveal', { roomId: gameState?.roomId }), + finishMissionResult: () => socket?.emit('finish_mission_result', { roomId: gameState?.roomId }), + restartGame: () => socket?.emit('restart_game', { roomId: gameState?.roomId }), + finalizeGame: () => socket?.emit('finalize_game', { roomId: gameState?.roomId }) + }), [socket, gameState?.roomId]); return { socket, isConnected, gameState, roomsList, - actions: { - createGame, - joinGame, - refreshRooms, - startGame, - proposeTeam, - voteTeam, - voteMission, - voteLeader: (approve: boolean) => socket?.emit('vote_leader', { roomId: gameState?.roomId, approve }), - assassinKill, - leaveGame, - reconnectSession, - finishIntro: () => socket?.emit('finish_intro', { roomId: gameState?.roomId }), - finishReveal: () => socket?.emit('finish_reveal', { roomId: gameState?.roomId }), - finishRollCall: () => socket?.emit('finish_roll_call', { roomId: gameState?.roomId }), - finishMissionReveal: () => socket?.emit('finish_reveal', { roomId: gameState?.roomId }), - finishMissionResult: () => socket?.emit('finish_mission_result', { roomId: gameState?.roomId }), - restartGame: () => socket?.emit('restart_game', { roomId: gameState?.roomId }), - finalizeGame: () => socket?.emit('finalize_game', { roomId: gameState?.roomId }) - } + actions }; };