mirror of https://github.com/bra1n/townsquare.git
added vote component
This commit is contained in:
parent
f42d7dd2be
commit
c2d142f169
|
@ -11,8 +11,9 @@
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<Intro v-if="!players.length"></Intro>
|
<Intro v-if="!players.length"></Intro>
|
||||||
<TownInfo v-if="players.length"></TownInfo>
|
<TownInfo v-if="players.length && !session.nomination"></TownInfo>
|
||||||
<TownSquare @screenshot="takeScreenshot"></TownSquare>
|
<TownSquare @screenshot="takeScreenshot"></TownSquare>
|
||||||
|
<Vote v-if="session.nomination"></Vote>
|
||||||
<Menu ref="menu"></Menu>
|
<Menu ref="menu"></Menu>
|
||||||
<EditionModal />
|
<EditionModal />
|
||||||
<RolesModal />
|
<RolesModal />
|
||||||
|
@ -29,9 +30,11 @@ import RolesModal from "./components/modals/RolesModal";
|
||||||
import EditionModal from "./components/modals/EditionModal";
|
import EditionModal from "./components/modals/EditionModal";
|
||||||
import Intro from "./components/Intro";
|
import Intro from "./components/Intro";
|
||||||
import ReferenceModal from "./components/modals/ReferenceModal";
|
import ReferenceModal from "./components/modals/ReferenceModal";
|
||||||
|
import Vote from "./components/Vote";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
Vote,
|
||||||
ReferenceModal,
|
ReferenceModal,
|
||||||
Intro,
|
Intro,
|
||||||
TownInfo,
|
TownInfo,
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -58,6 +58,12 @@
|
||||||
@click="movePlayer(player)"
|
@click="movePlayer(player)"
|
||||||
title="Move player to this seat"
|
title="Move player to this seat"
|
||||||
/>
|
/>
|
||||||
|
<font-awesome-icon
|
||||||
|
icon="hand-point-right"
|
||||||
|
class="nominate"
|
||||||
|
@click="nominatePlayer(player)"
|
||||||
|
title="Nominate this player"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Claimed seat icon -->
|
<!-- Claimed seat icon -->
|
||||||
<font-awesome-icon icon="chair" v-if="player.id" class="seat" />
|
<font-awesome-icon icon="chair" v-if="player.id" class="seat" />
|
||||||
|
@ -85,10 +91,10 @@
|
||||||
<li @click="changeName">
|
<li @click="changeName">
|
||||||
<font-awesome-icon icon="user-edit" />Rename
|
<font-awesome-icon icon="user-edit" />Rename
|
||||||
</li>
|
</li>
|
||||||
<!--<li @click="nomination">
|
<li v-if="!session.nomination" @click="nominatePlayer()">
|
||||||
<font-awesome-icon icon="hand-point-right" />
|
<font-awesome-icon icon="hand-point-right" />
|
||||||
Nomination
|
Nomination
|
||||||
</li>-->
|
</li>
|
||||||
<li @click="movePlayer()">
|
<li @click="movePlayer()">
|
||||||
<font-awesome-icon icon="redo-alt" />
|
<font-awesome-icon icon="redo-alt" />
|
||||||
Move player
|
Move player
|
||||||
|
@ -219,6 +225,10 @@ export default {
|
||||||
this.isMenuOpen = false;
|
this.isMenuOpen = false;
|
||||||
this.$emit("trigger", ["movePlayer", player]);
|
this.$emit("trigger", ["movePlayer", player]);
|
||||||
},
|
},
|
||||||
|
nominatePlayer(player) {
|
||||||
|
this.isMenuOpen = false;
|
||||||
|
this.$emit("trigger", ["nominatePlayer", player]);
|
||||||
|
},
|
||||||
cancel() {
|
cancel() {
|
||||||
this.$emit("trigger", ["cancel"]);
|
this.$emit("trigger", ["cancel"]);
|
||||||
},
|
},
|
||||||
|
@ -391,6 +401,7 @@ export default {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
&.swap,
|
&.swap,
|
||||||
&.move,
|
&.move,
|
||||||
|
&.nominate,
|
||||||
&.cancel {
|
&.cancel {
|
||||||
top: 9%;
|
top: 9%;
|
||||||
left: 20%;
|
left: 20%;
|
||||||
|
@ -406,13 +417,14 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
li.from .player > svg.cancel {
|
li.from:not(.nominate) .player > svg.cancel {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
|
|
||||||
li.swap:not(.from) .player > svg.swap,
|
li.swap:not(.from) .player > svg.swap,
|
||||||
|
li.nominate .player > svg.nominate,
|
||||||
li.move:not(.from) .player > svg.move {
|
li.move:not(.from) .player > svg.move {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
|
|
|
@ -59,15 +59,13 @@ export default {
|
||||||
).length
|
).length
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
...mapState({
|
...mapState(["edition"]),
|
||||||
edition: state => state.edition,
|
...mapState("players", ["players"])
|
||||||
players: state => state.players.players
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
@import "../vars.scss";
|
@import "../vars.scss";
|
||||||
|
|
||||||
// Editions
|
// Editions
|
||||||
|
@ -94,12 +92,8 @@ export default {
|
||||||
.info {
|
.info {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
left: 50%;
|
|
||||||
top: 50%;
|
|
||||||
width: 20%;
|
width: 20%;
|
||||||
height: 20%;
|
height: 20%;
|
||||||
margin-left: -10%;
|
|
||||||
margin-top: -5%;
|
|
||||||
padding: 50px 0 0;
|
padding: 50px 0 0;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
|
|
|
@ -133,6 +133,20 @@ export default {
|
||||||
this.cancel();
|
this.cancel();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
nominatePlayer(from, to) {
|
||||||
|
if (to === undefined && from !== this.nominate) {
|
||||||
|
this.cancel();
|
||||||
|
if (from !== this.nominate) {
|
||||||
|
this.nominate = from;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$store.commit("session/nomination", [
|
||||||
|
this.nominate,
|
||||||
|
this.players.indexOf(to)
|
||||||
|
]);
|
||||||
|
this.cancel();
|
||||||
|
}
|
||||||
|
},
|
||||||
cancel() {
|
cancel() {
|
||||||
this.move = -1;
|
this.move = -1;
|
||||||
this.swap = -1;
|
this.swap = -1;
|
||||||
|
@ -229,6 +243,10 @@ export default {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Demon bluffs *******/
|
/***** Demon bluffs *******/
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
<template>
|
||||||
|
<div class="vote">
|
||||||
|
<div class="arrows">
|
||||||
|
<span class="nominator"></span>
|
||||||
|
<span class="nominee"></span>
|
||||||
|
</div>
|
||||||
|
<div class="overlay">
|
||||||
|
<em>{{ nominator.name }}</em> nominated <em>{{ nominee.name }}</em
|
||||||
|
>!
|
||||||
|
<br />
|
||||||
|
<template v-if="nominee.role.team !== 'traveler'">
|
||||||
|
<em>{{ Math.ceil(alive / 2) }} votes</em> required for an
|
||||||
|
<em>execution</em>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<em>{{ Math.ceil(players.length / 2) }} votes</em> required for an
|
||||||
|
<em>exile</em>
|
||||||
|
</template>
|
||||||
|
<div class="button-group">
|
||||||
|
<div class="button">Start Vote</div>
|
||||||
|
<div class="button" @click="finish">Finish Vote</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters, mapState } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
nominator: function() {
|
||||||
|
return this.$store.state.players.players[
|
||||||
|
this.$store.state.session.nomination[0]
|
||||||
|
];
|
||||||
|
},
|
||||||
|
nominee: function() {
|
||||||
|
return this.$store.state.players.players[
|
||||||
|
this.$store.state.session.nomination[1]
|
||||||
|
];
|
||||||
|
},
|
||||||
|
...mapState("players", ["players"]),
|
||||||
|
...mapState(["session"]),
|
||||||
|
...mapGetters({ alive: "players/alive" })
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
finish() {
|
||||||
|
this.$store.commit("session/nomination", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../vars.scss";
|
||||||
|
|
||||||
|
.vote {
|
||||||
|
position: absolute;
|
||||||
|
height: 300px;
|
||||||
|
width: 300px;
|
||||||
|
z-index: 20;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: url("../assets/demon-head.png") center center no-repeat;
|
||||||
|
background-size: auto 100%;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: 0 1px 2px #000000, 0 -1px 2px #000000, 1px 0 2px #000000,
|
||||||
|
-1px 0 2px #000000;
|
||||||
|
|
||||||
|
em {
|
||||||
|
color: red;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -12,6 +12,9 @@ const state = () => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const getters = {
|
const getters = {
|
||||||
|
alive({ players }) {
|
||||||
|
return players.filter(player => !player.isDead).length;
|
||||||
|
},
|
||||||
nonTravelers({ players }) {
|
nonTravelers({ players }) {
|
||||||
const nonTravelers = players.filter(
|
const nonTravelers = players.filter(
|
||||||
player => player.role.team !== "traveler"
|
player => player.role.team !== "traveler"
|
||||||
|
|
|
@ -3,7 +3,8 @@ const state = () => ({
|
||||||
isSpectator: false,
|
isSpectator: false,
|
||||||
playerCount: 0,
|
playerCount: 0,
|
||||||
playerId: "",
|
playerId: "",
|
||||||
claimedSeat: -1
|
claimedSeat: -1,
|
||||||
|
nomination: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const getters = {};
|
const getters = {};
|
||||||
|
@ -25,6 +26,9 @@ const mutations = {
|
||||||
},
|
},
|
||||||
claimSeat(state, claimedSeat) {
|
claimSeat(state, claimedSeat) {
|
||||||
state.claimedSeat = claimedSeat;
|
state.claimedSeat = claimedSeat;
|
||||||
|
},
|
||||||
|
nomination(state, nomination) {
|
||||||
|
state.nomination = nomination;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -289,6 +289,16 @@ class LiveSession {
|
||||||
delete this._players[player];
|
delete this._players[player];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// remove claimed seats from players that are no longer connected
|
||||||
|
this._store.state.players.players.forEach(player => {
|
||||||
|
if (player.id && !this._players[player.id]) {
|
||||||
|
this._store.commit("players/update", {
|
||||||
|
player,
|
||||||
|
property: "id",
|
||||||
|
value: ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
this._store.commit(
|
this._store.commit(
|
||||||
"session/setPlayerCount",
|
"session/setPlayerCount",
|
||||||
Object.keys(this._players).length
|
Object.keys(this._players).length
|
||||||
|
|
Loading…
Reference in New Issue