added vote countdown & alert

This commit is contained in:
Steffen 2020-12-05 22:24:55 +01:00
parent 40087a3478
commit dcff59a183
5 changed files with 137 additions and 12 deletions

View File

@ -328,6 +328,7 @@ ul {
&.disabled { &.disabled {
color: gray; color: gray;
cursor: default; cursor: default;
opacity: 0.75;
} }
&:before, &:before,
&:after { &:after {

Binary file not shown.

View File

@ -21,14 +21,14 @@
<em>majority</em>. <em>majority</em>.
</template> </template>
<div v-if="session.lockedVote > 1"> <div v-if="session.isVoteInProgress">
<em class="blue" v-if="voters.length">{{ voters.join(", ") }} </em> <em class="blue" v-if="voters.length">{{ voters.join(", ") }} </em>
<span v-else>nobody</span> <span v-else>nobody</span>
had their hand <em>UP</em> had their hand <em>UP</em>
</div> </div>
<template v-if="!session.isSpectator"> <template v-if="!session.isSpectator">
<div v-if="!session.lockedVote"> <div v-if="!session.isVoteInProgress">
Time per player: Time per player:
<font-awesome-icon <font-awesome-icon
@mousedown.prevent="setVotingSpeed(-500)" @mousedown.prevent="setVotingSpeed(-500)"
@ -43,13 +43,20 @@
<div class="button-group"> <div class="button-group">
<div <div
class="button townsfolk" class="button townsfolk"
v-if="!session.lockedVote" v-if="!session.isVoteInProgress"
@click="start" @click="countdown"
> >
Countdown
</div>
<div class="button" v-if="!session.isVoteInProgress" @click="start">
Start Start
</div> </div>
<template v-else> <template v-else>
<div class="button townsfolk" @click="pause"> <div
class="button townsfolk"
:class="{ disabled: !session.lockedVote }"
@click="pause"
>
{{ voteTimer ? "Pause" : "Resume" }} {{ voteTimer ? "Pause" : "Resume" }}
</div> </div>
<div class="button" @click="stop">Reset</div> <div class="button" @click="stop">Reset</div>
@ -58,8 +65,8 @@
</div> </div>
</template> </template>
<template v-else-if="canVote"> <template v-else-if="canVote">
<div v-if="!session.lockedVote"> <div v-if="!session.isVoteInProgress">
{{ session.votingSpeed }} seconds between votes {{ session.votingSpeed / 1000 }} seconds between votes
</div> </div>
<div class="button-group"> <div class="button-group">
<div <div
@ -82,6 +89,18 @@
Please claim a seat to vote. Please claim a seat to vote.
</div> </div>
</div> </div>
<transition name="blur">
<div
class="countdown"
v-if="session.isVoteInProgress && !session.lockedVote"
>
<span>3</span>
<span>2</span>
<span>1</span>
<span>GO</span>
<audio autoplay src="../assets/sounds/countdown.mp3"></audio>
</div>
</transition>
</div> </div>
</template> </template>
@ -153,13 +172,21 @@ export default {
}; };
}, },
methods: { methods: {
countdown() {
this.$store.commit("session/setVoteInProgress", true);
this.voteTimer = setInterval(() => {
this.start();
}, 4000);
},
start() { start() {
this.$store.commit("session/setVoteInProgress", true);
this.$store.commit("session/lockVote"); this.$store.commit("session/lockVote");
clearInterval(this.voteTimer); clearInterval(this.voteTimer);
this.voteTimer = setInterval(() => { this.voteTimer = setInterval(() => {
this.$store.commit("session/lockVote"); this.$store.commit("session/lockVote");
if (this.session.lockedVote > this.players.length) { if (this.session.lockedVote > this.players.length) {
clearInterval(this.voteTimer); clearInterval(this.voteTimer);
this.$store.commit("session/setVoteInProgress", false);
} }
}, this.session.votingSpeed); }, this.session.votingSpeed);
}, },
@ -173,6 +200,8 @@ export default {
}, },
stop() { stop() {
clearInterval(this.voteTimer); clearInterval(this.voteTimer);
this.voteTimer = null;
this.$store.commit("session/setVoteInProgress", false);
this.$store.commit("session/lockVote", 0); this.$store.commit("session/lockVote", 0);
}, },
finish() { finish() {
@ -293,7 +322,78 @@ export default {
} }
} }
.button.disabled { @keyframes countdown {
opacity: 0.75; 0% {
transform: scale(1.5);
opacity: 0;
filter: blur(20px);
}
10% {
opacity: 1;
}
50% {
transform: scale(1);
filter: blur(0);
}
90% {
color: $townsfolk;
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes countdown-go {
0% {
transform: scale(1.5);
opacity: 0;
filter: blur(20px);
}
10% {
opacity: 1;
}
50% {
transform: scale(1);
filter: blur(0);
}
90% {
color: $demon;
opacity: 1;
}
100% {
opacity: 0;
}
}
.countdown {
display: flex;
position: absolute;
align-items: center;
justify-content: center;
pointer-events: none;
audio {
height: 0;
width: 0;
visibility: hidden;
}
span {
position: absolute;
font-size: 8em;
font-weight: bold;
opacity: 0;
}
span:nth-child(1) {
animation: countdown 1100ms normal forwards;
}
span:nth-child(2) {
animation: countdown 1100ms normal forwards 1000ms;
}
span:nth-child(3) {
animation: countdown 1100ms normal forwards 2000ms;
}
span:nth-child(4) {
animation: countdown-go 1100ms normal forwards 3000ms;
}
} }
</style> </style>

View File

@ -28,7 +28,8 @@ const state = () => ({
nomination: false, nomination: false,
votes: [], votes: [],
lockedVote: 0, lockedVote: 0,
votingSpeed: 3000 votingSpeed: 3000,
isVoteInProgress: false
}); });
const getters = {}; const getters = {};
@ -43,12 +44,17 @@ const mutations = {
setPlayerCount: set("playerCount"), setPlayerCount: set("playerCount"),
setPing: set("ping"), setPing: set("ping"),
setVotingSpeed: set("votingSpeed"), setVotingSpeed: set("votingSpeed"),
setVoteInProgress: set("isVoteInProgress"),
claimSeat: set("claimedSeat"), claimSeat: set("claimedSeat"),
nomination(state, { nomination, votes, votingSpeed, lockedVote } = {}) { nomination(
state,
{ nomination, votes, votingSpeed, lockedVote, isVoteInProgress } = {}
) {
state.nomination = nomination || false; state.nomination = nomination || false;
state.votes = votes || []; state.votes = votes || [];
state.votingSpeed = votingSpeed || state.votingSpeed; state.votingSpeed = votingSpeed || state.votingSpeed;
state.lockedVote = lockedVote || 0; state.lockedVote = lockedVote || 0;
state.isVoteInProgress = isVoteInProgress || false;
}, },
/** /**
* Store a vote with and without syncing it to the live session. * Store a vote with and without syncing it to the live session.

View File

@ -146,6 +146,10 @@ class LiveSession {
if (!this._isSpectator) return; if (!this._isSpectator) return;
this._store.commit("session/setVotingSpeed", params); this._store.commit("session/setVotingSpeed", params);
break; break;
case "isVoteInProgress":
if (!this._isSpectator) return;
this._store.commit("session/setVoteInProgress", params);
break;
case "vote": case "vote":
this._handleVote(params); this._handleVote(params);
break; break;
@ -218,6 +222,7 @@ class LiveSession {
nomination: session.nomination, nomination: session.nomination,
votingSpeed: session.votingSpeed, votingSpeed: session.votingSpeed,
lockedVote: session.lockedVote, lockedVote: session.lockedVote,
isVoteInProgress: session.isVoteInProgress,
fabled: fabled.map(({ id }) => id), fabled: fabled.map(({ id }) => id),
...(session.nomination ? { votes: session.votes } : {}) ...(session.nomination ? { votes: session.votes } : {})
}); });
@ -237,6 +242,7 @@ class LiveSession {
votingSpeed, votingSpeed,
votes, votes,
lockedVote, lockedVote,
isVoteInProgress,
fabled fabled
} = data; } = data;
this._store.commit("toggleNight", isNight); this._store.commit("toggleNight", isNight);
@ -244,7 +250,8 @@ class LiveSession {
nomination, nomination,
votes, votes,
votingSpeed, votingSpeed,
lockedVote lockedVote,
isVoteInProgress
}); });
this._store.commit("players/setFabled", { this._store.commit("players/setFabled", {
fabled: fabled.map(id => this._store.state.fabled.get(id)) fabled: fabled.map(id => this._store.state.fabled.get(id))
@ -526,6 +533,14 @@ class LiveSession {
} }
} }
/**
* Set the isVoteInProgress status. ST only
*/
setVoteInProgress() {
if (this._isSpectator) return;
this._send("isVoteInProgress", this._store.state.session.isVoteInProgress);
}
/** /**
* Send the isNight status. ST only * Send the isNight status. ST only
*/ */
@ -649,6 +664,9 @@ export default store => {
case "session/nomination": case "session/nomination":
session.nomination(payload); session.nomination(payload);
break; break;
case "session/setVoteInProgress":
session.setVoteInProgress(payload);
break;
case "session/voteSync": case "session/voteSync":
session.vote(payload); session.vote(payload);
break; break;