diff --git a/backend/index.js b/backend/index.js
index c3cda72..56e468f 100644
--- a/backend/index.js
+++ b/backend/index.js
@@ -1,24 +1,27 @@
-const express = require('express');
-const session = require('express-session');
+import express from 'express';
+import session from 'express-session';
+import mongodb from 'mongodb';
+import MongoStore from 'connect-mongo';
+import cors from 'cors';
+import { createNanoEvents } from 'nanoevents';
+
+import "dotenv/config";
+
+import names from './names.json' assert { type: "json" };
const app = express();
-const { MongoClient, ObjectId } = require('mongodb');
-const MongoStore = require('connect-mongo');
-const cors = require('cors');
-require('dotenv').config();
+
+const emitter = createNanoEvents();
+const { MongoClient, ObjectId } = mongodb;
app.use(cors({
- origin: [
- process.env.FRONTEND,
- ],
+ origin: process.env.FRONTEND,
credentials: true,
exposedHeaders: ['set-cookie'],
}));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
-const names = require('./names.json');
-
const client = new MongoClient(process.env.URI, { useUnifiedTopology: true });
(async () => {
@@ -139,34 +142,40 @@ const client = new MongoClient(process.env.URI, { useUnifiedTopology: true });
}
});
+ const state = {}
app.post('/api/answer', async (req, res) => {
- if (req.session.loggedIn) {
- if (req.body.data.id && req.body.data.name) {
- const card = await cardsCollection.findOne({ _id: ObjectId(req.body.data.id) });
- if (card) {
- const correct = card.name === req.body.data.name;
- if (correct) {
- req.session.right += 1;
- } else {
- req.session.wrong += 1;
- }
- answersCollection.insertOne({
- correct,
- selected: req.body.data.name,
- });
- res.status(200).send({
- correct,
- card,
- });
- } else {
- res.status(500).send();
- }
- } else {
- res.status(400).send();
- }
- } else {
- res.status(403).send();
+ if (!req.session.loggedIn) {
+ return res.status(403).send();
}
+
+ if (!req.body.data.id || !req.body.data.name || !req.body.data.username) {
+ return res.status(400).send();
+ }
+
+ const card = await cardsCollection.findOne({ _id: ObjectId(req.body.data.id) });
+ if (!card) {
+ return res.status(500).send();
+ }
+
+ const correct = card.name === req.body.data.name;
+ if (correct) {
+ req.session.right += 1;
+ } else {
+ req.session.wrong += 1;
+ }
+ answersCollection.insertOne({
+ correct,
+ selected: req.body.data.name,
+ });
+
+ state[req.body.data.username] = true
+ emitter.emit('answer', req.body.data.username);
+
+ // return res.status(200).send({
+ // correct,
+ // card,
+ // });
+ return res.status(200).send()
});
app.get('/api/score', (req, res) => {
@@ -219,5 +228,73 @@ const client = new MongoClient(process.env.URI, { useUnifiedTopology: true });
}
});
+ let usernames = new Set();
+ app.post('/api/connect', async (req, res) => {
+ if (!req.session.loggedIn) {
+ return res.status(403).send();
+ }
+
+ const { username } = req.body;
+ usernames.add(username);
+ state[username] = false;
+ emitter.emit('connection', usernames)
+
+ return res.status(200).send();
+ });
+
+ app.post('/api/end', async (req, res) => {
+ if (!req.session.loggedIn) {
+ return res.status(403).send();
+ }
+
+ usernames = new Set();
+ state = {}
+ return res.status(200).send();
+ });
+
+ app.get('/api/stream', async (req, res) => {
+ res.set({
+ 'Access-Control-Allow-Origin': '*',
+ 'Cache-Control': 'no-cache',
+ Connection: 'keep-alive',
+ 'Content-Type': 'text/event-stream',
+ });
+ res.flushHeaders();
+
+ emitter.on('connection', (usernames) => {
+ const data = usernames
+ res.write(`data: ${JSON.stringify(data)}\nevent: userlist\n\n`);
+ })
+
+ emitter.on('answer', (username) => {
+ const data = {
+ username,
+ state
+ }
+ res.write(`data: ${JSON.stringify(data)}\nevent: answer\n\n`);
+ });
+
+ emitter.on('allDone', () => {
+ const data = {}
+ res.write(`data: ${JSON.stringify(data)}\nevent: reveal\n\n`);
+ });
+
+ res.on('close', () => {
+ res.end();
+ });
+ });
+
+ let answers = 0;
+ emitter.on('answer', () => {
+ answers += 1;
+
+ if (answers === usernames.length) {
+ Object.keys(state).forEach((key) => {
+ state[key] = false
+ })
+ emitter.emit('allDone');
+ }
+ });
+
app.listen(process.env.PORT, () => console.log(`Server started on ${process.env.PORT}`));
})();
diff --git a/backend/package.json b/backend/package.json
index 2f3ce3b..22f48a1 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -3,6 +3,7 @@
"version": "1.0.0",
"description": "",
"main": "index.js",
+ "type": "module",
"scripts": {
"dev": "nodemon index.js"
},
@@ -19,7 +20,8 @@
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-session": "^1.17.1",
- "mongodb": "^3.6.5"
+ "mongodb": "^3.6.5",
+ "nanoevents": "^7.0.1"
},
"eslintConfig": {
"extends": "airbnb-base",
diff --git a/backend/yarn.lock b/backend/yarn.lock
index ac39a9c..9ad157c 100644
--- a/backend/yarn.lock
+++ b/backend/yarn.lock
@@ -1193,6 +1193,11 @@ ms@2.1.3, ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+nanoevents@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/nanoevents/-/nanoevents-7.0.1.tgz#181580b47787688d8cac775b977b1cf24e26e570"
+ integrity sha512-o6lpKiCxLeijK4hgsqfR6CNToPyRU3keKyyI6uwuHRvpRTbZ0wXw51WRgyldVugZqoJfkGFrjrIenYH3bfEO3Q==
+
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
diff --git a/frontend/package.json b/frontend/package.json
index ae355dd..cb0666d 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -11,7 +11,10 @@
"dependencies": {
"axios": "^0.21.1",
"core-js": "^3.6.5",
- "vue": "^3.0.0",
+ "pinia": "^2.1.4",
+ "vue": "^3.3.4",
+ "vue-peel": "^0.1.1",
+ "vue-router": "4",
"vue-spinner": "^1.0.4"
},
"devDependencies": {
@@ -30,7 +33,7 @@
"node": true
},
"extends": [
- "plugin:vue/vue3-essential",
+ "plugin:vue/vue3-recommended",
"eslint:recommended"
],
"parserOptions": {
diff --git a/frontend/public/index.html b/frontend/public/index.html
index 062393e..9c03737 100644
--- a/frontend/public/index.html
+++ b/frontend/public/index.html
@@ -9,7 +9,7 @@
-
<%= htmlWebpackPlugin.options.title %>
+ Флекспатруль мультиплеер