further cleanup

This commit is contained in:
Steffen 2020-05-02 21:33:44 +02:00
parent 966c6f0944
commit 23f754a955
No known key found for this signature in database
GPG Key ID: 764D74E98267DFC6
7 changed files with 120 additions and 113 deletions

View File

@ -10,32 +10,9 @@
: ''
}"
>
<div class="intro" v-if="!players.length">
<img src="static/apple-icon.png" alt="" />
Welcome to the (unofficial)
<b> Virtual Blood on the Clocktower Town Square</b>!<br />
Please add more players through the
<span class="button">
<font-awesome-icon icon="cog" /> Menu
</span>
on the top right or by pressing <b>[A]</b>.<br />
This project is free and open source and can be found on
<a href="https://github.com/bra1n/townsquare" target="_blank">GitHub</a>.
</div>
<TownInfo
:players="players"
:edition="edition"
v-if="players.length"
></TownInfo>
<TownSquare
:is-public="grimoire.isPublic"
:is-night-order="grimoire.isNightOrder"
:players="players"
:roles="roles"
:zoom="grimoire.zoom"
@screenshot="takeScreenshot"
></TownSquare>
<Intro v-if="!players.length"></Intro>
<TownInfo :players="players" v-if="players.length"></TownInfo>
<TownSquare :players="players" @screenshot="takeScreenshot"></TownSquare>
<Menu ref="menu" :players="players"></Menu>
<EditionSelectionModal :players="players"></EditionSelectionModal>
<RoleSelectionModal :players="players"></RoleSelectionModal>
@ -49,16 +26,18 @@ import TownInfo from "./components/TownInfo";
import Menu from "./components/Menu";
import RoleSelectionModal from "./components/RoleSelectionModal";
import EditionSelectionModal from "./components/EditionSelectionModal";
import Intro from "./components/Intro";
export default {
components: {
Intro,
EditionSelectionModal,
Menu,
TownSquare,
TownInfo,
RoleSelectionModal
},
computed: mapState(["grimoire", "edition", "roles"]),
computed: mapState(["grimoire"]),
data: function() {
return {
players: []
@ -85,15 +64,17 @@ export default {
case "c":
this.$store.commit("toggleModal", "roles");
break;
case "Escape":
this.$store.commit("toggleMenu");
}
}
},
mounted() {
if (localStorage.background !== undefined) {
this.background = JSON.parse(localStorage.background);
this.$store.commit("setBackground", JSON.parse(localStorage.background));
}
if (localStorage.isPublic !== undefined) {
this.isPublic = JSON.parse(localStorage.isPublic);
this.$store.commit("showGrimoire", JSON.parse(localStorage.isPublic));
}
if (localStorage.edition) {
this.$store.commit("setEdition", localStorage.edition);
@ -101,7 +82,7 @@ export default {
if (localStorage.players) {
this.players = JSON.parse(localStorage.players).map(player => ({
...player,
role: this.roles.get(player.role) || {}
role: this.$store.state.roles.get(player.role) || {}
}));
}
},
@ -223,39 +204,6 @@ ul {
justify-content: center;
}
// success animation
@keyframes greenToWhite {
from {
color: green;
}
to {
color: white;
}
}
// Intro
.intro {
text-align: center;
width: 50%;
font-size: 120%;
position: absolute;
padding: 10px;
background: rgba(0, 0, 0, 0.5);
border: 3px solid black;
border-radius: 10px;
z-index: 3;
img {
position: absolute;
bottom: 100%;
left: 50%;
margin-left: -96px;
margin-bottom: 20px;
border-radius: 50%;
box-shadow: 0 0 10px black;
border: 3px solid black;
}
}
// Buttons
.button-group {
display: flex;

47
src/components/Intro.vue Normal file
View File

@ -0,0 +1,47 @@
<template>
<div class="intro" >
<img src="static/apple-icon.png" alt="" />
Welcome to the (unofficial)
<b> Virtual Blood on the Clocktower Town Square</b>!<br />
Please add more players through the
<span class="button">
<font-awesome-icon icon="cog" @click="toggleMenu" /> Menu
</span>
on the top right or by pressing <b>[A]</b>.<br />
This project is free and open source and can be found on
<a href="https://github.com/bra1n/townsquare" target="_blank">GitHub</a>.
</div>
</template>
<script>
import { mapMutations } from "vuex";
export default {
methods: mapMutations(["toggleMenu"])
};
</script>
<style scoped lang="scss">
// Intro
.intro {
text-align: center;
width: 50%;
font-size: 120%;
position: absolute;
padding: 10px;
background: rgba(0, 0, 0, 0.5);
border: 3px solid black;
border-radius: 10px;
z-index: 3;
img {
position: absolute;
bottom: 100%;
left: 50%;
margin-left: -96px;
margin-bottom: 20px;
border-radius: 50%;
box-shadow: 0 0 10px black;
border: 3px solid black;
}
}
</style>

View File

@ -6,8 +6,8 @@
@click="takeScreenshot()"
v-bind:class="{ success: grimoire.isScreenshotSuccess }"
/>
<div class="menu" v-bind:class="{ open: isMenuOpen }">
<font-awesome-icon icon="cog" @click="isMenuOpen = !isMenuOpen" />
<div class="menu" v-bind:class="{ open: grimoire.isMenuOpen }">
<font-awesome-icon icon="cog" @click="toggleMenu" />
<ul>
<!-- Grimoire -->
<li class="headline">
@ -82,9 +82,7 @@ export default {
},
props: ["players"],
data: function() {
return {
isMenuOpen: false
};
return {};
},
computed: mapState(["grimoire"]),
methods: {
@ -133,6 +131,7 @@ export default {
},
...mapMutations([
"toggleGrimoire",
"toggleMenu",
"toggleNightOrder",
"updateScreenshot",
"updateZoom",
@ -145,6 +144,16 @@ export default {
<style scoped lang="scss">
@import "../vars.scss";
// success animation
@keyframes greenToWhite {
from {
color: green;
}
to {
color: white;
}
}
// Controls
#controls {
position: absolute;

View File

@ -12,13 +12,19 @@
<div class="shroud" @click="toggleStatus()"></div>
<div class="life" @click="toggleStatus()"></div>
<div class="night first" v-if="player.firstNight && isNightOrder">
<div
class="night first"
v-if="player.firstNight && grimoire.isNightOrder"
>
<em>{{ player.firstNight }}.</em>
<span v-if="player.role.firstNightReminder">{{
player.role.firstNightReminder | handleEmojis
}}</span>
</div>
<div class="night other" v-if="player.otherNight && isNightOrder">
<div
class="night other"
v-if="player.otherNight && grimoire.isNightOrder"
>
<em>{{ player.otherNight }}.</em>
<span v-if="player.role.otherNightReminder">{{
player.role.otherNightReminder | handleEmojis
@ -66,6 +72,7 @@
<script>
import Token from "./Token";
import { mapState } from "vuex";
export default {
components: {
@ -75,20 +82,9 @@ export default {
player: {
type: Object,
required: true
},
roles: {
type: Map,
required: true
},
isPublic: {
type: Boolean,
required: true
},
isNightOrder: {
type: Boolean,
required: true
}
},
computed: mapState(["grimoire"]),
data() {
return {};
},
@ -101,7 +97,7 @@ export default {
this.$emit("screenshot", { width, height, x, y });
},
toggleStatus() {
if (this.isPublic) {
if (this.$store.state.grimoire.isPublic) {
if (!this.player.hasDied) {
this.$set(this.player, "hasDied", true);
} else if (this.player.hasVoted) {

View File

@ -40,16 +40,13 @@
<script>
import gameJSON from "./../game";
import { mapState } from "vuex";
export default {
props: {
players: {
type: Array,
required: true
},
edition: {
type: String,
required: true
}
},
computed: {
@ -70,7 +67,8 @@ export default {
player => player.hasDied === true && player.hasVoted !== true
).length
};
}
},
...mapState(["edition"])
}
};
</script>
@ -78,6 +76,27 @@ export default {
<style lang="scss">
@import "../vars.scss";
// Editions
@each $img, $skipIcons in $editions {
.edition-#{$img} {
background-image: url("../assets/editions/#{$img}.png");
}
@if $skipIcons != true {
.edition-#{$img}.townsfolk {
background-image: url("../assets/editions/#{$img}-townsfolk.png");
}
.edition-#{$img}.outsider {
background-image: url("../assets/editions/#{$img}-outsider.png");
}
.edition-#{$img}.minion {
background-image: url("../assets/editions/#{$img}-minion.png");
}
.edition-#{$img}.demon {
background-image: url("../assets/editions/#{$img}-demon.png");
}
}
}
.info {
position: absolute;
display: flex;

View File

@ -2,17 +2,14 @@
<div
id="townsquare"
class="square"
v-bind:class="{ public: isPublic }"
v-bind:style="{ zoom: zoom }"
v-bind:class="{ public: grimoire.isPublic }"
v-bind:style="{ zoom: grimoire.zoom }"
>
<ul class="circle" v-bind:class="['size-' + players.length]">
<Player
v-for="(player, index) in players"
:key="index"
:player="player"
:roles="roles"
:is-public="isPublic"
:is-night-order="isNightOrder"
@add-reminder="openReminderModal"
@set-role="openRoleModal"
@remove-player="removePlayer"
@ -60,6 +57,7 @@
</li>
</ul>
</Modal>
<Modal v-show="availableRoles.length && selectedPlayer" @close="closeModal">
<h3>Choose a new character:</h3>
<ul class="tokens">
@ -80,6 +78,7 @@
import Player from "./Player";
import Modal from "./Modal";
import Token from "./Token";
import { mapState } from "vuex";
export default {
components: {
@ -88,27 +87,12 @@ export default {
Player
},
props: {
isPublic: {
type: Boolean,
required: true
},
isNightOrder: {
type: Boolean,
required: true
},
players: {
type: Array,
required: true
},
roles: {
type: Map,
required: true
},
zoom: {
type: Number,
required: true
}
},
computed: mapState(["grimoire"]),
data() {
return {
selectedPlayer: false,
@ -128,7 +112,7 @@ export default {
this.availableRoles = [];
this.availableReminders = [];
this.selectedPlayer = player;
this.roles.forEach(role => {
this.$store.state.roles.forEach(role => {
if (this.players.some(p => p.role.id === role.id)) {
this.availableReminders = [
...this.availableReminders,
@ -143,7 +127,7 @@ export default {
this.availableRoles = [];
this.availableReminders = [];
this.selectedPlayer = player;
this.roles.forEach(role => {
this.$store.state.roles.forEach(role => {
if (player.role && role.id !== player.role.id) {
this.availableRoles.push(role);
}

View File

@ -22,6 +22,7 @@ export default new Vuex.Store({
grimoire: {
isNightOrder: true,
isPublic: true,
isMenuOpen: false,
isScreenshot: false,
isScreenshotSuccess: false,
zoom: 1,
@ -36,12 +37,15 @@ export default new Vuex.Store({
players: []
},
mutations: {
toggleMenu({ grimoire }) {
grimoire.isMenuOpen = !grimoire.isMenuOpen;
},
toggleGrimoire({ grimoire }) {
grimoire.isPublic = !grimoire.isPublic;
grimoire.isControlOpen = !grimoire.isPublic;
},
showGrimoire({ grimoire }) {
grimoire.isPublic = false;
showGrimoire({ grimoire }, isPublic = false) {
grimoire.isPublic = isPublic;
},
toggleNightOrder({ grimoire }) {
grimoire.isNightOrder = !grimoire.isNightOrder;