mirror of
https://github.com/bra1n/townsquare.git
synced 2025-04-04 22:24:36 +00:00
Add a timer
This commit is contained in:
parent
9bafcc2c61
commit
045f7112e0
9 changed files with 330 additions and 38 deletions
|
@ -1,5 +1,8 @@
|
||||||
# Release Notes
|
# Release Notes
|
||||||
|
|
||||||
|
### Version 2.15.4
|
||||||
|
- add timer
|
||||||
|
|
||||||
### Version 2.15.3
|
### Version 2.15.3
|
||||||
- add Huntsman/Damsel to list of available characters
|
- add Huntsman/Damsel to list of available characters
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,10 @@ export default {
|
||||||
if (this.session.isSpectator) return;
|
if (this.session.isSpectator) return;
|
||||||
this.$refs.menu.toggleNight();
|
this.$refs.menu.toggleNight();
|
||||||
break;
|
break;
|
||||||
|
case "t":
|
||||||
|
if (this.session.isSpectator) return;
|
||||||
|
this.$refs.menu.toggleTimer();
|
||||||
|
break;
|
||||||
case "escape":
|
case "escape":
|
||||||
this.$store.commit("toggleModal");
|
this.$store.commit("toggleModal");
|
||||||
}
|
}
|
||||||
|
|
173
src/components/CountdownTimer.vue
Normal file
173
src/components/CountdownTimer.vue
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
<template>
|
||||||
|
<div class="countdown-timer">
|
||||||
|
<div
|
||||||
|
id="timer"
|
||||||
|
v-bind:style="[
|
||||||
|
remainingSeconds <= 30 ? { color: 'red' } : { color: 'white' }
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
{{ formattedMinutes }}:{{ formattedSeconds }}
|
||||||
|
</div>
|
||||||
|
<div class="timer-control" v-if="!session.isSpectator">
|
||||||
|
<div class="timer-button" @click="startTimer" v-if="!isTicking">
|
||||||
|
<font-awesome-icon icon="play"></font-awesome-icon>
|
||||||
|
</div>
|
||||||
|
<div class="timer-button" @click="pauseTimer" v-if="isTicking">
|
||||||
|
<font-awesome-icon icon="pause"></font-awesome-icon>
|
||||||
|
</div>
|
||||||
|
<div class="timer-button" @click="stopTimer">
|
||||||
|
<font-awesome-icon icon="stop"></font-awesome-icon>
|
||||||
|
</div>
|
||||||
|
<div class="timer-button" @click="addMinute" v-if="!isTicking">
|
||||||
|
<font-awesome-icon icon="plus"></font-awesome-icon>
|
||||||
|
</div>
|
||||||
|
<div class="timer-button" @click="subtractMinute" v-if="!isTicking">
|
||||||
|
<font-awesome-icon icon="minus"></font-awesome-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "CountdownTimer",
|
||||||
|
computed: {
|
||||||
|
...mapState(["session"]),
|
||||||
|
remainingSeconds: {
|
||||||
|
get: function() {
|
||||||
|
return this.$store.state.countdownTimer.remainingSeconds;
|
||||||
|
},
|
||||||
|
set: function(newValue) {
|
||||||
|
this.$store.state.countdownTimer.remainingSeconds = newValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
totalSeconds: {
|
||||||
|
get: function() {
|
||||||
|
return this.$store.state.countdownTimer.totalSeconds;
|
||||||
|
},
|
||||||
|
set: function(newValue) {
|
||||||
|
this.$store.state.countdownTimer.totalSeconds = newValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isTicking: {
|
||||||
|
get: function() {
|
||||||
|
return this.$store.state.countdownTimer.isTicking;
|
||||||
|
},
|
||||||
|
set: function(newValue) {
|
||||||
|
this.$store.state.countdownTimer.isTicking = newValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formattedMinutes() {
|
||||||
|
let minutes = Math.floor(this.remainingSeconds / 60);
|
||||||
|
if (minutes < 10) {
|
||||||
|
minutes = "0" + minutes;
|
||||||
|
}
|
||||||
|
return minutes;
|
||||||
|
},
|
||||||
|
formattedSeconds() {
|
||||||
|
let seconds = this.remainingSeconds % 60;
|
||||||
|
if (seconds < 10) {
|
||||||
|
seconds = "0" + seconds;
|
||||||
|
}
|
||||||
|
return seconds;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
clearInterval(this.timerInterval);
|
||||||
|
if (this.isTicking) {
|
||||||
|
this.timerInterval = setInterval(this.elapseTimer, 1000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: () => {
|
||||||
|
return {
|
||||||
|
timerInterval: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
startTimer() {
|
||||||
|
clearInterval(this.timerInterval);
|
||||||
|
if (this.remainingSeconds === 0) {
|
||||||
|
this.remainingSeconds = this.totalSeconds;
|
||||||
|
}
|
||||||
|
this.isTicking = true;
|
||||||
|
this.sendTimerUpdate();
|
||||||
|
this.timerInterval = setInterval(this.elapseTimer, 1000);
|
||||||
|
},
|
||||||
|
pauseTimer() {
|
||||||
|
clearInterval(this.timerInterval);
|
||||||
|
this.isTicking = false;
|
||||||
|
this.sendTimerUpdate();
|
||||||
|
},
|
||||||
|
stopTimer() {
|
||||||
|
clearInterval(this.timerInterval);
|
||||||
|
this.remainingSeconds = this.totalSeconds;
|
||||||
|
this.pauseTimer();
|
||||||
|
},
|
||||||
|
sendTimerUpdate() {
|
||||||
|
if (this.session.isSpectator) return;
|
||||||
|
let payload = {
|
||||||
|
remainingSeconds: this.remainingSeconds,
|
||||||
|
totalSeconds: this.totalSeconds,
|
||||||
|
isTicking: this.isTicking
|
||||||
|
};
|
||||||
|
this.$store.commit("session/distributeTimerAction", payload);
|
||||||
|
},
|
||||||
|
elapseTimer() {
|
||||||
|
if (this.remainingSeconds <= 0) {
|
||||||
|
clearInterval(this.timerInterval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.remainingSeconds--;
|
||||||
|
|
||||||
|
// Update local state on ST, so if a player joins while timer is ticking, they will get updated timer state.
|
||||||
|
if (!this.session.isSpectator) {
|
||||||
|
let payload = {
|
||||||
|
remainingSeconds: this.remainingSeconds,
|
||||||
|
totalSeconds: this.totalSeconds,
|
||||||
|
isTicking: this.isTicking
|
||||||
|
};
|
||||||
|
this.$store.commit("session/updateTimerState", payload);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addMinute() {
|
||||||
|
this.totalSeconds += 60;
|
||||||
|
this.remainingSeconds += 60;
|
||||||
|
this.sendTimerUpdate();
|
||||||
|
},
|
||||||
|
subtractMinute() {
|
||||||
|
this.totalSeconds = Math.max(0, this.totalSeconds - 60);
|
||||||
|
this.remainingSeconds = Math.max(0, this.remainingSeconds - 60);
|
||||||
|
this.sendTimerUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.countdown-timer {
|
||||||
|
border-color: white;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: thick;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 5px 5px 5px;
|
||||||
|
}
|
||||||
|
.timer-control {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
.timer-button {
|
||||||
|
margin: 0 5px 0 5px;
|
||||||
|
filter: drop-shadow(0 2px 1px black);
|
||||||
|
}
|
||||||
|
#timer {
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: 0 2px 1px black, 0 -2px 1px black, 2px 0 1px black,
|
||||||
|
-2px 0 1px black;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -138,6 +138,10 @@
|
||||||
Send Characters
|
Send Characters
|
||||||
<em><font-awesome-icon icon="theater-masks"/></em>
|
<em><font-awesome-icon icon="theater-masks"/></em>
|
||||||
</li>
|
</li>
|
||||||
|
<li v-if="!session.isSpectator" @click="toggleTimer">
|
||||||
|
Toggle timer
|
||||||
|
<em>[T]</em>
|
||||||
|
</li>
|
||||||
<li
|
<li
|
||||||
v-if="session.voteHistory.length || !session.isSpectator"
|
v-if="session.voteHistory.length || !session.isSpectator"
|
||||||
@click="toggleModal('voteHistory')"
|
@click="toggleModal('voteHistory')"
|
||||||
|
@ -345,6 +349,9 @@ export default {
|
||||||
this.$store.commit("session/setMarkedPlayer", -1);
|
this.$store.commit("session/setMarkedPlayer", -1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
toggleTimer() {
|
||||||
|
this.$store.commit("toggleTimer");
|
||||||
|
},
|
||||||
...mapMutations([
|
...mapMutations([
|
||||||
"toggleGrimoire",
|
"toggleGrimoire",
|
||||||
"toggleMenu",
|
"toggleMenu",
|
||||||
|
|
|
@ -46,39 +46,47 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="fabled" :class="{ closed: !isFabledOpen }" v-if="fabled.length">
|
<div id="top-left">
|
||||||
<h3>
|
<div
|
||||||
<span>Fabled</span>
|
class="fabled"
|
||||||
<font-awesome-icon icon="times-circle" @click.stop="toggleFabled" />
|
:class="{ closed: !isFabledOpen }"
|
||||||
<font-awesome-icon icon="plus-circle" @click.stop="toggleFabled" />
|
v-if="fabled.length"
|
||||||
</h3>
|
>
|
||||||
<ul>
|
<h3>
|
||||||
<li
|
<span>Fabled</span>
|
||||||
v-for="(role, index) in fabled"
|
<font-awesome-icon icon="times-circle" @click.stop="toggleFabled" />
|
||||||
:key="index"
|
<font-awesome-icon icon="plus-circle" @click.stop="toggleFabled" />
|
||||||
@click="removeFabled(index)"
|
</h3>
|
||||||
>
|
<ul>
|
||||||
<div
|
<li
|
||||||
class="night-order first"
|
v-for="(role, index) in fabled"
|
||||||
v-if="nightOrder.get(role).first && grimoire.isNightOrder"
|
:key="index"
|
||||||
|
@click="removeFabled(index)"
|
||||||
>
|
>
|
||||||
<em>{{ nightOrder.get(role).first }}.</em>
|
<div
|
||||||
<span v-if="role.firstNightReminder">{{
|
class="night-order first"
|
||||||
role.firstNightReminder
|
v-if="nightOrder.get(role).first && grimoire.isNightOrder"
|
||||||
}}</span>
|
>
|
||||||
</div>
|
<em>{{ nightOrder.get(role).first }}.</em>
|
||||||
<div
|
<span v-if="role.firstNightReminder">{{
|
||||||
class="night-order other"
|
role.firstNightReminder
|
||||||
v-if="nightOrder.get(role).other && grimoire.isNightOrder"
|
}}</span>
|
||||||
>
|
</div>
|
||||||
<em>{{ nightOrder.get(role).other }}.</em>
|
<div
|
||||||
<span v-if="role.otherNightReminder">{{
|
class="night-order other"
|
||||||
role.otherNightReminder
|
v-if="nightOrder.get(role).other && grimoire.isNightOrder"
|
||||||
}}</span>
|
>
|
||||||
</div>
|
<em>{{ nightOrder.get(role).other }}.</em>
|
||||||
<Token :role="role"></Token>
|
<span v-if="role.otherNightReminder">{{
|
||||||
</li>
|
role.otherNightReminder
|
||||||
</ul>
|
}}</span>
|
||||||
|
</div>
|
||||||
|
<Token :role="role"></Token>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<CountdownTimer v-if="grimoire.isTimerEnabled" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ReminderModal :player-index="selectedPlayer"></ReminderModal>
|
<ReminderModal :player-index="selectedPlayer"></ReminderModal>
|
||||||
|
@ -90,6 +98,7 @@
|
||||||
import { mapGetters, mapState } from "vuex";
|
import { mapGetters, mapState } from "vuex";
|
||||||
import Player from "./Player";
|
import Player from "./Player";
|
||||||
import Token from "./Token";
|
import Token from "./Token";
|
||||||
|
import CountdownTimer from "./CountdownTimer";
|
||||||
import ReminderModal from "./modals/ReminderModal";
|
import ReminderModal from "./modals/ReminderModal";
|
||||||
import RoleModal from "./modals/RoleModal";
|
import RoleModal from "./modals/RoleModal";
|
||||||
|
|
||||||
|
@ -97,6 +106,7 @@ export default {
|
||||||
components: {
|
components: {
|
||||||
Player,
|
Player,
|
||||||
Token,
|
Token,
|
||||||
|
CountdownTimer,
|
||||||
RoleModal,
|
RoleModal,
|
||||||
ReminderModal
|
ReminderModal
|
||||||
},
|
},
|
||||||
|
@ -394,16 +404,32 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Demon bluffs / Fabled *******/
|
#top-left {
|
||||||
#townsquare > .bluffs,
|
|
||||||
#townsquare > .fabled {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 10px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Demon bluffs / Fabled / Countdown Timer *******/
|
||||||
|
#townsquare > .bluffs,
|
||||||
|
#top-left > .fabled,
|
||||||
|
#top-left > .countdown-timer {
|
||||||
&.bluffs {
|
&.bluffs {
|
||||||
|
position: absolute;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
}
|
}
|
||||||
&.fabled {
|
&.fabled {
|
||||||
top: 10px;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
&.countdown-timer {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
margin: 5px 0 0 0;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
|
|
@ -27,8 +27,12 @@ const faIcons = [
|
||||||
"Heartbeat",
|
"Heartbeat",
|
||||||
"Image",
|
"Image",
|
||||||
"Link",
|
"Link",
|
||||||
|
"Minus",
|
||||||
"MinusCircle",
|
"MinusCircle",
|
||||||
|
"Pause",
|
||||||
"PeopleArrows",
|
"PeopleArrows",
|
||||||
|
"Play",
|
||||||
|
"Plus",
|
||||||
"PlusCircle",
|
"PlusCircle",
|
||||||
"Question",
|
"Question",
|
||||||
"Random",
|
"Random",
|
||||||
|
@ -37,6 +41,7 @@ const faIcons = [
|
||||||
"SearchPlus",
|
"SearchPlus",
|
||||||
"Skull",
|
"Skull",
|
||||||
"Square",
|
"Square",
|
||||||
|
"Stop",
|
||||||
"TheaterMasks",
|
"TheaterMasks",
|
||||||
"Times",
|
"Times",
|
||||||
"TimesCircle",
|
"TimesCircle",
|
||||||
|
|
|
@ -105,9 +105,15 @@ export default new Vuex.Store({
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isMuted: false,
|
isMuted: false,
|
||||||
isImageOptIn: false,
|
isImageOptIn: false,
|
||||||
|
isTimerEnabled: false,
|
||||||
zoom: 0,
|
zoom: 0,
|
||||||
background: ""
|
background: ""
|
||||||
},
|
},
|
||||||
|
countdownTimer: {
|
||||||
|
totalSeconds: 300,
|
||||||
|
remainingSeconds: 300,
|
||||||
|
isTicking: false
|
||||||
|
},
|
||||||
modals: {
|
modals: {
|
||||||
edition: false,
|
edition: false,
|
||||||
fabled: false,
|
fabled: false,
|
||||||
|
@ -171,6 +177,7 @@ export default new Vuex.Store({
|
||||||
toggleNight: toggle("isNight"),
|
toggleNight: toggle("isNight"),
|
||||||
toggleGrimoire: toggle("isPublic"),
|
toggleGrimoire: toggle("isPublic"),
|
||||||
toggleImageOptIn: toggle("isImageOptIn"),
|
toggleImageOptIn: toggle("isImageOptIn"),
|
||||||
|
toggleTimer: toggle("isTimerEnabled"),
|
||||||
toggleModal({ modals }, name) {
|
toggleModal({ modals }, name) {
|
||||||
if (name) {
|
if (name) {
|
||||||
modals[name] = !modals[name];
|
modals[name] = !modals[name];
|
||||||
|
@ -260,6 +267,14 @@ export default new Vuex.Store({
|
||||||
state.edition = edition;
|
state.edition = edition;
|
||||||
}
|
}
|
||||||
state.modals.edition = false;
|
state.modals.edition = false;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Set timer state
|
||||||
|
* @param state
|
||||||
|
* @param payload Object with keys: `remainingSeconds`, `totalSeconds`, and `isTicking`
|
||||||
|
*/
|
||||||
|
setTimerState(state, payload) {
|
||||||
|
state.countdownTimer = payload;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [persistence, socket]
|
plugins: [persistence, socket]
|
||||||
|
|
|
@ -27,7 +27,12 @@ const state = () => ({
|
||||||
voteHistory: [],
|
voteHistory: [],
|
||||||
markedPlayer: -1,
|
markedPlayer: -1,
|
||||||
isVoteHistoryAllowed: true,
|
isVoteHistoryAllowed: true,
|
||||||
isRolesDistributed: false
|
isRolesDistributed: false,
|
||||||
|
countdownTimer: {
|
||||||
|
totalSeconds: 300,
|
||||||
|
remainingSeconds: 300,
|
||||||
|
isTicking: false
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const getters = {};
|
const getters = {};
|
||||||
|
@ -94,6 +99,12 @@ const mutations = {
|
||||||
clearVoteHistory(state) {
|
clearVoteHistory(state) {
|
||||||
state.voteHistory = [];
|
state.voteHistory = [];
|
||||||
},
|
},
|
||||||
|
updateTimerState(state, payload) {
|
||||||
|
state.countdownTimer = payload;
|
||||||
|
},
|
||||||
|
distributeTimerAction(state, payload) {
|
||||||
|
state.countdownTimer = payload;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Store a vote with and without syncing it to the live session.
|
* Store a vote with and without syncing it to the live session.
|
||||||
* This is necessary in order to prevent infinite voting loops.
|
* This is necessary in order to prevent infinite voting loops.
|
||||||
|
|
|
@ -205,6 +205,13 @@ class LiveSession {
|
||||||
case "pronouns":
|
case "pronouns":
|
||||||
this._updatePlayerPronouns(params);
|
this._updatePlayerPronouns(params);
|
||||||
break;
|
break;
|
||||||
|
case "timer":
|
||||||
|
this._handleTimerAction(params);
|
||||||
|
break;
|
||||||
|
case "isTimerEnabled":
|
||||||
|
if (!this._isSpectator) return;
|
||||||
|
this._store.commit("toggleTimer", params);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +291,8 @@ class LiveSession {
|
||||||
isVoteInProgress: session.isVoteInProgress,
|
isVoteInProgress: session.isVoteInProgress,
|
||||||
markedPlayer: session.markedPlayer,
|
markedPlayer: session.markedPlayer,
|
||||||
fabled: fabled.map(f => (f.isCustom ? f : { id: f.id })),
|
fabled: fabled.map(f => (f.isCustom ? f : { id: f.id })),
|
||||||
|
isTimerEnabled: grimoire.isTimerEnabled,
|
||||||
|
countdownTimer: session.countdownTimer,
|
||||||
...(session.nomination ? { votes: session.votes } : {})
|
...(session.nomination ? { votes: session.votes } : {})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -307,7 +316,9 @@ class LiveSession {
|
||||||
lockedVote,
|
lockedVote,
|
||||||
isVoteInProgress,
|
isVoteInProgress,
|
||||||
markedPlayer,
|
markedPlayer,
|
||||||
fabled
|
fabled,
|
||||||
|
isTimerEnabled,
|
||||||
|
countdownTimer
|
||||||
} = data;
|
} = data;
|
||||||
const players = this._store.state.players.players;
|
const players = this._store.state.players.players;
|
||||||
// adjust number of players
|
// adjust number of players
|
||||||
|
@ -365,6 +376,8 @@ class LiveSession {
|
||||||
this._store.commit("players/setFabled", {
|
this._store.commit("players/setFabled", {
|
||||||
fabled: fabled.map(f => this._store.state.fabled.get(f.id) || f)
|
fabled: fabled.map(f => this._store.state.fabled.get(f.id) || f)
|
||||||
});
|
});
|
||||||
|
this._store.commit("toggleTimer", isTimerEnabled);
|
||||||
|
this._store.commit("setTimerState", countdownTimer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,6 +681,25 @@ class LiveSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Distribute new timer action to each player.
|
||||||
|
*/
|
||||||
|
distributeTimerAction(payload) {
|
||||||
|
if (this._isSpectator) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._send("timer", payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a timer action.
|
||||||
|
* @param payload
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_handleTimerAction(payload) {
|
||||||
|
this._store.commit("setTimerState", payload);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A player nomination. ST only
|
* A player nomination. ST only
|
||||||
* This also syncs the voting speed to the players.
|
* This also syncs the voting speed to the players.
|
||||||
|
@ -703,6 +735,14 @@ class LiveSession {
|
||||||
this._send("isNight", this._store.state.grimoire.isNight);
|
this._send("isNight", this._store.state.grimoire.isNight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the isTimerEnabled status. ST only
|
||||||
|
*/
|
||||||
|
setIsTimerEnabled() {
|
||||||
|
if (this._isSpectator) return;
|
||||||
|
this._send("isTimerEnabled", this._store.state.grimoire.isTimerEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the isVoteHistoryAllowed state. ST only
|
* Send the isVoteHistoryAllowed state. ST only
|
||||||
*/
|
*/
|
||||||
|
@ -859,6 +899,11 @@ export default store => {
|
||||||
session.distributeRoles();
|
session.distributeRoles();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "session/distributeTimerAction":
|
||||||
|
if (payload) {
|
||||||
|
session.distributeTimerAction(payload);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "session/nomination":
|
case "session/nomination":
|
||||||
case "session/setNomination":
|
case "session/setNomination":
|
||||||
session.nomination(payload);
|
session.nomination(payload);
|
||||||
|
@ -914,6 +959,9 @@ export default store => {
|
||||||
session.sendPlayer(payload);
|
session.sendPlayer(payload);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "toggleTimer":
|
||||||
|
session.setIsTimerEnabled();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue