diff --git a/backend/models/challenge.js b/backend/models/challenge.js new file mode 100644 index 0000000..4ddc587 --- /dev/null +++ b/backend/models/challenge.js @@ -0,0 +1,32 @@ +const { Schema, default: mongoose } = require("mongoose"); +const { String, ObjectId, Number } = Schema.Types; + +const challengeSchema = new Schema({ + challenger: { + type: String, + unique: true, + required: true, + }, + challenged: { + type: String, + unique: true, + required: true, + }, + color: { + type: String, + enum: ["b", "w"], + required: true, + }, + timeLimit: { + type: Number, + required: true, + }, + roomID: { + type: String, + required: true, + unique: true, + }, +}); + +const Challenge = mongoose.model("Challenge", challengeSchema); +module.exports = { Challenge }; diff --git a/backend/routes/room.js b/backend/routes/room.js index ab5c611..e704bb2 100644 --- a/backend/routes/room.js +++ b/backend/routes/room.js @@ -1,10 +1,10 @@ const router = require("express").Router(); const uuid = require("uuid"); const { createRoom } = require("../socket"); -const { User } = require("../models/user"); const { checkAuth } = require("../util/auth"); +const { Challenge } = require("../models/challenge"); -const pendingChallenges = new Map(); +async function fetchChallenge({ challenger, challenged }) {} // rooms can only be created through HTTP requests and destroyed only by socket.io server // and vice versa is not true @@ -13,6 +13,13 @@ router.post("/create", checkAuth, async (req, res, next) => { // challenger and challenged are username, color is the color played by challenger, timeLimit is the timeLimit for one player const { challenger, challenged, color, timeLimit } = req.body; + let challenge = await Challenge.findOne({ challenger }); + + // a user can create only one challenge at a time + if (challenge) { + return res.status(405).json({ success: false, error: { message: "Cannot create new challenge" } }); + } + // get email of the challenged person // const challengedEmail = (await User.findOne({ username: challenged })).email; // console.log(challengedEmail); @@ -20,17 +27,17 @@ router.post("/create", checkAuth, async (req, res, next) => { const roomID = uuid.v4(); createRoom(roomID, timeLimit); - // create a challenge and add it to pendingChallenges to notify the challenged user - // structure of challenge: {challenger,roomID,color,timeLimit} - if (pendingChallenges.has(challenged)) { - let challenges = pendingChallenges.get(challenged); - challenges.push({ challenger, roomID, color, timeLimit }); - } else { - // color is the choosed by the challenger - pendingChallenges.set(challenged, [{ challenger, roomID, color, timeLimit }]); - } + challenge = await Challenge.create({ challenger, challenged, color, timeLimit, roomID }); - console.log("Pending challenges", pendingChallenges); + // if (pendingChallenges.has(challenged)) { + // let challenges = pendingChallenges.get(challenged); + // challenges.push({ challenger, roomID, color, timeLimit }); + // } else { + // // color is the choosed by the challenger + // pendingChallenges.set(challenged, [{ challenger, roomID, color, timeLimit }]); + // } + + console.log("Pending challenge:", challenge); // STOP SENDING EMAILS FOR NOW // sendEmail( @@ -42,4 +49,3 @@ router.post("/create", checkAuth, async (req, res, next) => { }); module.exports = router; -module.exports.pendingChallenges = pendingChallenges; diff --git a/backend/routes/user.js b/backend/routes/user.js index 8dc18bc..5c32a34 100644 --- a/backend/routes/user.js +++ b/backend/routes/user.js @@ -1,7 +1,7 @@ const router = require("express").Router(); +const { Challenge } = require("../models/challenge"); const { User } = require("../models/user"); const { checkAuth } = require("../util/auth"); -const { pendingChallenges } = require("./room"); // TODO // get user details @@ -40,12 +40,28 @@ router.delete("/:username/friends/:friend_username", async (req, res, next) => { // get current challenges of the user router.get("/:username/challenges", async (req, res, next) => { let username = req.params.username; - let challenges = pendingChallenges.get(username); + let challenges = await Challenge.find({ challenged: username }); if (!challenges) challenges = []; - console.log(username, challenges); + console.log("Challenges to", username, challenges); res.json({ success: true, challenges: challenges }); }); +// accept or decline a challenge +// challengeID here refers to the roomID associated with the challenge +router.delete("/:username/challenges/:challengeID", async (req, res) => { + let challengeResponse = req.query.response; + let { challengeID } = req.params; + if (challengeResponse === "accept") { + let { deletedCount } = await Challenge.deleteOne({ roomID: challengeID }); + return res.json({ success: true }); + } else if (challengeResponse === "decline") { + let { deletedCount } = await Challenge.deleteOne({ roomID: challengeID }); + return res.json({ success: true }); + } else { + res.json({ success: false, error: { message: "Invalid query parameter" } }); + } +}); + // TODO // get history of games played router.get("/:username/games", async (req, res, next) => { diff --git a/backend/socket.js b/backend/socket.js index c67ac5d..30eb142 100644 --- a/backend/socket.js +++ b/backend/socket.js @@ -16,13 +16,13 @@ function getRoom(roomID) { } // structure of userDetails: {username,color} -function addUserToRoom(roomID, userDetails) { +function addUserToRoom(roomID, socket, userDetails) { console.log(userDetails); let { username, color } = userDetails; let room = activeRooms.get(roomID); if (room.players[username]) { - room.players[username] = { color }; + room.players[username] = { color, socket }; return JOIN_ROOM_SUCCESS; } if (Object.keys(room.players).length > 1) { @@ -30,7 +30,7 @@ function addUserToRoom(roomID, userDetails) { console.log(activeRooms); return ROOM_FULL; } else { - room.players[username] = { color }; + room.players[username] = { color, socket }; } console.log(activeRooms); @@ -57,7 +57,7 @@ function socketIOServerInit(server) { // structure: {username,color} socket.on(JOIN_ROOM, (roomID, data) => { if (activeRooms.has(roomID)) { - let result = addUserToRoom(roomID, data); + let result = addUserToRoom(roomID, socket, data); if (result === JOIN_ROOM_SUCCESS) { socket.join(roomID); io.to(roomID).emit("new user joined the room"); @@ -82,6 +82,7 @@ function socketIOServerInit(server) { } module.exports = { + activeRooms, createRoom, addUserToRoom, socketIOServerInit,