mirror of https://github.com/bra1n/townsquare.git
added vote locking and styling
This commit is contained in:
parent
6a37d17aec
commit
3b36c47f8e
|
@ -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"]),
|
||||
|
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue