diff --git a/public/index.html b/public/index.html index 32f4485..ef89f22 100644 --- a/public/index.html +++ b/public/index.html @@ -18,10 +18,10 @@
- + - +
diff --git a/public/js/htmlTmpl.js b/public/js/htmlTmpl.js index bddbbf7..e6f9c9e 100644 --- a/public/js/htmlTmpl.js +++ b/public/js/htmlTmpl.js @@ -1,27 +1,27 @@ -export const cardGamePropia = (nickname, game_id) => { +export const cardGamePropia = (nickname, game_id,eliminarPartidaCallback) => { var cardGameDiv = document.createElement('div'); cardGameDiv.classList.add('cardGame'); cardGameDiv.innerHTML = `${nickname} Esperando rival... - + `; const cancelGameBtn = cardGameDiv.querySelector('.cancel-game-btn'); cancelGameBtn.addEventListener('click', () => { - eliminarPartida(game_id); + eliminarPartidaCallback(game_id); }); return cardGameDiv; }; -export const cardGameGeneral = (nickname, game_id) => { +export const cardGameGeneral = (nickname, game_id,unirsePartidaCallback) => { var cardGameDiv = document.createElement('div'); cardGameDiv.classList.add('cardGame'); cardGameDiv.innerHTML = `${nickname} VS - + `; const joinGameBtn = cardGameDiv.querySelector('.join-game-btn'); joinGameBtn.addEventListener('click', () => { - unirsePartida(game_id); + unirsePartidaCallback(game_id); }); return cardGameDiv; }; diff --git a/public/js/listapartidas.js b/public/js/listapartidas.js index 940967f..987b8e6 100644 --- a/public/js/listapartidas.js +++ b/public/js/listapartidas.js @@ -1,25 +1,26 @@ export class ListaPartidas { - _partidas = []; - constructor(partidas) { - this._partidas = partidas; - } - agregarPartida(partida) { - this._partidas.push(partida); - } - eliminaPartida(uuid){ - const index = this._partidas.findIndex((partida) => partida.uuid === uuid); - if (index !== -1) { - this._partidas.splice(index, 1); - } - } - get partidasAbiertas() { - return this._partidas.filter((partida) => partida.abierta); - } - getPartidasEnCurso(uuid) { - return this._partidas.filter((partida) => partida.uuid === uuid && !partida.abierta); - } - obtenerPartidaPorUuid(uuid) { - return this._partidas.find((partida) => partida.uuid === uuid); + _partidas = []; + constructor(partidas) { + this._partidas = partidas; + } + agregarPartida(partida) { + this._partidas.push(partida); + } + actualizarPartida(partidaActualizada) { + const index = this._partidas.findIndex( + (partida) => partida.uuid === partidaActualizada.uuid, + ); + if (index !== -1) { + this._partidas[index] = partidaActualizada; } } - \ No newline at end of file + eliminarPartida(uuid) { + const index = this._partidas.findIndex((partida) => partida.uuid === uuid); + if (index !== -1) { + this._partidas.splice(index, 1); + } + } + get partidas() { + return this._partidas; + } +} diff --git a/public/js/salaespera.js b/public/js/salaespera.js index 7f205b3..d98359a 100644 --- a/public/js/salaespera.js +++ b/public/js/salaespera.js @@ -11,125 +11,164 @@ const chat = document.querySelector('#logchat'); const userId = localStorage.getItem('userId'); const socket = io('/salachat', { closeOnBeforeunload: true, auth: { userId } }); -document.querySelector('#btnCerrar').addEventListener('click', () => { - cerrarSesion('buttonClick'); -}); -document.querySelector('#btnCrearPartida').addEventListener('click', () => { - crearPartida(); -}); -document.querySelector('#chatinput').addEventListener('keyup', (event) => { - enviarMensaje(event); -}); - let listaUsuarios; -let listaPartidas; +let listaPartidasAbiertas; -// Funciones que modifican el DOM -function agregarUsuarioToLista(usuario, listaElemento, claseCSS) { +// Función para generar elementos de lista de usuarios +function generarElementoListaUsuario(usuario, claseCSS) { const liUsuario = document.createElement('li'); - liUsuario.innerHTML = usuario.nickname; + liUsuario.textContent = usuario.nickname; liUsuario.classList.add(claseCSS); - listaElemento.appendChild(liUsuario); + return liUsuario; } -function listarUsuarios() { +// Función para actualizar la lista de usuarios +function actualizarListaUsuarios() { usersConnectUlEl.innerHTML = ''; usersDisconnectUlEl.innerHTML = ''; + const miUsuario = listaUsuarios.usuario; - agregarUsuarioToLista(miUsuario, usersConnectUlEl, 'spanNickPropio'); - const usuariosConectados = listaUsuarios.usuariosConectados; - usuariosConectados.forEach((usuario) => { - agregarUsuarioToLista(usuario, usersConnectUlEl, 'spanNick'); + usersConnectUlEl.appendChild( + generarElementoListaUsuario(miUsuario, 'spanNickPropio'), + ); + + listaUsuarios.usuariosConectados.forEach((usuario) => { + usersConnectUlEl.appendChild( + generarElementoListaUsuario(usuario, 'spanNick'), + ); }); - const usuariosDesconectados = listaUsuarios.usuariosDesconectados; - usuariosDesconectados.forEach((usuario) => { - agregarUsuarioToLista(usuario, usersDisconnectUlEl, 'spanNickOffline'); + + listaUsuarios.usuariosDesconectados.forEach((usuario) => { + usersDisconnectUlEl.appendChild( + generarElementoListaUsuario(usuario, 'spanNickOffline'), + ); }); } -function listarPartidasAbiertas() { - partidasAbiertasEl.innerHTML = ''; - listaPartidas.partidasAbiertas.forEach((partida) => { - const cardGame = - userId === partida.uuidJugadorA - ? cardGamePropia(partida.nickJugadorA, partida.uuid) - : cardGameGeneral(partida.nickJugadorA, partida.uuid); - partidasAbiertasEl.appendChild(cardGame); +// Función para generar elementos de la lista de partidas +function generarElementoListaPartida(partida) { + const cardGame = + userId === partida.uuidJugadorA + ? cardGamePropia( + partida.nickJugadorA, + partida.uuid, + onClickEliminarPartida, + ) + : cardGameGeneral( + partida.nickJugadorA, + partida.uuid, + onClickUnirsePartida, + ); + return cardGame; +} +// Función para actualizar la lista de partidas abiertas +function actualizarListaPartidasAbiertas() { + partidasAbiertasEl.innerHTML = 'Partidas abiertas'; + partidasProcesoEl.innerHTML = 'Tus partidas'; + + listaPartidasAbiertas.partidas.forEach((partida) => { + const cardGame = generarElementoListaPartida(partida); + userId === partida.uuidJugadorA || userId === partida.uuidJugadorB + ? partidasProcesoEl.appendChild(cardGame) + : partidasAbiertasEl.appendChild(cardGame); }); } -function agregaMsg({ uuid, msg }) { +// Función para agregar un mensaje al chat +function agregarMensajeAlChat({ uuid, msg }) { const spanUser = document.createElement('span'); + spanUser.textContent = + userId === uuid + ? 'Tú: ' + : `${listaUsuarios.obtenerUsuarioPorUuid(uuid).nickname}: `; + spanUser.classList.add(userId === uuid ? 'spanNickPropio' : 'spanNick'); + const spanMsg = document.createElement('span'); - if (userId === uuid) { - spanUser.classList.add('spanNickPropio'); - spanUser.textContent = `Tú: `; - spanMsg.textContent = msg; - } else { - spanUser.classList.add('spanNick'); - spanUser.textContent = `${listaUsuarios.obtenerUsuarioPorUuid(uuid).nickname}: `; - spanMsg.textContent = msg; - } + spanMsg.textContent = msg; + const linea = document.createElement('p'); linea.appendChild(spanUser); linea.appendChild(spanMsg); + chat.appendChild(linea); logchat.scrollTop = logchat.scrollHeight; } -function agregaMsgBroadcast(msg) { +// Función para agregar un mensaje de transmisión al chat +function agregarMensajeDeTransmisionAlChat(msg) { const spanMsg = document.createElement('span'); spanMsg.textContent = msg; spanMsg.classList.add('broadcastMsg'); + const linea = document.createElement('p'); linea.appendChild(spanMsg); + chat.appendChild(linea); logchat.scrollTop = logchat.scrollHeight; } -// Logica de negocio de la aplicacion -const entraSala = ({ usuarios, partidas }) => { - listaUsuarios = new ListaUsuarios(userId, usuarios); - listaPartidas = new ListaPartidas(partidas); - listarUsuarios(); - listarPartidasAbiertas(); -}; -const actualizaUsuarios = (usuario) => { - listaUsuarios.actualizaUsuario(usuario); - listarUsuarios(); - usuario.conectado - ? agregaMsgBroadcast(`${usuario.nickname} se ha conectado`) - : agregaMsgBroadcast(`${usuario.nickname} se ha desconectado`); -}; -const agregarPartida = (partida) => { - listaPartidas.agregarPartida(partida); - listarPartidasAbiertas(); +const handlers = { + onConnectRoom: ({ usuarios, partidas }) => { + listaUsuarios = new ListaUsuarios(userId, usuarios); + listaPartidasAbiertas = new ListaPartidas(partidas); + actualizarListaUsuarios(); + actualizarListaPartidasAbiertas(); + }, + onUserChangeStatus: (usuario) => { + listaUsuarios.actualizaUsuario(usuario); + actualizarListaUsuarios(); + const mensaje = usuario.conectado + ? `${usuario.nickname} se ha conectado` + : `${usuario.nickname} se ha desconectado`; + agregarMensajeDeTransmisionAlChat(mensaje); + }, + onMsgChat: (mensaje) => { + agregarMensajeAlChat(mensaje); + }, + onCreatePartida: (partida) => { + listaPartidasAbiertas.agregarPartida(partida); + actualizarListaPartidasAbiertas(); + }, + onJoinPartida: (partida) => { + listaPartidasAbiertas.eliminarPartida(partida); + actualizarListaPartidasAbiertas(); + }, + onCancelPartida: (uuid) => { + listaPartidasAbiertas.eliminarPartida(uuid); + actualizarListaPartidasAbiertas(); + }, + disconnect: (reason) => { + if (reason === 'io server disconnect' || reason === 'buttonClick') { + localStorage.removeItem('userId'); + window.location.replace('/'); + } + }, }; -// Cerrar sesión -const cerrarSesion = (reason) => { - if (reason === 'io server disconnect' || reason === 'buttonClick') { - localStorage.removeItem('userId'); - window.location.replace('/'); - } -}; -// Enviar mensaje -function enviarMensaje(event) { +Object.entries(handlers).forEach(([event, handler]) => { + socket.on(event, handler); +}); + +document.querySelector('#btnCerrar').addEventListener('click', () => { + handlers.disconnect('buttonClick'); +}); + +document.querySelector('#btnCrearPartida').addEventListener('click', () => { + socket.emit('createPartida', handlers.onCreatePartida); +}); + +document.querySelector('#chatinput').addEventListener('keyup', (event) => { if (event.key === 'Enter') { const mensaje = event.target.value.trim(); if (mensaje != '') { - socket.emit('chatMsg', mensaje, agregaMsg); + socket.emit('msgChat', mensaje, agregarMensajeAlChat); } event.target.value = ''; } -} -function crearPartida() { - socket.emit('creaPartida'); -} - -// Manejadores de eventos del socket -socket.on('onConnectRoom', entraSala); -socket.on('onUserConnectRoom', actualizaUsuarios); -socket.on('chatMsg', agregaMsg); -socket.on('onCrearPartida', agregarPartida); -socket.on('onUserDisconnectRoom', actualizaUsuarios); -socket.on('disconnect', cerrarSesion); +}); // // const url = '/batalla.html?game_id=' + encodeURIComponent(partida.uuid); // // window.open(url, '_blank'); + +function onClickEliminarPartida(game_id) { + socket.emit('cancelPartida', game_id, handlers.onCancelPartida); +} +function onClickUnirsePartida(game_id) { + socket.emit('joinPartida', game_id, handlers.onJoinPartida); +} diff --git a/public/salageneral.html b/public/salageneral.html index 15d6fa0..db57093 100644 --- a/public/salageneral.html +++ b/public/salageneral.html @@ -22,7 +22,7 @@ - +
@@ -32,17 +32,14 @@
- + - +
+ Tus partidas +
Partidas abiertas -
-
- Partidas -
-
diff --git a/public/style.css b/public/style.css index af78660..0185093 100644 --- a/public/style.css +++ b/public/style.css @@ -77,26 +77,64 @@ body { overflow-y: auto; } -input[type='submit'], -button { +/* Estilo base para los botones */ +.button { padding: 0.5rem 1rem; font-size: 1rem; border: none; border-radius: 0.4rem; - background-color: #ff5722; /* Color de fondo naranja */ - color: white; /* Color del texto blanco */ - cursor: pointer; /* Cambia el cursor al pasar sobre el botón */ - transition: background-color 0.3s ease; /* Transición suave al cambiar de color */ + color: white; + cursor: pointer; + transition: background-color 0.3s ease; } -input[type='submit']:hover, -button:hover { - background-color: #e64a19; /* Color de fondo naranja más oscuro al pasar el cursor */ + +/* Estilo para el botón naranja */ +.button-orange { + background-color: #ff5722; } -input[type='submit']:active, -button:active { - background-color: #bf360c; /* Color de fondo naranja más oscuro al hacer clic */ + +/* Estilo para el botón naranja claro al pasar el cursor */ +.button-orange:hover { + background-color: #e64a19; } -.cardGame button { + +/* Estilo para el botón naranja oscuro al hacer clic */ +.button-orange:active { + background-color: #bf360c; +} + +/* Estilo para el botón azul */ +.button-blue { + background-color: #2196f3; +} + +/* Estilo para el botón azul claro al pasar el cursor */ +.button-blue:hover { + background-color: #0d47a1; +} + +/* Estilo para el botón azul oscuro al hacer clic */ +.button-blue:active { + background-color: #002171; +} + +/* Estilo para el botón verde */ +.button-green { + background-color: #4caf50; +} + +/* Estilo para el botón verde claro al pasar el cursor */ +.button-green:hover { + background-color: #388e3c; +} + +/* Estilo para el botón verde oscuro al hacer clic */ +.button-green:active { + background-color: #1b5e20; +} + +/* Estilo para el botón personalizado dentro de la clase .cardGame */ +.cardGame .button { padding: 0 0.4rem; font-size: medium; width: 100%; @@ -167,26 +205,44 @@ button:active { animation-duration: 2s; animation-timing-function: linear; animation-iteration-count: infinite; - -webkit-animation-name:parpadeo; + -webkit-animation-name: parpadeo; -webkit-animation-duration: 2s; -webkit-animation-timing-function: linear; -webkit-animation-iteration-count: infinite; } -@-moz-keyframes parpadeo{ - 0% { opacity: 1.0; } - 50% { opacity: 0.0; } - 100% { opacity: 1.0; } +@-moz-keyframes parpadeo { + 0% { + opacity: 1; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } } -@-webkit-keyframes parpadeo { - 0% { opacity: 1.0; } - 50% { opacity: 0.0; } - 100% { opacity: 1.0; } +@-webkit-keyframes parpadeo { + 0% { + opacity: 1; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } } -@keyframes parpadeo { - 0% { opacity: 1.0; } - 50% { opacity: 0.0; } - 100% { opacity: 1.0; } -} \ No newline at end of file +@keyframes parpadeo { + 0% { + opacity: 1; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } +} diff --git a/src/sala-chat/sala-chat.gateway.ts b/src/sala-chat/sala-chat.gateway.ts index 68098e9..8a881ca 100644 --- a/src/sala-chat/sala-chat.gateway.ts +++ b/src/sala-chat/sala-chat.gateway.ts @@ -28,7 +28,7 @@ export class SalaChatGateway }); client.broadcast .to('chat_general') - .emit('onUserConnectRoom', userConectado); + .emit('onUserChangeStatus', userConectado); } else { client.disconnect(); } @@ -40,31 +40,52 @@ export class SalaChatGateway if (userDesconectado) { client.broadcast .to('chat_general') - .emit('onUserDisconnectRoom', userDesconectado); + .emit('onUserChangeStatus', userDesconectado); } client.leave('chat_general'); } - @SubscribeMessage('chatMsg') + @SubscribeMessage('msgChat') handleMsg(client: Socket, msg: string) { const userId = client.handshake.auth.userId; const user = this.salaChatService.getUsuarioUUID(userId); - if (user) { - client.broadcast.to('chat_general').emit('chatMsg',{ uuid: userId, msg }); - return { uuid: userId, msg }; - } else { - client.disconnect(); - } + client.broadcast + .to('chat_general') + .emit('onMsgChat', { uuid: userId, msg }); + return { uuid: userId, msg }; } sendBroadcastMsg(msg: string) { this.server.to('chat_general').emit('broadcastMsg', msg); } - @SubscribeMessage('creaPartida') - handleCreaPartida(client: Socket) { + @SubscribeMessage('createPartida') + handleCreatePartida(client: Socket) { const userId = client.handshake.auth.userId; const partida = this.salaChatService.creaPartida(userId); - this.server.to('chat_general').emit('onCrearPartida', partida); + client.broadcast.to('chat_general').emit('onCreatePartida', partida); + return partida; } -} + + @SubscribeMessage('cancelPartida') + handleCancelPartida(client: Socket, uuidPartida: string) { + const userId = client.handshake.auth.userId; + const uuidPartidaEliminado = this.salaChatService.eliminarPartida( + userId, + uuidPartida, + ); + if (uuidPartidaEliminado) + client.broadcast + .to('chat_general') + .emit('onCancelPartida', uuidPartidaEliminado); + return uuidPartidaEliminado; + } + + @SubscribeMessage('joinPartida') + handleJoinPartida(client: Socket, uuidPartida: string) { + const userId = client.handshake.auth.userId; + const partida = this.salaChatService.unirsePartida(userId, uuidPartida); + client.broadcast.to('chat_general').emit('onJoinPartida', partida); + return partida; + } +} \ No newline at end of file diff --git a/src/sala-chat/sala-chat.service.ts b/src/sala-chat/sala-chat.service.ts index 2cb4108..334b9db 100644 --- a/src/sala-chat/sala-chat.service.ts +++ b/src/sala-chat/sala-chat.service.ts @@ -59,4 +59,12 @@ export class SalaChatService { const partida = this.partidasService.creaPartida(uuidJugadorCreador); return partida; } + + unirsePartida(uuidJugadorB:string,uuidPartida:string){ + return this.partidasService.unirsePartida(uuidJugadorB,uuidPartida); + } + + eliminarPartida(uuidJugador:string, uuidPartida:string){ + return this.partidasService.eliminarPartida(uuidJugador,uuidPartida); + } } diff --git a/src/shared/partidas.service.ts b/src/shared/partidas.service.ts index 20b7d65..df0327b 100644 --- a/src/shared/partidas.service.ts +++ b/src/shared/partidas.service.ts @@ -27,9 +27,35 @@ export class PartidasService { creaPartida(uuidJugadorA: string) { const uuid = uuidv4(); - const nickJugadorA=this.usuariosService.usuarios.get(uuidJugadorA).nickname; - const partida = new Partida(uuid, uuidJugadorA,nickJugadorA); + const nickJugadorA = + this.usuariosService.usuarios.get(uuidJugadorA).nickname; + const partida = new Partida(uuid, uuidJugadorA, nickJugadorA); this._partidas.set(uuid, partida); return partida; } + + unirsePartida(uuidJugadorB: string, uuidPartida: string){ + const partida = this._partidas.get(uuidPartida); + const nickJugadorB = this.usuariosService.usuarios.get(uuidJugadorB)?.nickname; + partida.uuidJugadorB = uuidJugadorB; + partida.nickJugadorB = nickJugadorB; + partida.abierta = false; + return partida; + } + + + eliminarPartida(uuidJugador: string, uuidPartida: string) { + if (!this._partidas.has(uuidPartida)) { + return null; + } + const partida = this._partidas.get(uuidPartida); + if ( + partida.uuidJugadorA !== uuidJugador && + partida.uuidJugadorB !== uuidJugador + ) { + return null; + } + this._partidas.delete(uuidPartida); + return uuidPartida; + } }