Redesign and fix dupe events

This commit is contained in:
2023-06-18 01:49:43 +03:00
parent 28ab992aa1
commit fc6ae4e245
9 changed files with 106 additions and 70 deletions

View File

@@ -3,6 +3,7 @@ import session from 'express-session';
import mongodb from 'mongodb';
import MongoStore from 'connect-mongo';
import cors from 'cors';
import crypto from 'crypto'
import { createNanoEvents } from 'nanoevents';
import "dotenv/config";
@@ -103,7 +104,6 @@ const client = new MongoClient(process.env.URI, { useUnifiedTopology: true });
}
let players = {}
let oldPlayers = {}
let score = {}
let card = await drawCard()
let oldCard = null;
@@ -257,6 +257,8 @@ const client = new MongoClient(process.env.URI, { useUnifiedTopology: true });
});
app.get('/api/stream', async (req, res) => {
const id = crypto.randomUUID()
res.set({
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache',
@@ -278,6 +280,7 @@ const client = new MongoClient(process.env.URI, { useUnifiedTopology: true });
players,
selected
}
res.write(`data: ${JSON.stringify(data)}\nevent: answer\n\n`);
answers += 1
@@ -295,12 +298,13 @@ const client = new MongoClient(process.env.URI, { useUnifiedTopology: true });
answers = 0
oldCard = { ...card }
card = await drawCard()
emitter.emit('allDone');
emitter.emit(`allDone-${id}`);
}
});
emitter.on('allDone', () => {
const data = {
const unbindAllDone = emitter.on(`allDone-${id}`, () => {
const data = {
correctAnswer: oldCard.name,
score
}

View File

@@ -28,6 +28,7 @@
:root {
--clr-bg: #ffd537;
--clr-accent: #37ffac;
--clr-text: #141414;
}
body {
@@ -35,16 +36,17 @@ body {
background-color: var(--clr-bg);
}
input, button {
font: inherit;
}
#app {
font-family: "Pangram Sans Rounded", Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: black;
margin-top: 60px;
}
#game {
margin-bottom: 100px;
color: var(--clr-text);
min-height: 100vh;
box-sizing: border-box;
}
</style>

View File

@@ -2,7 +2,7 @@
$resulting-shadow: null;
@for $i from 1 through $distance {
$resulting-shadow: $resulting-shadow, #{$i}px #{$i}px 0 black;
$resulting-shadow: $resulting-shadow, #{$i}px #{$i}px 0 var(--clr-text);
}
box-shadow: $resulting-shadow;

View File

@@ -22,10 +22,10 @@ function endGame() {
<style scoped lang="scss">
.end {
position: fixed;
bottom: 8px;
left: 50%;
transform: translateX(-50%);
// position: fixed;
// bottom: 8px;
// left: 50%;
// transform: translateX(-50%);
}
.endButton {
@@ -33,7 +33,7 @@ function endGame() {
border: none;
font: inherit;
padding: 8px 12px;
border-bottom: 1px dotted black;
border-bottom: 1px dotted var(--clr-text);
&:hover {
cursor: pointer;

View File

@@ -1,5 +1,5 @@
<template>
<h1>Флекспатруль мультиплеер</h1>
<h1 class="header">Флекспатруль мультиплеер</h1>
<div class="main">
<div
@@ -12,16 +12,14 @@
>
<h2>Кто скинул этот мем?</h2>
<div class="interactive">
<transition name="fade-answers">
<transition name="fade-answers" mode="out-in">
<List
v-if="!showResult"
:options="options"
@selectedAnswer="selectAnswer"
/>
</transition>
<transition name="spin-result">
<Result
v-if="showResult"
v-else
:selectedName="selectedAnswer"
:correct="correctAnswer"
/>
@@ -97,19 +95,32 @@ onMounted(async () => {
</script>
<style scoped lang="scss">
.header {
padding: 60px;
margin: auto;
height: 42px;
}
.main {
padding-bottom: 200px;
position: relative;
min-height: calc(100vh - 162px);
box-sizing: border-box;
padding: 8px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.card {
width: 450px;
margin: auto;
margin: 0 auto;
min-height: 0;
}
.meme {
width: 100%;
border-radius: 32px;
border: 3px solid black;
border: 3px solid var(--clr-text);
@include filled-shadow(16);
transform: translateX(-8px);
}
@@ -120,11 +131,6 @@ onMounted(async () => {
.interactive {
position: relative;
> * {
position: absolute;
width: 100%;
}
}
.fade-answers-leave-active {
@@ -135,14 +141,6 @@ onMounted(async () => {
transform: scale(0.3);
}
.spin-result-enter-active {
transition: all 2s ease;
}
.spin-result-enter-from {
transform: scale(0.2);
transform: rotateY(120deg);
}
.loader {
margin-top: 100px;
}

View File

@@ -31,12 +31,12 @@ export default {
<style scoped>
.result {
padding: 30px 40px;
border-radius: 8px;
border-radius: 32px;
background-color: white;
}
.correct {
color: black;
color: var(--clr-text);
background-color: var(--clr-accent);
}

View File

@@ -1,6 +1,4 @@
<template>
<h1>Флекспатруль мультиплеер</h1>
<div class="authCard">
<h1>Авторизация:</h1>
@@ -9,21 +7,25 @@
<input
placeholder="Ответ"
v-model="answer"
class="input"
>
<input
v-if="mode === 'player'"
placeholder="Ваше имя"
v-model="username"
class="input"
>
<button
v-if="mode === 'player'"
class="login"
@click="loginPlayer"
>
Войти как игрок
</button>
<button
v-else
class="login"
@click="loginScreen"
>
Войти как большой экран
@@ -31,7 +33,7 @@
<button
@click="switchMode"
class="secondary"
class="switchMode"
>
Я не {{ mode === 'player' ? 'игрок' : 'большой экран' }}!
</button>
@@ -60,6 +62,10 @@ function switchMode() {
}
async function loginPlayer() {
if (!answer.value || !username.value) {
return
}
store.username = username.value
await axios
@@ -83,7 +89,7 @@ async function loginScreen() {
}
</script>
<style scoped>
<style scoped lang="scss">
.auth {
display: flex;
gap: 16px;
@@ -92,43 +98,68 @@ async function loginScreen() {
}
.authCard {
background-color: #121212;
color: white;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: var(--clr-text);
color: var(--clr-text);
width: 400px;
margin: auto;
border-radius: 18px;
padding: 40px 10px;
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.6);
border-radius: 32px;
padding: 40px 40px;
box-sizing: border-box;
background: white;
border: 3px solid var(--clr-text);
@include filled-shadow(16);
}
input {
font-size: 1em;
text-align: center;
padding: 5px 8px;
border-radius: 6px;
border: none;
width: 20ch;
.input {
font-size: 16px;
padding: 16px;
border: 2px solid var(--clr-text);
width: 100%;
box-sizing: border-box;
@include filled-shadow(4);
border-radius: 12px;
&:focus {
outline: none;
}
}
button {
color: white;
font-size: 1em;
box-sizing: content-box;
background-color: #5a5a5a;
border-radius: 6px;
.login {
color: var(--clr-text);
font-size: 16px;
box-sizing: border-box;
background-color: var(--clr-bg);
border: none;
width: 20ch;
padding: 5px 8px;
width: 100%;
padding: 16px;
cursor: pointer;
border: 2px solid var(--clr-text);
@include filled-shadow(4);
border-radius: 12px;
}
button.secondary {
background: #919191;
.switchMode {
position: absolute;
color: var(--clr-text);
background: var(--clr-accent);
font-size: 12px;
width: 70px;
height: 70px;
border-radius: 100px;
border: 2px solid var(--clr-text);
left: 0;
bottom: 0;
transform: translate(-50%, 50%);
cursor: pointer;
@include filled-shadow(4);
}
@media only screen and (max-width: 520px) {
div {
.authCard {
width: 100%;
padding: 40px 0;
}

View File

@@ -25,7 +25,7 @@ const position = reactive({
border-radius: 32px;
font-size: 30px;
padding: 32px;
border: 3px solid black;
border: 3px solid var(--clr-text);
top: 50%;
left: 50%;
font-weight: 600;

View File

@@ -148,7 +148,7 @@ onMounted(() => {
padding: 64px;
background: var(--clr-bg);
box-sizing: border-box;
color: black;
color: var(--clr-text);
}
.image {
@@ -158,7 +158,8 @@ onMounted(() => {
object-fit: contain;
margin-top: auto;
margin-bottom: auto;
border: 3px solid black;
background: var(--clr-text);
border: 3px solid var(--clr-text);
@include filled-shadow(16);
border-radius: 64px;
animation-name: rock;
@@ -187,7 +188,7 @@ onMounted(() => {
}
.users.-unanwsered {
border-right: 1px dashed black;
border-right: 1px dashed var(--clr-text);
}
.user.-correct {