added vote locking and styling

This commit is contained in:
Steffen 2020-06-04 18:23:33 +02:00
parent 6a37d17aec
commit 3b36c47f8e
No known key found for this signature in database
GPG Key ID: 764D74E98267DFC6
5 changed files with 114 additions and 39 deletions

View File

@ -18,6 +18,7 @@
<EditionModal />
<RolesModal />
<ReferenceModal />
<Gradients />
</div>
</template>
@ -31,6 +32,7 @@ import EditionModal from "./components/modals/EditionModal";
import Intro from "./components/Intro";
import ReferenceModal from "./components/modals/ReferenceModal";
import Vote from "./components/Vote";
import Gradients from "./components/Gradients";
export default {
components: {
@ -41,7 +43,8 @@ export default {
TownSquare,
Menu,
EditionModal,
RolesModal
RolesModal,
Gradients
},
computed: {
...mapState(["grimoire", "session"]),

View File

@ -0,0 +1,43 @@
<template>
<!-- SVG Gradients -->
<div id="gradients">
<svg
width="0"
height="0"
v-for="(gradient, index) in gradients"
:key="index"
>
<linearGradient :id="gradient[0]" x1="50%" y1="100%" x2="50%" y2="0%">
<stop
offset="0%"
:style="{ 'stop-color': gradient[2], 'stop-opacity': 1 }"
></stop>
<stop
offset="100%"
:style="{ 'stop-color': gradient[1], 'stop-opacity': 1 }"
></stop>
</linearGradient>
</svg>
</div>
</template>
<script>
export default {
data() {
return {
gradients: [
["demon", "#ce0100", "#000"],
["townsfolk", "#1f65ff", "#000"],
["default", "#4E4E4E", "#000"]
]
};
}
};
</script>
<style lang="scss" scoped>
svg {
position: absolute;
z-index: -1;
}
</style>

View File

@ -8,7 +8,8 @@
dead: player.isDead,
'no-vote': player.isVoteless,
you: player.id === session.playerId,
'voted-yes': session.votes[index]
'vote-yes': session.votes[index],
'vote-lock': voteLocked
},
player.role.team
]"
@ -44,7 +45,13 @@
<font-awesome-icon
icon="skull"
class="vote"
title="Vote"
title="Voted YES"
@click="vote()"
/>
<font-awesome-icon
icon="times"
class="vote"
title="Voted NO"
@click="vote()"
/>
<font-awesome-icon
@ -170,11 +177,20 @@ export default {
}
},
computed: {
index: function() {
return this.$store.state.players.players.indexOf(this.player);
},
...mapState("players", ["players"]),
...mapState(["grimoire", "session"]),
...mapGetters({ nightOrder: "players/nightOrder" })
...mapGetters({ nightOrder: "players/nightOrder" }),
index: function() {
return this.players.indexOf(this.player);
},
voteLocked: function() {
const session = this.session;
const players = this.players.length;
if (!session.nomination) return false;
const indexAdjusted =
(this.index - 1 + players - session.nomination[1]) % players;
return indexAdjusted < session.lockedVote - 1;
}
},
data() {
return {
@ -419,26 +435,36 @@ export default {
&.vote,
&.cancel {
top: 9%;
left: 20%;
width: 60%;
left: 25%;
width: 50%;
height: 60%;
opacity: 0;
pointer-events: none;
transition: all 250ms;
transform: scale(0.2);
&:hover {
color: red;
* {
stroke-width: 10px;
stroke: white;
fill: url(#default);
}
&:hover *,
&.fa-skull * {
fill: url(#demon);
}
&.fa-times * {
fill: url(#townsfolk);
}
}
}
#townsquare.vote .player.voted-yes > svg.vote {
color: $demon;
#townsquare.vote .player.vote-yes > svg.vote.fa-skull {
opacity: 0.5;
transform: scale(1);
}
#townsquare.vote .player.you.voted-yes > svg.vote {
#townsquare.vote .player.you.vote-yes > svg.vote.fa-skull,
#townsquare.vote .player.vote-lock.vote-yes > svg.vote.fa-skull,
#townsquare.vote .player.vote-lock:not(.vote-yes) > svg.vote.fa-times {
opacity: 1;
transform: scale(1);
}

View File

@ -26,12 +26,7 @@
</div>
<div class="button" @click="finish">Finish</div>
</div>
<div
class="button-group"
v-else-if="
player && (!player.isVoteless || nominee.role.team === 'traveler')
"
>
<div class="button-group" v-else-if="canVote">
<div class="button vote-no" @click="vote(false)">Vote NO</div>
<div class="button vote-yes" @click="vote(true)">Vote YES</div>
</div>
@ -47,39 +42,45 @@ import { mapGetters, mapState } from "vuex";
export default {
computed: {
...mapState("players", ["players"]),
...mapState(["session"]),
...mapGetters({ alive: "players/alive" }),
nominator: function() {
return this.$store.state.players.players[
this.$store.state.session.nomination[0]
];
return this.players[this.session.nomination[0]];
},
nominatorStyle: function() {
const players = this.$store.state.players.players.length;
const nomination = this.$store.state.session.nomination[0];
const players = this.players.length;
const nomination = this.session.nomination[0];
return {
transform: `rotate(${Math.round((nomination / players) * 360)}deg)`
};
},
nominee: function() {
return this.$store.state.players.players[
this.$store.state.session.nomination[1]
];
return this.players[this.session.nomination[1]];
},
nomineeStyle: function() {
const players = this.$store.state.players.players.length;
const nomination = this.$store.state.session.nomination[1];
const lock = this.$store.state.session.lockedVote;
const players = this.players.length;
const nomination = this.session.nomination[1];
const lock = this.session.lockedVote;
const rotation = (360 * (nomination + Math.min(lock, players))) / players;
return {
transform: `rotate(${Math.round(rotation)}deg)`
};
},
player: function() {
const id = this.$store.state.session.playerId;
return this.$store.state.players.players.find(p => p.id === id);
return this.players.find(p => p.id === this.session.playerId);
},
...mapState("players", ["players"]),
...mapState(["session"]),
...mapGetters({ alive: "players/alive" })
canVote: function() {
if (!this.player) return false;
if (this.player.isVoteless && this.nominee.role.team !== "traveler")
return false;
const session = this.session;
const players = this.players.length;
const index = this.players.indexOf(this.player);
const indexAdjusted =
(index - 1 + players - session.nomination[1]) % players;
return indexAdjusted >= session.lockedVote - 1;
}
},
methods: {
start() {
@ -99,6 +100,7 @@ export default {
this.$store.commit("session/nomination", false);
},
vote(vote) {
if (!this.canVote) return false;
const index = this.players.findIndex(p => p.id === this.session.playerId);
if (index >= 0 && !!this.session.votes[index] !== vote) {
this.$store.commit("session/vote", [index, vote]);

View File

@ -9,8 +9,8 @@ const faIcons = [
"BookOpen",
"BroadcastTower",
"Camera",
"Chair",
"CheckSquare",
"Skull",
"Cog",
"Copy",
"ExchangeAlt",
@ -23,16 +23,17 @@ const faIcons = [
"RedoAlt",
"SearchMinus",
"SearchPlus",
"Skull",
"Square",
"TheaterMasks",
"Times",
"TimesCircle",
"Undo",
"User",
"UserEdit",
"UserFriends",
"Users",
"VoteYea",
"Chair"
"VoteYea"
];
library.add(...faIcons.map(i => fas["fa" + i]));
Vue.component("font-awesome-icon", FontAwesomeIcon);