mirror of https://github.com/bra1n/townsquare.git
separated night order reference sheet into its own modal and hotkey (fixes #36)
This commit is contained in:
parent
300066a551
commit
036f61fed0
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "townsquare",
|
"name": "townsquare",
|
||||||
"version": "1.2.1",
|
"version": "1.3.0",
|
||||||
"description": "Blood on the Clocktower Town Square",
|
"description": "Blood on the Clocktower Town Square",
|
||||||
"author": "Steffen Baumgart",
|
"author": "Steffen Baumgart",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -10,23 +10,23 @@
|
||||||
},
|
},
|
||||||
"main": "App.vue",
|
"main": "App.vue",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.28",
|
"@fortawesome/fontawesome-svg-core": "^1.2.29",
|
||||||
"@fortawesome/free-brands-svg-icons": "^5.13.0",
|
"@fortawesome/free-brands-svg-icons": "^5.13.1",
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.13.0",
|
"@fortawesome/free-solid-svg-icons": "^5.13.1",
|
||||||
"@fortawesome/vue-fontawesome": "^0.1.9",
|
"@fortawesome/vue-fontawesome": "^0.1.10",
|
||||||
"@vue/cli-service": "^4.3.1",
|
"@vue/cli-service": "^4.4.6",
|
||||||
"sass": "^1.26.3",
|
"sass": "^1.26.9",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"vue": "^2.3.3",
|
"vue": "^2.3.3",
|
||||||
"vue-template-compiler": "^2.6.11",
|
"vue-template-compiler": "^2.6.11",
|
||||||
"vuex": "^3.3.0",
|
"vuex": "^3.5.1",
|
||||||
"ws": "^7.3.0"
|
"ws": "^7.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-eslint": "^4.3.1",
|
"@vue/cli-plugin-eslint": "^4.4.6",
|
||||||
"@vue/eslint-config-prettier": "^6.0.0",
|
"@vue/eslint-config-prettier": "^6.0.0",
|
||||||
"eslint": "^6.7.2",
|
"eslint": "^6.7.2",
|
||||||
"eslint-plugin-prettier": "^3.1.3",
|
"eslint-plugin-prettier": "^3.1.4",
|
||||||
"eslint-plugin-vue": "^6.2.2",
|
"eslint-plugin-vue": "^6.2.2",
|
||||||
"prettier": "^1.19.1"
|
"prettier": "^1.19.1"
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
<EditionModal />
|
<EditionModal />
|
||||||
<RolesModal />
|
<RolesModal />
|
||||||
<ReferenceModal />
|
<ReferenceModal />
|
||||||
|
<NightOrderModal />
|
||||||
<Gradients />
|
<Gradients />
|
||||||
<span id="version">v{{ version }}</span>
|
<span id="version">v{{ version }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,9 +38,11 @@ import Intro from "./components/Intro";
|
||||||
import ReferenceModal from "./components/modals/ReferenceModal";
|
import ReferenceModal from "./components/modals/ReferenceModal";
|
||||||
import Vote from "./components/Vote";
|
import Vote from "./components/Vote";
|
||||||
import Gradients from "./components/Gradients";
|
import Gradients from "./components/Gradients";
|
||||||
|
import NightOrderModal from "./components/modals/NightOrderModal";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
NightOrderModal,
|
||||||
Vote,
|
Vote,
|
||||||
ReferenceModal,
|
ReferenceModal,
|
||||||
Intro,
|
Intro,
|
||||||
|
@ -81,6 +84,9 @@ export default {
|
||||||
case "r":
|
case "r":
|
||||||
this.$store.commit("toggleModal", "reference");
|
this.$store.commit("toggleModal", "reference");
|
||||||
break;
|
break;
|
||||||
|
case "n":
|
||||||
|
this.$store.commit("toggleModal", "nightOrder");
|
||||||
|
break;
|
||||||
case "e":
|
case "e":
|
||||||
if (this.session.isSpectator) return;
|
if (this.session.isSpectator) return;
|
||||||
this.$store.commit("toggleModal", "edition");
|
this.$store.commit("toggleModal", "edition");
|
||||||
|
|
|
@ -138,6 +138,10 @@
|
||||||
Reference Sheet
|
Reference Sheet
|
||||||
<em>[R]</em>
|
<em>[R]</em>
|
||||||
</li>
|
</li>
|
||||||
|
<li @click="toggleModal('nightOrder')">
|
||||||
|
Night Order Sheet
|
||||||
|
<em>[N]</em>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="https://discord.gg/tkWDny6" target="_blank">
|
<a href="https://discord.gg/tkWDny6" target="_blank">
|
||||||
Join Discord
|
Join Discord
|
||||||
|
|
|
@ -0,0 +1,287 @@
|
||||||
|
<template>
|
||||||
|
<Modal
|
||||||
|
class="characters"
|
||||||
|
v-show="modals.nightOrder"
|
||||||
|
@close="toggleModal('nightOrder')"
|
||||||
|
v-if="roles.size"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
@click="toggleModal('reference')"
|
||||||
|
icon="address-card"
|
||||||
|
class="toggle"
|
||||||
|
title="Show Character Reference"
|
||||||
|
/>
|
||||||
|
<h3>
|
||||||
|
Night Order
|
||||||
|
<font-awesome-icon icon="cloud-moon" />
|
||||||
|
{{ editionName }}
|
||||||
|
</h3>
|
||||||
|
<div class="night">
|
||||||
|
<ul class="first">
|
||||||
|
<li class="headline">First Night</li>
|
||||||
|
<li v-for="role in rolesFirstNight" :key="role.id" :class="[role.team]">
|
||||||
|
<span class="name">
|
||||||
|
{{ role.name }}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="icon"
|
||||||
|
v-if="role.id"
|
||||||
|
v-bind:style="{
|
||||||
|
backgroundImage: `url(${role.image ||
|
||||||
|
require('../../assets/icons/' + role.id + '.png')})`
|
||||||
|
}"
|
||||||
|
></span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="other">
|
||||||
|
<li class="headline">Other Nights</li>
|
||||||
|
<li v-for="role in rolesOtherNight" :key="role.id" :class="[role.team]">
|
||||||
|
<span
|
||||||
|
class="icon"
|
||||||
|
v-if="role.id"
|
||||||
|
v-bind:style="{
|
||||||
|
backgroundImage: `url(${role.image ||
|
||||||
|
require('../../assets/icons/' + role.id + '.png')})`
|
||||||
|
}"
|
||||||
|
></span>
|
||||||
|
<span class="name">
|
||||||
|
{{ role.name }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Modal from "./Modal";
|
||||||
|
import editionJSON from "./../../editions.json";
|
||||||
|
import { mapMutations, mapState } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Modal
|
||||||
|
},
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
roleSelection: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
editionName: function() {
|
||||||
|
const edition = editionJSON.find(({ id }) => id === this.edition);
|
||||||
|
return edition ? edition.name : "Custom Script";
|
||||||
|
},
|
||||||
|
rolesFirstNight: function() {
|
||||||
|
const rolesFirstNight = [];
|
||||||
|
this.roles.forEach(role => {
|
||||||
|
if (role.firstNight) {
|
||||||
|
rolesFirstNight.push(role);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rolesFirstNight.sort((a, b) => a.firstNight - b.firstNight);
|
||||||
|
return rolesFirstNight;
|
||||||
|
},
|
||||||
|
rolesOtherNight: function() {
|
||||||
|
const rolesOtherNight = [];
|
||||||
|
this.roles.forEach(role => {
|
||||||
|
if (role.otherNight) {
|
||||||
|
rolesOtherNight.push(role);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rolesOtherNight.sort((a, b) => a.otherNight - b.otherNight);
|
||||||
|
return rolesOtherNight;
|
||||||
|
},
|
||||||
|
...mapState(["roles", "modals", "edition"]),
|
||||||
|
...mapState("players", ["players"])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations(["toggleModal"])
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../vars.scss";
|
||||||
|
|
||||||
|
.toggle {
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
top: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0 40px;
|
||||||
|
svg {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
text-transform: capitalize;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 20px;
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
content: " ";
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
&:before {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
&:after {
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.townsfolk {
|
||||||
|
.name,
|
||||||
|
.player,
|
||||||
|
h4 {
|
||||||
|
color: $townsfolk;
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
background-color: $townsfolk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.outsider {
|
||||||
|
.name,
|
||||||
|
.player,
|
||||||
|
h4 {
|
||||||
|
color: $outsider;
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
background-color: $outsider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.minion {
|
||||||
|
.name,
|
||||||
|
.player,
|
||||||
|
h4 {
|
||||||
|
color: $minion;
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
background-color: $minion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.demon {
|
||||||
|
.name,
|
||||||
|
.player,
|
||||||
|
h4 {
|
||||||
|
color: $demon;
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
background-color: $demon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
/*background: linear-gradient(0deg, #ffffff0f, transparent);*/
|
||||||
|
border-radius: 10px;
|
||||||
|
.icon {
|
||||||
|
width: 6vh;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: 0 -5px;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin: 0 10px;
|
||||||
|
text-align: center;
|
||||||
|
border-left: 1px solid #ffffff1f;
|
||||||
|
border-right: 1px solid #ffffff1f;
|
||||||
|
&:after {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
padding-top: 66%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 15%;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: right;
|
||||||
|
font-family: "Papyrus", sans-serif;
|
||||||
|
font-size: 110%;
|
||||||
|
}
|
||||||
|
.player {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
text-align: right;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
.ability {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.legend {
|
||||||
|
font-weight: bold;
|
||||||
|
height: 20px;
|
||||||
|
margin-top: 10px;
|
||||||
|
li span {
|
||||||
|
background: none;
|
||||||
|
height: auto;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
.icon:after {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.night {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
> *:first-child {
|
||||||
|
margin-right: 2vh;
|
||||||
|
}
|
||||||
|
> * {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.headline {
|
||||||
|
display: block;
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom: 1px solid white;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
border-color: white;
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.first {
|
||||||
|
.icon {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.other {
|
||||||
|
li .name {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -5,9 +5,8 @@
|
||||||
@close="toggleModal('reference')"
|
@close="toggleModal('reference')"
|
||||||
v-if="roles.size"
|
v-if="roles.size"
|
||||||
>
|
>
|
||||||
<template v-if="!isNightOrder">
|
|
||||||
<font-awesome-icon
|
<font-awesome-icon
|
||||||
@click="isNightOrder = !isNightOrder"
|
@click="toggleModal('nightOrder')"
|
||||||
icon="cloud-moon"
|
icon="cloud-moon"
|
||||||
class="toggle"
|
class="toggle"
|
||||||
title="Show Night Order"
|
title="Show Night Order"
|
||||||
|
@ -27,11 +26,7 @@
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div
|
<div v-for="(teamRoles, team) in rolesGrouped" :key="team" :class="[team]">
|
||||||
v-for="(teamRoles, team) in rolesGrouped"
|
|
||||||
:key="team"
|
|
||||||
:class="[team]"
|
|
||||||
>
|
|
||||||
<h4>{{ team }}</h4>
|
<h4>{{ team }}</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="role in teamRoles" :class="[team]" :key="role.id">
|
<li v-for="role in teamRoles" :class="[team]" :key="role.id">
|
||||||
|
@ -51,64 +46,6 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<font-awesome-icon
|
|
||||||
@click="isNightOrder = !isNightOrder"
|
|
||||||
icon="address-card"
|
|
||||||
class="toggle"
|
|
||||||
title="Show Character Reference"
|
|
||||||
/>
|
|
||||||
<h3>
|
|
||||||
Night Order
|
|
||||||
<font-awesome-icon icon="cloud-moon" />
|
|
||||||
{{ editionName }}
|
|
||||||
</h3>
|
|
||||||
<div class="night">
|
|
||||||
<ul class="first">
|
|
||||||
<li class="headline">First Night</li>
|
|
||||||
<li
|
|
||||||
v-for="role in rolesFirstNight"
|
|
||||||
:key="role.id"
|
|
||||||
:class="[role.team]"
|
|
||||||
>
|
|
||||||
<span class="name">
|
|
||||||
{{ role.name }}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="icon"
|
|
||||||
v-if="role.id"
|
|
||||||
v-bind:style="{
|
|
||||||
backgroundImage: `url(${require('../../assets/icons/' +
|
|
||||||
role.id +
|
|
||||||
'.png')})`
|
|
||||||
}"
|
|
||||||
></span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="other">
|
|
||||||
<li class="headline">Other Nights</li>
|
|
||||||
<li
|
|
||||||
v-for="role in rolesOtherNight"
|
|
||||||
:key="role.id"
|
|
||||||
:class="[role.team]"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="icon"
|
|
||||||
v-if="role.id"
|
|
||||||
v-bind:style="{
|
|
||||||
backgroundImage: `url(${require('../../assets/icons/' +
|
|
||||||
role.id +
|
|
||||||
'.png')})`
|
|
||||||
}"
|
|
||||||
></span>
|
|
||||||
<span class="name">
|
|
||||||
{{ role.name }}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -123,8 +60,7 @@ export default {
|
||||||
},
|
},
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
roleSelection: {},
|
roleSelection: {}
|
||||||
isNightOrder: false
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -155,26 +91,6 @@ export default {
|
||||||
});
|
});
|
||||||
return players;
|
return players;
|
||||||
},
|
},
|
||||||
rolesFirstNight: function() {
|
|
||||||
const rolesFirstNight = [];
|
|
||||||
this.roles.forEach(role => {
|
|
||||||
if (role.firstNight) {
|
|
||||||
rolesFirstNight.push(role);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
rolesFirstNight.sort((a, b) => a.firstNight - b.firstNight);
|
|
||||||
return rolesFirstNight;
|
|
||||||
},
|
|
||||||
rolesOtherNight: function() {
|
|
||||||
const rolesOtherNight = [];
|
|
||||||
this.roles.forEach(role => {
|
|
||||||
if (role.otherNight) {
|
|
||||||
rolesOtherNight.push(role);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
rolesOtherNight.sort((a, b) => a.otherNight - b.otherNight);
|
|
||||||
return rolesOtherNight;
|
|
||||||
},
|
|
||||||
...mapState(["roles", "modals", "edition"]),
|
...mapState(["roles", "modals", "edition"]),
|
||||||
...mapState("players", ["players"])
|
...mapState("players", ["players"])
|
||||||
},
|
},
|
||||||
|
@ -326,45 +242,4 @@ ul {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.night {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: center;
|
|
||||||
> *:first-child {
|
|
||||||
margin-right: 2vh;
|
|
||||||
}
|
|
||||||
> * {
|
|
||||||
flex-grow: 0;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.headline {
|
|
||||||
display: block;
|
|
||||||
font-weight: bold;
|
|
||||||
border-bottom: 1px solid white;
|
|
||||||
padding: 5px 10px;
|
|
||||||
border-radius: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.icon {
|
|
||||||
border-color: white;
|
|
||||||
}
|
|
||||||
.name {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
.first {
|
|
||||||
.icon {
|
|
||||||
border-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.other {
|
|
||||||
li .name {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.icon {
|
|
||||||
border-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -45,7 +45,8 @@ export default new Vuex.Store({
|
||||||
edition: false,
|
edition: false,
|
||||||
roles: false,
|
roles: false,
|
||||||
role: false,
|
role: false,
|
||||||
reminder: false
|
reminder: false,
|
||||||
|
nightOrder: false
|
||||||
},
|
},
|
||||||
edition: "tb",
|
edition: "tb",
|
||||||
roles: getRolesByEdition()
|
roles: getRolesByEdition()
|
||||||
|
|
Loading…
Reference in New Issue