mirror of https://github.com/bra1n/townsquare.git
add vote history
This commit is contained in:
parent
7caa0e7a4b
commit
15ced66b42
|
@ -26,6 +26,7 @@
|
||||||
<RolesModal />
|
<RolesModal />
|
||||||
<ReferenceModal />
|
<ReferenceModal />
|
||||||
<NightOrderModal />
|
<NightOrderModal />
|
||||||
|
<VoteHistoryModal />
|
||||||
<Gradients />
|
<Gradients />
|
||||||
<span id="version">v{{ version }}</span>
|
<span id="version">v{{ version }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,9 +46,11 @@ import Vote from "./components/Vote";
|
||||||
import Gradients from "./components/Gradients";
|
import Gradients from "./components/Gradients";
|
||||||
import NightOrderModal from "./components/modals/NightOrderModal";
|
import NightOrderModal from "./components/modals/NightOrderModal";
|
||||||
import FabledModal from "@/components/modals/FabledModal";
|
import FabledModal from "@/components/modals/FabledModal";
|
||||||
|
import VoteHistoryModal from "@/components/modals/VoteHistoryModal";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
VoteHistoryModal,
|
||||||
FabledModal,
|
FabledModal,
|
||||||
NightOrderModal,
|
NightOrderModal,
|
||||||
Vote,
|
Vote,
|
||||||
|
|
|
@ -108,6 +108,13 @@
|
||||||
Copy player link
|
Copy player link
|
||||||
<em><font-awesome-icon icon="copy"/></em>
|
<em><font-awesome-icon icon="copy"/></em>
|
||||||
</li>
|
</li>
|
||||||
|
<li
|
||||||
|
v-if="session.voteHistory.length"
|
||||||
|
@click="toggleModal('voteHistory')"
|
||||||
|
>
|
||||||
|
Nomination history
|
||||||
|
<em><font-awesome-icon icon="hand-paper"/></em>
|
||||||
|
</li>
|
||||||
<li @click="leaveSession" v-if="session.sessionId">
|
<li @click="leaveSession" v-if="session.sessionId">
|
||||||
Leave Session
|
Leave Session
|
||||||
<em>{{ session.sessionId }}</em>
|
<em>{{ session.sessionId }}</em>
|
||||||
|
@ -223,6 +230,7 @@ export default {
|
||||||
Math.round(Math.random() * 10000)
|
Math.round(Math.random() * 10000)
|
||||||
);
|
);
|
||||||
if (sessionId) {
|
if (sessionId) {
|
||||||
|
this.$store.commit("session/clearHistory");
|
||||||
this.$store.commit("session/setSpectator", false);
|
this.$store.commit("session/setSpectator", false);
|
||||||
this.$store.commit(
|
this.$store.commit(
|
||||||
"session/setSessionId",
|
"session/setSessionId",
|
||||||
|
@ -251,6 +259,7 @@ export default {
|
||||||
"Enter the channel number / name of the session you want to join"
|
"Enter the channel number / name of the session you want to join"
|
||||||
);
|
);
|
||||||
if (sessionId) {
|
if (sessionId) {
|
||||||
|
this.$store.commit("session/clearHistory");
|
||||||
this.$store.commit("session/setSpectator", true);
|
this.$store.commit("session/setSpectator", true);
|
||||||
this.$store.commit("toggleGrimoire", false);
|
this.$store.commit("toggleGrimoire", false);
|
||||||
this.$store.commit(
|
this.$store.commit(
|
||||||
|
|
|
@ -206,6 +206,7 @@ export default {
|
||||||
},
|
},
|
||||||
finish() {
|
finish() {
|
||||||
clearInterval(this.voteTimer);
|
clearInterval(this.voteTimer);
|
||||||
|
this.$store.commit("session/addHistory", this.players);
|
||||||
this.$store.commit("session/nomination");
|
this.$store.commit("session/nomination");
|
||||||
},
|
},
|
||||||
vote(vote) {
|
vote(vote) {
|
||||||
|
|
|
@ -53,6 +53,11 @@ export default {
|
||||||
max-width: 80%;
|
max-width: 80%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
.vote-history & {
|
||||||
|
max-height: 80%;
|
||||||
|
max-width: 80%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
<template>
|
||||||
|
<Modal
|
||||||
|
class="vote-history"
|
||||||
|
v-show="modals.voteHistory"
|
||||||
|
@close="toggleModal('voteHistory')"
|
||||||
|
v-if="session.voteHistory"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
@click="clearHistory"
|
||||||
|
icon="trash-alt"
|
||||||
|
class="clear"
|
||||||
|
title="Clear history"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<h3>Nomination history</h3>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Nominator</td>
|
||||||
|
<td>Nominee</td>
|
||||||
|
<td>Type</td>
|
||||||
|
<td>Majority</td>
|
||||||
|
<td><font-awesome-icon icon="hand-paper" /> Hand up</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="(vote, index) in session.voteHistory" :key="index">
|
||||||
|
<td>{{ vote.nominator }}</td>
|
||||||
|
<td>{{ vote.nominee }}</td>
|
||||||
|
<td>{{ vote.type }}</td>
|
||||||
|
<td>{{ vote.majority }}</td>
|
||||||
|
<td>
|
||||||
|
{{ vote.votes.length }}
|
||||||
|
<font-awesome-icon icon="user-friends" />
|
||||||
|
{{ vote.votes.join(", ") }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Modal from "./Modal";
|
||||||
|
import { mapMutations, mapState } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Modal
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(["session", "modals"])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations(["toggleModal"]),
|
||||||
|
...mapMutations("session", ["clearHistory"])
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../vars.scss";
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
top: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0 40px;
|
||||||
|
svg {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-spacing: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead td {
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom: 1px solid white;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody {
|
||||||
|
td:nth-child(1) {
|
||||||
|
color: $townsfolk;
|
||||||
|
}
|
||||||
|
td:nth-child(2) {
|
||||||
|
color: $demon;
|
||||||
|
}
|
||||||
|
td:nth-child(4) {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -66,7 +66,8 @@ export default new Vuex.Store({
|
||||||
reference: false,
|
reference: false,
|
||||||
reminder: false,
|
reminder: false,
|
||||||
role: false,
|
role: false,
|
||||||
roles: false
|
roles: false,
|
||||||
|
voteHistory: false
|
||||||
},
|
},
|
||||||
edition: "tb",
|
edition: "tb",
|
||||||
roles: getRolesByEdition(),
|
roles: getRolesByEdition(),
|
||||||
|
|
|
@ -9,7 +9,6 @@ const set = key => (state, val) => {
|
||||||
* @param state session state
|
* @param state session state
|
||||||
* @param index seat of the player in the circle
|
* @param index seat of the player in the circle
|
||||||
* @param vote true or false
|
* @param vote true or false
|
||||||
* @param indexAdjusted seat of the player counted from the nominated player
|
|
||||||
*/
|
*/
|
||||||
const handleVote = (state, [index, vote]) => {
|
const handleVote = (state, [index, vote]) => {
|
||||||
if (!state.nomination) return;
|
if (!state.nomination) return;
|
||||||
|
@ -29,7 +28,8 @@ const state = () => ({
|
||||||
votes: [],
|
votes: [],
|
||||||
lockedVote: 0,
|
lockedVote: 0,
|
||||||
votingSpeed: 3000,
|
votingSpeed: 3000,
|
||||||
isVoteInProgress: false
|
isVoteInProgress: false,
|
||||||
|
voteHistory: []
|
||||||
});
|
});
|
||||||
|
|
||||||
const getters = {};
|
const getters = {};
|
||||||
|
@ -56,6 +56,30 @@ const mutations = {
|
||||||
state.lockedVote = lockedVote || 0;
|
state.lockedVote = lockedVote || 0;
|
||||||
state.isVoteInProgress = isVoteInProgress || false;
|
state.isVoteInProgress = isVoteInProgress || false;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Create an entry in the vote history log. Requires current player array because it might change later in the game.
|
||||||
|
* Only stores votes that were completed.
|
||||||
|
* @param state
|
||||||
|
* @param players
|
||||||
|
*/
|
||||||
|
addHistory(state, players) {
|
||||||
|
if (!state.nomination || state.lockedVote <= players.length) return;
|
||||||
|
const isBanishment = players[state.nomination[1]].team === "traveler";
|
||||||
|
state.voteHistory.push({
|
||||||
|
nominator: players[state.nomination[0]].name,
|
||||||
|
nominee: players[state.nomination[1]].name,
|
||||||
|
type: isBanishment ? "Banishment" : "Execution",
|
||||||
|
majority: Math.ceil(
|
||||||
|
players.filter(player => !player.isDead || isBanishment).length / 2
|
||||||
|
),
|
||||||
|
votes: players
|
||||||
|
.filter((player, index) => state.votes[index])
|
||||||
|
.map(({ name }) => name)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
clearHistory(state) {
|
||||||
|
state.voteHistory = [];
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
|
|
|
@ -128,6 +128,13 @@ class LiveSession {
|
||||||
break;
|
break;
|
||||||
case "nomination":
|
case "nomination":
|
||||||
if (!this._isSpectator) return;
|
if (!this._isSpectator) return;
|
||||||
|
if (!params) {
|
||||||
|
// create vote history record
|
||||||
|
this._store.commit(
|
||||||
|
"session/addHistory",
|
||||||
|
this._store.state.players.players
|
||||||
|
);
|
||||||
|
}
|
||||||
this._store.commit("session/nomination", { nomination: params });
|
this._store.commit("session/nomination", { nomination: params });
|
||||||
break;
|
break;
|
||||||
case "swap":
|
case "swap":
|
||||||
|
@ -245,7 +252,7 @@ class LiveSession {
|
||||||
isVoteInProgress,
|
isVoteInProgress,
|
||||||
fabled
|
fabled
|
||||||
} = data;
|
} = data;
|
||||||
this._store.commit("toggleNight", isNight);
|
this._store.commit("toggleNight", !!isNight);
|
||||||
this._store.commit("session/nomination", {
|
this._store.commit("session/nomination", {
|
||||||
nomination,
|
nomination,
|
||||||
votes,
|
votes,
|
||||||
|
|
Loading…
Reference in New Issue