mirror of
https://github.com/bra1n/townsquare.git
synced 2025-04-04 22:24:36 +00:00
feat: [i18n] parameterize labels with english locale
This commit is contained in:
parent
661aac9bcb
commit
6a6a5ee165
21 changed files with 449 additions and 168 deletions
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
### Version 2.14.0
|
### Version 2.14.0
|
||||||
- added Farmer to list of available characters
|
- added Farmer to list of available characters
|
||||||
|
- added i18n support
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
62
package-lock.json
generated
62
package-lock.json
generated
|
@ -17,11 +17,13 @@
|
||||||
"sass": "^1.30.0",
|
"sass": "^1.30.0",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"vue": "^2.6.12",
|
"vue": "^2.6.12",
|
||||||
|
"vue-i18n": "^8.24.4",
|
||||||
"vue-template-compiler": "^2.6.12",
|
"vue-template-compiler": "^2.6.12",
|
||||||
"vuex": "^3.6.0",
|
"vuex": "^3.6.0",
|
||||||
"ws": "^7.4.6"
|
"ws": "^7.4.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@kazupon/vue-i18n-loader": "^0.5.0",
|
||||||
"@vue/cli-plugin-eslint": "^4.5.9",
|
"@vue/cli-plugin-eslint": "^4.5.9",
|
||||||
"@vue/eslint-config-prettier": "^6.0.0",
|
"@vue/eslint-config-prettier": "^6.0.0",
|
||||||
"eslint": "^6.7.2",
|
"eslint": "^6.7.2",
|
||||||
|
@ -159,6 +161,35 @@
|
||||||
"webpack": "^4.0.0"
|
"webpack": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@kazupon/vue-i18n-loader": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@kazupon/vue-i18n-loader/-/vue-i18n-loader-0.5.0.tgz",
|
||||||
|
"integrity": "sha512-Tp2mXKemf9/RBhI9CW14JjR9oKjL2KH7tV6S0eKEjIBuQBAOFNuPJu3ouacmz9hgoXbNp+nusw3MVQmxZWFR9g==",
|
||||||
|
"deprecated": "WARNING: If you would like to use @kazupon/vue-i18n-loader that is released new features and bug fixes, you need to install @intlify/vue-i18n-loader.",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"js-yaml": "^3.13.1",
|
||||||
|
"json5": "^2.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@kazupon/vue-i18n-loader/node_modules/json5": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"json5": "lib/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@mrmlnc/readdir-enhanced": {
|
"node_modules/@mrmlnc/readdir-enhanced": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
||||||
|
@ -10697,6 +10728,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
|
||||||
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog=="
|
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog=="
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-i18n": {
|
||||||
|
"version": "8.24.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.24.4.tgz",
|
||||||
|
"integrity": "sha512-RZE94WUAGxEiBAANxQ0pptbRwDkNKNSXl3fnJslpFOxVMF6UkUtMDSuYGuW2blDrVgweIXVpethOVkYoNNT9xw=="
|
||||||
|
},
|
||||||
"node_modules/vue-loader": {
|
"node_modules/vue-loader": {
|
||||||
"version": "15.9.6",
|
"version": "15.9.6",
|
||||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.6.tgz",
|
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.6.tgz",
|
||||||
|
@ -12095,6 +12131,27 @@
|
||||||
"postcss": "^7.0.0"
|
"postcss": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@kazupon/vue-i18n-loader": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@kazupon/vue-i18n-loader/-/vue-i18n-loader-0.5.0.tgz",
|
||||||
|
"integrity": "sha512-Tp2mXKemf9/RBhI9CW14JjR9oKjL2KH7tV6S0eKEjIBuQBAOFNuPJu3ouacmz9hgoXbNp+nusw3MVQmxZWFR9g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"js-yaml": "^3.13.1",
|
||||||
|
"json5": "^2.1.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"json5": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@mrmlnc/readdir-enhanced": {
|
"@mrmlnc/readdir-enhanced": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
||||||
|
@ -20511,6 +20568,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
|
||||||
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog=="
|
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog=="
|
||||||
},
|
},
|
||||||
|
"vue-i18n": {
|
||||||
|
"version": "8.24.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.24.4.tgz",
|
||||||
|
"integrity": "sha512-RZE94WUAGxEiBAANxQ0pptbRwDkNKNSXl3fnJslpFOxVMF6UkUtMDSuYGuW2blDrVgweIXVpethOVkYoNNT9xw=="
|
||||||
|
},
|
||||||
"vue-loader": {
|
"vue-loader": {
|
||||||
"version": "15.9.6",
|
"version": "15.9.6",
|
||||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.6.tgz",
|
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.6.tgz",
|
||||||
|
|
|
@ -20,11 +20,13 @@
|
||||||
"sass": "^1.30.0",
|
"sass": "^1.30.0",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"vue": "^2.6.12",
|
"vue": "^2.6.12",
|
||||||
|
"vue-i18n": "^8.24.4",
|
||||||
"vue-template-compiler": "^2.6.12",
|
"vue-template-compiler": "^2.6.12",
|
||||||
"vuex": "^3.6.0",
|
"vuex": "^3.6.0",
|
||||||
"ws": "^7.4.6"
|
"ws": "^7.4.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@kazupon/vue-i18n-loader": "^0.5.0",
|
||||||
"@vue/cli-plugin-eslint": "^4.5.9",
|
"@vue/cli-plugin-eslint": "^4.5.9",
|
||||||
"@vue/eslint-config-prettier": "^6.0.0",
|
"@vue/eslint-config-prettier": "^6.0.0",
|
||||||
"eslint": "^6.7.2",
|
"eslint": "^6.7.2",
|
||||||
|
|
168
src/assets/translations/en.json
Normal file
168
src/assets/translations/en.json
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
{
|
||||||
|
"menu": {
|
||||||
|
"grimoire": "Grimoire",
|
||||||
|
"zoom": "Zoom",
|
||||||
|
"other-players-in-session": "other players in this session",
|
||||||
|
"show-background-image": "Show background image",
|
||||||
|
"background-image": "Background image",
|
||||||
|
"show-custom-image": "Show custom image",
|
||||||
|
"night-order": "Night order",
|
||||||
|
"disable-animations": "Disable animations",
|
||||||
|
"mute-sounds": "Mute sounds",
|
||||||
|
"playing": "Playing",
|
||||||
|
"hosting": "Hosting",
|
||||||
|
"switch-night": "Switch to night",
|
||||||
|
"switch-day": "Switch to day",
|
||||||
|
"show": "Show",
|
||||||
|
"hide": "Hide",
|
||||||
|
"live-session": "Live Session",
|
||||||
|
"delay-to": "Delay to ",
|
||||||
|
"vote-history": "Vote history",
|
||||||
|
"leave-session": "Leave Session",
|
||||||
|
"players": "Players",
|
||||||
|
"add": "Add",
|
||||||
|
"randomize": "Randomize",
|
||||||
|
"remove-all": "Remove all",
|
||||||
|
"characters": "Characters",
|
||||||
|
"select-edition": "Select Edition",
|
||||||
|
"choose-assign": "Choose & Assign",
|
||||||
|
"add-fabled": "Add Fabled",
|
||||||
|
"help": "Help",
|
||||||
|
"reference-sheet": "Reference Sheet",
|
||||||
|
"night-order-sheet": "Night Order Sheet",
|
||||||
|
"game-state-json": "Game State JSON",
|
||||||
|
"join-discord": "Join Discord",
|
||||||
|
"source-code": "Source code",
|
||||||
|
"host": "Host (Storyteller)",
|
||||||
|
"join": "Join (Player)",
|
||||||
|
"copy-player-link": "Copy player link",
|
||||||
|
"send-characters": "Send characters",
|
||||||
|
"player-name": "Player name",
|
||||||
|
"enter-background": "Enter custom background URL",
|
||||||
|
"create-session": "Enter a channel number / name for your session",
|
||||||
|
"distribute-roles": "Do you want to distribute assigned characters to all SEATED players?",
|
||||||
|
"custom-images-warn": "Are you sure you want to allow custom images? A malicious script file author might track your IP address this way.",
|
||||||
|
"join-session": "Enter the channel number / name of the session you want to join",
|
||||||
|
"leave-warn": "Are you sure you want to leave the active live game?",
|
||||||
|
"randomize-warn": "Are you sure you want to randomize seatings?",
|
||||||
|
"remove-players-warn": "Are you sure you want to remove all players?",
|
||||||
|
"remove-roles-warn": "Are you sure you want to remove all player roles?"
|
||||||
|
},
|
||||||
|
"intro": {
|
||||||
|
"welcome": "Welcome to the (unofficial) {grimoire} for Blood on the Clocktower ! Please add more players through the {menu} on the top right or by pressing {a-key}. You can also join a game session by pressing {j-key}.",
|
||||||
|
"townsquare-grimoire": "Virtual Town Square and Grimoire",
|
||||||
|
"menu": "Menu",
|
||||||
|
"project-notice": "This project is free and open source and can be found on {github}. It is not affiliated with The Pandemonium Institute. \"Blood on the Clocktower\" is a trademark of Steven Medway and The Pandemonium Institute."
|
||||||
|
},
|
||||||
|
"player": {
|
||||||
|
"change-pronouns": "Change Pronouns",
|
||||||
|
"rename": "Rename",
|
||||||
|
"move-player": "Move player",
|
||||||
|
"swap-seats": "Swap seats",
|
||||||
|
"remove": "Remove",
|
||||||
|
"empty-seat": "Empty seat",
|
||||||
|
"nomination": "Nomination",
|
||||||
|
"claim-seat": "Claim seat",
|
||||||
|
"vacate-seat": "Vacate seat",
|
||||||
|
"seat-occupied": "Seat occupied",
|
||||||
|
"player-name": "Player name"
|
||||||
|
},
|
||||||
|
"town-info": {
|
||||||
|
"add-more": "Please add more players!",
|
||||||
|
"night-phase": "Night phase"
|
||||||
|
},
|
||||||
|
"townsquare": {
|
||||||
|
"other-characters": "Other characters",
|
||||||
|
"demon-bluffs": "Demon bluffs",
|
||||||
|
"fabled": "Fabled"
|
||||||
|
},
|
||||||
|
"vote": {
|
||||||
|
"nominated": "nominated",
|
||||||
|
"vote": "vote",
|
||||||
|
"in-favor": "in favor",
|
||||||
|
"majority-is": "majority is",
|
||||||
|
"time-per-player": "Time per player",
|
||||||
|
"countdown": "Countdown",
|
||||||
|
"restart": "Restart",
|
||||||
|
"start": "Start",
|
||||||
|
"pause": "Pause",
|
||||||
|
"resume": "Resume",
|
||||||
|
"reset": "Reset",
|
||||||
|
"close": "Close",
|
||||||
|
"mark-execution": "Mark for execution",
|
||||||
|
"clear-mark": "Clear mark",
|
||||||
|
"seconds-between-votes": "seconds between votes",
|
||||||
|
"hand-down": "Hand DOWN",
|
||||||
|
"hand-up": "Hand UP",
|
||||||
|
"claim-seat": "Please claim a seat to vote"
|
||||||
|
},
|
||||||
|
"edition-modal": {
|
||||||
|
"select-edition": "Select an edition:",
|
||||||
|
"custom-script": "Custom Script / Characters",
|
||||||
|
"load-script-title": "Load custom script / characters",
|
||||||
|
"load-script-help": "To play with a custom script, you need to select the characters you want to play with in the official {link} and then upload the generated \"custom-list.json\" either directly here or provide a URL to such a hosted JSON file.",
|
||||||
|
"script-tool": "Script Tool",
|
||||||
|
"custom-characters-notice": "To play with custom characters, please read {documentation} on how to write a custom character definition file.",
|
||||||
|
"documentation": "the documentation",
|
||||||
|
"trusted-sources": "Only load custom JSON files from sources that you trust!",
|
||||||
|
"popular-scripts": "Some popular custom scripts:",
|
||||||
|
"upload-json": "Upload JSON",
|
||||||
|
"enter-url": "Enter URL",
|
||||||
|
"back": "Back"
|
||||||
|
},
|
||||||
|
"fabled-modal": {
|
||||||
|
"choose-fabled": "Choose a fabled character to add to the game"
|
||||||
|
},
|
||||||
|
"game-state-modal": {
|
||||||
|
"current-game-state": "Current Game State",
|
||||||
|
"copy-json": "Copy JSON",
|
||||||
|
"load-state": "Load State"
|
||||||
|
},
|
||||||
|
"night-order-modal": {
|
||||||
|
"show-reference": "Show Character Reference",
|
||||||
|
"night-order": "Night Order",
|
||||||
|
"first-night": "First Night",
|
||||||
|
"other-nights": "Other Nights",
|
||||||
|
"minion-info": "Minion info",
|
||||||
|
"minion-reminder": "• If more than one Minion, they all make eye contact with each other. • Show the “This is the Demon” card. Point to the Demon.",
|
||||||
|
"demon-info": "Demon info & bluffs",
|
||||||
|
"demon-reminder": "• Show the “These are your minions” card. Point to each Minion. • Show the “These characters are not in play” card. Show 3 character tokens of good characters not in play."
|
||||||
|
},
|
||||||
|
"reference-modal": {
|
||||||
|
"show-night-order": "Show Night Order",
|
||||||
|
"character-reference": "Character Reference",
|
||||||
|
"jinxed": "Jinxed",
|
||||||
|
"townsfolk": "Townsfolk",
|
||||||
|
"outsider": "Outsider",
|
||||||
|
"minion": "Minion",
|
||||||
|
"demon": "Demon"
|
||||||
|
},
|
||||||
|
"reminder-modal": {
|
||||||
|
"reminder-token": "Choose a reminder token"
|
||||||
|
},
|
||||||
|
"role-modal": {
|
||||||
|
"choose-character": "Choose a new character for {player}",
|
||||||
|
"bluffing": "bluffing",
|
||||||
|
"edition-roles": "Edition Roles",
|
||||||
|
"other-travelers": "Other Travelers"
|
||||||
|
},
|
||||||
|
"roles-modal": {
|
||||||
|
"select-roles": "Select the characters for {nonTravelers} players:",
|
||||||
|
"warning-incorrect-setup": "Warning: there are characters selected that modify the game setup! The randomizer does not account for these characters.",
|
||||||
|
"allow-duplicate": "Allow duplicate characters",
|
||||||
|
"assign-randomly": "Assign {roles} characters randomly",
|
||||||
|
"shuffle": "Shuffle characters"
|
||||||
|
},
|
||||||
|
"vote-history-modal": {
|
||||||
|
"vote-history": "Vote history",
|
||||||
|
"accessible-players": "Accessible to players",
|
||||||
|
"clear": "Clear for everyone",
|
||||||
|
"time": "Time",
|
||||||
|
"nominator": "Nominator",
|
||||||
|
"nominee": "Nominee",
|
||||||
|
"type": "Type",
|
||||||
|
"votes": "Votes",
|
||||||
|
"majority": "Majority",
|
||||||
|
"voters": "Voters"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +1,31 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="intro">
|
<div class="intro">
|
||||||
<img src="static/apple-icon.png" alt="" />
|
<img src="static/apple-icon.png" alt="" />
|
||||||
Welcome to the (unofficial)
|
<i18n path="intro.welcome">
|
||||||
<b>Virtual Town Square and Grimoire</b> for Blood on the Clocktower! Please
|
<template #menu>
|
||||||
add more players through the
|
|
||||||
<span class="button" @click="toggleMenu">
|
<span class="button" @click="toggleMenu">
|
||||||
<font-awesome-icon icon="cog" /> Menu
|
<font-awesome-icon icon="cog" /> {{ $t("intro.menu") }}</span
|
||||||
</span>
|
>
|
||||||
on the top right or by pressing <b>[A]</b>. You can also join a game session
|
</template>
|
||||||
by pressing <b>[J]</b>.<br />
|
<template #grimoire>
|
||||||
|
<b>{{ $t("intro.townsquare-grimoire") }}</b>
|
||||||
|
</template>
|
||||||
|
<template #a-key>
|
||||||
|
<b>[A]</b>
|
||||||
|
</template>
|
||||||
|
<template #j-key>
|
||||||
|
<b>[J]</b>
|
||||||
|
</template>
|
||||||
|
</i18n>
|
||||||
|
<br />
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
This project is free and open source and can be found on
|
<i18n path="intro.project-notice">
|
||||||
<a href="https://github.com/bra1n/townsquare" target="_blank">GitHub</a>.
|
<template #github>
|
||||||
It is not affiliated with The Pandemonium Institute. "Blood on the
|
<a href="https://github.com/bra1n/townsquare" target="_blank"
|
||||||
Clocktower" is a trademark of Steven Medway and The Pandemonium Institute.
|
>GitHub</a
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</i18n>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
v-if="session.sessionId"
|
v-if="session.sessionId"
|
||||||
@click="leaveSession"
|
@click="leaveSession"
|
||||||
:title="
|
:title="
|
||||||
`${session.playerCount} other players in this session${
|
`${session.playerCount} ${$t('other-players-in-session')}${
|
||||||
session.ping ? ' (' + session.ping + 'ms latency)' : ''
|
session.ping ? ' (' + session.ping + 'ms latency)' : ''
|
||||||
}`
|
}`
|
||||||
"
|
"
|
||||||
|
@ -47,19 +47,23 @@
|
||||||
|
|
||||||
<template v-if="tab === 'grimoire'">
|
<template v-if="tab === 'grimoire'">
|
||||||
<!-- Grimoire -->
|
<!-- Grimoire -->
|
||||||
<li class="headline">Grimoire</li>
|
<li class="headline">{{ $t("menu.grimoire") }}</li>
|
||||||
<li @click="toggleGrimoire" v-if="players.length">
|
<li @click="toggleGrimoire" v-if="players.length">
|
||||||
<template v-if="!grimoire.isPublic">Hide</template>
|
<template v-if="!grimoire.isPublic">{{ $t("menu.hide") }}</template>
|
||||||
<template v-if="grimoire.isPublic">Show</template>
|
<template v-if="grimoire.isPublic">{{ $t("menu.show") }}</template>
|
||||||
<em>[G]</em>
|
<em>[G]</em>
|
||||||
</li>
|
</li>
|
||||||
<li @click="toggleNight" v-if="!session.isSpectator">
|
<li @click="toggleNight" v-if="!session.isSpectator">
|
||||||
<template v-if="!grimoire.isNight">Switch to Night</template>
|
<template v-if="!grimoire.isNight">
|
||||||
<template v-if="grimoire.isNight">Switch to Day</template>
|
{{ $t("menu.switch-night") }}
|
||||||
|
</template>
|
||||||
|
<template v-if="grimoire.isNight">
|
||||||
|
{{ $t("menu.switch-day") }}
|
||||||
|
</template>
|
||||||
<em>[S]</em>
|
<em>[S]</em>
|
||||||
</li>
|
</li>
|
||||||
<li @click="toggleNightOrder" v-if="players.length">
|
<li @click="toggleNightOrder" v-if="players.length">
|
||||||
Night order
|
{{ $t("menu.night-order") }}
|
||||||
<em>
|
<em>
|
||||||
<font-awesome-icon
|
<font-awesome-icon
|
||||||
:icon="[
|
:icon="[
|
||||||
|
@ -70,7 +74,7 @@
|
||||||
</em>
|
</em>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="players.length">
|
<li v-if="players.length">
|
||||||
Zoom
|
{{ $t("menu.zoom") }}
|
||||||
<em>
|
<em>
|
||||||
<font-awesome-icon
|
<font-awesome-icon
|
||||||
@click="setZoom(grimoire.zoom - 1)"
|
@click="setZoom(grimoire.zoom - 1)"
|
||||||
|
@ -84,11 +88,11 @@
|
||||||
</em>
|
</em>
|
||||||
</li>
|
</li>
|
||||||
<li @click="setBackground">
|
<li @click="setBackground">
|
||||||
Background image
|
{{ $t("menu.background-image") }}
|
||||||
<em><font-awesome-icon icon="image"/></em>
|
<em><font-awesome-icon icon="image"/></em>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="!edition.isOfficial" @click="imageOptIn">
|
<li v-if="!edition.isOfficial" @click="imageOptIn">
|
||||||
<small>Show Custom Images</small>
|
<small>{{ $t("menu.show-custom-image") }}</small>
|
||||||
<em
|
<em
|
||||||
><font-awesome-icon
|
><font-awesome-icon
|
||||||
:icon="[
|
:icon="[
|
||||||
|
@ -98,14 +102,14 @@
|
||||||
/></em>
|
/></em>
|
||||||
</li>
|
</li>
|
||||||
<li @click="toggleStatic">
|
<li @click="toggleStatic">
|
||||||
Disable Animations
|
{{ $t("menu.disable-animations") }}
|
||||||
<em
|
<em
|
||||||
><font-awesome-icon
|
><font-awesome-icon
|
||||||
:icon="['fas', grimoire.isStatic ? 'check-square' : 'square']"
|
:icon="['fas', grimoire.isStatic ? 'check-square' : 'square']"
|
||||||
/></em>
|
/></em>
|
||||||
</li>
|
</li>
|
||||||
<li @click="toggleMuted">
|
<li @click="toggleMuted">
|
||||||
Mute Sounds
|
{{ $t("menu.mute-sounds") }}
|
||||||
<em
|
<em
|
||||||
><font-awesome-icon
|
><font-awesome-icon
|
||||||
:icon="['fas', grimoire.isMuted ? 'volume-mute' : 'volume-up']"
|
:icon="['fas', grimoire.isMuted ? 'volume-mute' : 'volume-up']"
|
||||||
|
@ -116,36 +120,37 @@
|
||||||
<template v-if="tab === 'session'">
|
<template v-if="tab === 'session'">
|
||||||
<!-- Session -->
|
<!-- Session -->
|
||||||
<li class="headline" v-if="session.sessionId">
|
<li class="headline" v-if="session.sessionId">
|
||||||
{{ session.isSpectator ? "Playing" : "Hosting" }}
|
{{ session.isSpectator ? $t("menu.playing") : $t("menu.hosting") }}
|
||||||
</li>
|
</li>
|
||||||
<li class="headline" v-else>
|
<li class="headline" v-else>
|
||||||
Live Session
|
{{ $t("menu.live-session") }}
|
||||||
</li>
|
</li>
|
||||||
<template v-if="!session.sessionId">
|
<template v-if="!session.sessionId">
|
||||||
<li @click="hostSession">Host (Storyteller)<em>[H]</em></li>
|
<li @click="hostSession">{{ $t("menu.host") }}<em>[H]</em></li>
|
||||||
<li @click="joinSession">Join (Player)<em>[J]</em></li>
|
<li @click="joinSession">{{ $t("menu.join") }}<em>[J]</em></li>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<li v-if="session.ping">
|
<li v-if="session.ping">
|
||||||
Delay to {{ session.isSpectator ? "host" : "players" }}
|
{{ $t("menu.delay-to") }}
|
||||||
|
{{ session.isSpectator ? "host" : "players" }}
|
||||||
<em>{{ session.ping }}ms</em>
|
<em>{{ session.ping }}ms</em>
|
||||||
</li>
|
</li>
|
||||||
<li @click="copySessionUrl">
|
<li @click="copySessionUrl">
|
||||||
Copy player link
|
{{ $t("menu.copy-player-link") }}
|
||||||
<em><font-awesome-icon icon="copy"/></em>
|
<em><font-awesome-icon icon="copy"/></em>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="!session.isSpectator" @click="distributeRoles">
|
<li v-if="!session.isSpectator" @click="distributeRoles">
|
||||||
Send Characters
|
{{ $t("menu.send-characters") }}
|
||||||
<em><font-awesome-icon icon="theater-masks"/></em>
|
<em><font-awesome-icon icon="theater-masks"/></em>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
v-if="session.voteHistory.length || !session.isSpectator"
|
v-if="session.voteHistory.length || !session.isSpectator"
|
||||||
@click="toggleModal('voteHistory')"
|
@click="toggleModal('voteHistory')"
|
||||||
>
|
>
|
||||||
Vote history<em>[V]</em>
|
{{ $t("menu.vote-history") }}<em>[V]</em>
|
||||||
</li>
|
</li>
|
||||||
<li @click="leaveSession">
|
<li @click="leaveSession">
|
||||||
Leave Session
|
{{ $t("menu.leave-session") }}
|
||||||
<em>{{ session.sessionId }}</em>
|
<em>{{ session.sessionId }}</em>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
@ -153,60 +158,62 @@
|
||||||
|
|
||||||
<template v-if="tab === 'players' && !session.isSpectator">
|
<template v-if="tab === 'players' && !session.isSpectator">
|
||||||
<!-- Users -->
|
<!-- Users -->
|
||||||
<li class="headline">Players</li>
|
<li class="headline">{{ $t("menu.players") }}</li>
|
||||||
<li @click="addPlayer" v-if="players.length < 20">Add<em>[A]</em></li>
|
<li @click="addPlayer" v-if="players.length < 20">
|
||||||
|
{{ $t("menu.add") }}<em>[A]</em>
|
||||||
|
</li>
|
||||||
<li @click="randomizeSeatings" v-if="players.length > 2">
|
<li @click="randomizeSeatings" v-if="players.length > 2">
|
||||||
Randomize
|
{{ $t("menu.randomize") }}
|
||||||
<em><font-awesome-icon icon="dice"/></em>
|
<em><font-awesome-icon icon="dice"/></em>
|
||||||
</li>
|
</li>
|
||||||
<li @click="clearPlayers" v-if="players.length">
|
<li @click="clearPlayers" v-if="players.length">
|
||||||
Remove all
|
{{ $t("menu.remove-all") }}
|
||||||
<em><font-awesome-icon icon="trash-alt"/></em>
|
<em><font-awesome-icon icon="trash-alt"/></em>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="tab === 'characters'">
|
<template v-if="tab === 'characters'">
|
||||||
<!-- Characters -->
|
<!-- Characters -->
|
||||||
<li class="headline">Characters</li>
|
<li class="headline">{{ $t("menu.characters") }}</li>
|
||||||
<li v-if="!session.isSpectator" @click="toggleModal('edition')">
|
<li v-if="!session.isSpectator" @click="toggleModal('edition')">
|
||||||
Select Edition
|
{{ $t("menu.select-edition") }}
|
||||||
<em>[E]</em>
|
<em>[E]</em>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
@click="toggleModal('roles')"
|
@click="toggleModal('roles')"
|
||||||
v-if="!session.isSpectator && players.length > 4"
|
v-if="!session.isSpectator && players.length > 4"
|
||||||
>
|
>
|
||||||
Choose & Assign
|
{{ $t("menu.choose-assign") }}
|
||||||
<em>[C]</em>
|
<em>[C]</em>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="!session.isSpectator" @click="toggleModal('fabled')">
|
<li v-if="!session.isSpectator" @click="toggleModal('fabled')">
|
||||||
Add Fabled
|
{{ $t("menu.add-fabled") }}
|
||||||
<em><font-awesome-icon icon="dragon"/></em>
|
<em><font-awesome-icon icon="dragon"/></em>
|
||||||
</li>
|
</li>
|
||||||
<li @click="clearRoles" v-if="players.length">
|
<li @click="clearRoles" v-if="players.length">
|
||||||
Remove all
|
{{ $t("menu.remove-all") }}
|
||||||
<em><font-awesome-icon icon="trash-alt"/></em>
|
<em><font-awesome-icon icon="trash-alt"/></em>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="tab === 'help'">
|
<template v-if="tab === 'help'">
|
||||||
<!-- Help -->
|
<!-- Help -->
|
||||||
<li class="headline">Help</li>
|
<li class="headline">{{ $t("menu.help") }}</li>
|
||||||
<li @click="toggleModal('reference')">
|
<li @click="toggleModal('reference')">
|
||||||
Reference Sheet
|
{{ $t("menu.reference-sheet") }}
|
||||||
<em>[R]</em>
|
<em>[R]</em>
|
||||||
</li>
|
</li>
|
||||||
<li @click="toggleModal('nightOrder')">
|
<li @click="toggleModal('nightOrder')">
|
||||||
Night Order Sheet
|
{{ $t("menu.night-order-sheet") }}
|
||||||
<em>[N]</em>
|
<em>[N]</em>
|
||||||
</li>
|
</li>
|
||||||
<li @click="toggleModal('gameState')">
|
<li @click="toggleModal('gameState')">
|
||||||
Game State JSON
|
{{ $t("menu.game-state-json") }}
|
||||||
<em><font-awesome-icon icon="file-code"/></em>
|
<em><font-awesome-icon icon="file-code"/></em>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="https://discord.gg/Gd7ybwWbFk" target="_blank">
|
<a href="https://discord.gg/Gd7ybwWbFk" target="_blank">
|
||||||
Join Discord
|
{{ $t("menu.join-discord") }}
|
||||||
</a>
|
</a>
|
||||||
<em>
|
<em>
|
||||||
<a href="https://discord.gg/Gd7ybwWbFk" target="_blank">
|
<a href="https://discord.gg/Gd7ybwWbFk" target="_blank">
|
||||||
|
@ -216,7 +223,7 @@
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="https://github.com/bra1n/townsquare" target="_blank">
|
<a href="https://github.com/bra1n/townsquare" target="_blank">
|
||||||
Source code
|
{{ $t("menu.source-code") }}
|
||||||
</a>
|
</a>
|
||||||
<em>
|
<em>
|
||||||
<a href="https://github.com/bra1n/townsquare" target="_blank">
|
<a href="https://github.com/bra1n/townsquare" target="_blank">
|
||||||
|
@ -245,7 +252,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setBackground() {
|
setBackground() {
|
||||||
const background = prompt("Enter custom background URL");
|
const background = prompt(this.$t("menu.enter-background"));
|
||||||
if (background || background === "") {
|
if (background || background === "") {
|
||||||
this.$store.commit("setBackground", background);
|
this.$store.commit("setBackground", background);
|
||||||
}
|
}
|
||||||
|
@ -253,7 +260,7 @@ export default {
|
||||||
hostSession() {
|
hostSession() {
|
||||||
if (this.session.sessionId) return;
|
if (this.session.sessionId) return;
|
||||||
const sessionId = prompt(
|
const sessionId = prompt(
|
||||||
"Enter a channel number / name for your session",
|
this.$t("menu.create-session"),
|
||||||
Math.round(Math.random() * 10000)
|
Math.round(Math.random() * 10000)
|
||||||
);
|
);
|
||||||
if (sessionId) {
|
if (sessionId) {
|
||||||
|
@ -270,8 +277,7 @@ export default {
|
||||||
},
|
},
|
||||||
distributeRoles() {
|
distributeRoles() {
|
||||||
if (this.session.isSpectator) return;
|
if (this.session.isSpectator) return;
|
||||||
const popup =
|
const popup = this.$t("menu.distribute-roles");
|
||||||
"Do you want to distribute assigned characters to all SEATED players?";
|
|
||||||
if (confirm(popup)) {
|
if (confirm(popup)) {
|
||||||
this.$store.commit("session/distributeRoles", true);
|
this.$store.commit("session/distributeRoles", true);
|
||||||
setTimeout(
|
setTimeout(
|
||||||
|
@ -283,17 +289,14 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
imageOptIn() {
|
imageOptIn() {
|
||||||
const popup =
|
const popup = this.$t("menu.custom-images-warn");
|
||||||
"Are you sure you want to allow custom images? A malicious script file author might track your IP address this way.";
|
|
||||||
if (this.grimoire.isImageOptIn || confirm(popup)) {
|
if (this.grimoire.isImageOptIn || confirm(popup)) {
|
||||||
this.toggleImageOptIn();
|
this.toggleImageOptIn();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
joinSession() {
|
joinSession() {
|
||||||
if (this.session.sessionId) return this.leaveSession();
|
if (this.session.sessionId) return this.leaveSession();
|
||||||
let sessionId = prompt(
|
let sessionId = prompt(this.$t("menu.join-session"));
|
||||||
"Enter the channel number / name of the session you want to join"
|
|
||||||
);
|
|
||||||
if (sessionId.match(/^https?:\/\//i)) {
|
if (sessionId.match(/^https?:\/\//i)) {
|
||||||
sessionId = sessionId.split("#").pop();
|
sessionId = sessionId.split("#").pop();
|
||||||
}
|
}
|
||||||
|
@ -305,7 +308,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
leaveSession() {
|
leaveSession() {
|
||||||
if (confirm("Are you sure you want to leave the active live game?")) {
|
if (confirm(this.$t("menu.leave-warn"))) {
|
||||||
this.$store.commit("session/setSpectator", false);
|
this.$store.commit("session/setSpectator", false);
|
||||||
this.$store.commit("session/setSessionId", "");
|
this.$store.commit("session/setSessionId", "");
|
||||||
}
|
}
|
||||||
|
@ -313,20 +316,20 @@ export default {
|
||||||
addPlayer() {
|
addPlayer() {
|
||||||
if (this.session.isSpectator) return;
|
if (this.session.isSpectator) return;
|
||||||
if (this.players.length >= 20) return;
|
if (this.players.length >= 20) return;
|
||||||
const name = prompt("Player name");
|
const name = prompt(this.$t("menu.player-name"));
|
||||||
if (name) {
|
if (name) {
|
||||||
this.$store.commit("players/add", name);
|
this.$store.commit("players/add", name);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
randomizeSeatings() {
|
randomizeSeatings() {
|
||||||
if (this.session.isSpectator) return;
|
if (this.session.isSpectator) return;
|
||||||
if (confirm("Are you sure you want to randomize seatings?")) {
|
if (confirm(this.$t("menu.randomize-warn"))) {
|
||||||
this.$store.dispatch("players/randomize");
|
this.$store.dispatch("players/randomize");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clearPlayers() {
|
clearPlayers() {
|
||||||
if (this.session.isSpectator) return;
|
if (this.session.isSpectator) return;
|
||||||
if (confirm("Are you sure you want to remove all players?")) {
|
if (confirm(this.$t("menu.remove-players-warn"))) {
|
||||||
// abort vote if in progress
|
// abort vote if in progress
|
||||||
if (this.session.nomination) {
|
if (this.session.nomination) {
|
||||||
this.$store.commit("session/nomination");
|
this.$store.commit("session/nomination");
|
||||||
|
@ -335,7 +338,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clearRoles() {
|
clearRoles() {
|
||||||
if (confirm("Are you sure you want to remove all player roles?")) {
|
if (confirm(this.$t("menu.remove-roles-warn"))) {
|
||||||
this.$store.dispatch("players/clearRoles");
|
this.$store.dispatch("players/clearRoles");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -124,35 +124,37 @@
|
||||||
(session.isSpectator && player.id === session.playerId)
|
(session.isSpectator && player.id === session.playerId)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<font-awesome-icon icon="venus-mars" />Change Pronouns
|
<font-awesome-icon icon="venus-mars" />
|
||||||
|
{{ $t("player.change-pronouns") }}
|
||||||
</li>
|
</li>
|
||||||
<template v-if="!session.isSpectator">
|
<template v-if="!session.isSpectator">
|
||||||
<li @click="changeName">
|
<li @click="changeName">
|
||||||
<font-awesome-icon icon="user-edit" />Rename
|
<font-awesome-icon icon="user-edit" />
|
||||||
|
{{ $t("player.rename") }}
|
||||||
</li>
|
</li>
|
||||||
<li @click="movePlayer()" :class="{ disabled: session.lockedVote }">
|
<li @click="movePlayer()" :class="{ disabled: session.lockedVote }">
|
||||||
<font-awesome-icon icon="redo-alt" />
|
<font-awesome-icon icon="redo-alt" />
|
||||||
Move player
|
{{ $t("player.move-player") }}
|
||||||
</li>
|
</li>
|
||||||
<li @click="swapPlayer()" :class="{ disabled: session.lockedVote }">
|
<li @click="swapPlayer()" :class="{ disabled: session.lockedVote }">
|
||||||
<font-awesome-icon icon="exchange-alt" />
|
<font-awesome-icon icon="exchange-alt" />
|
||||||
Swap seats
|
{{ $t("player.swap-seats") }}
|
||||||
</li>
|
</li>
|
||||||
<li @click="removePlayer" :class="{ disabled: session.lockedVote }">
|
<li @click="removePlayer" :class="{ disabled: session.lockedVote }">
|
||||||
<font-awesome-icon icon="times-circle" />
|
<font-awesome-icon icon="times-circle" />
|
||||||
Remove
|
{{ $t("player.remove") }}
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
@click="updatePlayer('id', '', true)"
|
@click="updatePlayer('id', '', true)"
|
||||||
v-if="player.id && session.sessionId"
|
v-if="player.id && session.sessionId"
|
||||||
>
|
>
|
||||||
<font-awesome-icon icon="chair" />
|
<font-awesome-icon icon="chair" />
|
||||||
Empty seat
|
{{ $t("player.empty-seat") }}
|
||||||
</li>
|
</li>
|
||||||
<template v-if="!session.nomination">
|
<template v-if="!session.nomination">
|
||||||
<li @click="nominatePlayer()">
|
<li @click="nominatePlayer()">
|
||||||
<font-awesome-icon icon="hand-point-right" />
|
<font-awesome-icon icon="hand-point-right" />
|
||||||
Nomination
|
{{ $t("player.nomination") }}
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -163,12 +165,12 @@
|
||||||
>
|
>
|
||||||
<font-awesome-icon icon="chair" />
|
<font-awesome-icon icon="chair" />
|
||||||
<template v-if="!player.id">
|
<template v-if="!player.id">
|
||||||
Claim seat
|
{{ $t("player.claim-seat") }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="player.id === session.playerId">
|
<template v-else-if="player.id === session.playerId">
|
||||||
Vacate seat
|
{{ $t("player.vacate-seat") }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else> Seat occupied</template>
|
<template v-else> {{ $t("player.seat-occupied") }}</template>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</transition>
|
</transition>
|
||||||
|
@ -286,7 +288,8 @@ export default {
|
||||||
},
|
},
|
||||||
changeName() {
|
changeName() {
|
||||||
if (this.session.isSpectator) return;
|
if (this.session.isSpectator) return;
|
||||||
const name = prompt("Player name", this.player.name) || this.player.name;
|
const name =
|
||||||
|
prompt(this.$t("player.player-name"), this.player.name) || this.player.name;
|
||||||
this.updatePlayer("name", name, true);
|
this.updatePlayer("name", name, true);
|
||||||
},
|
},
|
||||||
removeReminder(reminder) {
|
removeReminder(reminder) {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
}"
|
}"
|
||||||
></li>
|
></li>
|
||||||
<li v-if="players.length - teams.traveler < 5">
|
<li v-if="players.length - teams.traveler < 5">
|
||||||
Please add more players!
|
{{ $t("town-info.add-more") }}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="meta" v-if="!edition.isOfficial">
|
<span class="meta" v-if="!edition.isOfficial">
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="grimoire.isNight">
|
<span v-if="grimoire.isNight">
|
||||||
Night phase
|
{{ $t("town-info.night-phase") }}
|
||||||
<font-awesome-icon :icon="['fas', 'cloud-moon']" />
|
<font-awesome-icon :icon="['fas', 'cloud-moon']" />
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -30,8 +30,12 @@
|
||||||
:class="{ closed: !isBluffsOpen }"
|
:class="{ closed: !isBluffsOpen }"
|
||||||
>
|
>
|
||||||
<h3>
|
<h3>
|
||||||
<span v-if="session.isSpectator">Other characters</span>
|
<span v-if="session.isSpectator">
|
||||||
<span v-else>Demon bluffs</span>
|
{{ $t("townsquare.other-characters") }}
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
{{ $t("townsquare.demon-bluffs") }}
|
||||||
|
</span>
|
||||||
<font-awesome-icon icon="times-circle" @click.stop="toggleBluffs" />
|
<font-awesome-icon icon="times-circle" @click.stop="toggleBluffs" />
|
||||||
<font-awesome-icon icon="plus-circle" @click.stop="toggleBluffs" />
|
<font-awesome-icon icon="plus-circle" @click.stop="toggleBluffs" />
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -48,7 +52,9 @@
|
||||||
|
|
||||||
<div class="fabled" :class="{ closed: !isFabledOpen }" v-if="fabled.length">
|
<div class="fabled" :class="{ closed: !isFabledOpen }" v-if="fabled.length">
|
||||||
<h3>
|
<h3>
|
||||||
<span>Fabled</span>
|
<span>
|
||||||
|
{{ $t("townsquare.fabled") }}
|
||||||
|
</span>
|
||||||
<font-awesome-icon icon="times-circle" @click.stop="toggleFabled" />
|
<font-awesome-icon icon="times-circle" @click.stop="toggleFabled" />
|
||||||
<font-awesome-icon icon="plus-circle" @click.stop="toggleFabled" />
|
<font-awesome-icon icon="plus-circle" @click.stop="toggleFabled" />
|
||||||
</h3>
|
</h3>
|
||||||
|
|
|
@ -6,22 +6,24 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="overlay">
|
<div class="overlay">
|
||||||
<audio src="../assets/sounds/countdown.mp3" preload="auto"></audio>
|
<audio src="../assets/sounds/countdown.mp3" preload="auto"></audio>
|
||||||
<em class="blue">{{ nominator.name }}</em> nominated
|
<em class="blue">{{ nominator.name }}</em> {{ $t("vote.nominated") }}
|
||||||
<em>{{ nominee.name }}</em
|
<em>{{ nominee.name }}</em
|
||||||
>!
|
>!
|
||||||
<br />
|
<br />
|
||||||
<em class="blue">
|
<em class="blue">
|
||||||
{{ voters.length }} vote{{ voters.length !== 1 ? "s" : "" }}
|
{{ voters.length }} {{ $t("vote.vote") }}{{ voters.length !== 1 ? "s" : "" }}
|
||||||
</em>
|
</em>
|
||||||
in favor
|
{{ $t("vote.in-favor") }}
|
||||||
<em v-if="nominee.role.team !== 'traveler'">
|
<em v-if="nominee.role.team !== 'traveler'">
|
||||||
(majority is {{ Math.ceil(alive / 2) }})
|
({{ $t("vote.majority-is") }} {{ Math.ceil(alive / 2) }})
|
||||||
|
</em>
|
||||||
|
<em v-else>
|
||||||
|
({{ $t("vote.majority-is") }} {{ Math.ceil(players.length / 2) }})
|
||||||
</em>
|
</em>
|
||||||
<em v-else>(majority is {{ Math.ceil(players.length / 2) }})</em>
|
|
||||||
|
|
||||||
<template v-if="!session.isSpectator">
|
<template v-if="!session.isSpectator">
|
||||||
<div v-if="!session.isVoteInProgress && session.lockedVote < 1">
|
<div v-if="!session.isVoteInProgress && session.lockedVote < 1">
|
||||||
Time per player:
|
{{ $t("vote.time-per-player") }}:
|
||||||
<font-awesome-icon
|
<font-awesome-icon
|
||||||
@mousedown.prevent="setVotingSpeed(-500)"
|
@mousedown.prevent="setVotingSpeed(-500)"
|
||||||
icon="minus-circle"
|
icon="minus-circle"
|
||||||
|
@ -38,10 +40,10 @@
|
||||||
v-if="!session.isVoteInProgress"
|
v-if="!session.isVoteInProgress"
|
||||||
@click="countdown"
|
@click="countdown"
|
||||||
>
|
>
|
||||||
Countdown
|
{{ $t("vote.countdown") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="button" v-if="!session.isVoteInProgress" @click="start">
|
<div class="button" v-if="!session.isVoteInProgress" @click="start">
|
||||||
{{ session.lockedVote ? "Restart" : "Start" }}
|
{{ session.lockedVote ? $t("vote.restart") : $t("vote.start") }}
|
||||||
</div>
|
</div>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div
|
<div
|
||||||
|
@ -49,11 +51,11 @@
|
||||||
:class="{ disabled: !session.lockedVote }"
|
:class="{ disabled: !session.lockedVote }"
|
||||||
@click="pause"
|
@click="pause"
|
||||||
>
|
>
|
||||||
{{ voteTimer ? "Pause" : "Resume" }}
|
{{ voteTimer ? $t("vote.pause") : $t("vote.resume") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="button" @click="stop">Reset</div>
|
<div class="button" @click="stop">{{ $t("vote.reset") }}</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="button demon" @click="finish">Close</div>
|
<div class="button demon" @click="finish">{{ $t("vote.close") }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-group mark" v-if="nominee.role.team !== 'traveler'">
|
<div class="button-group mark" v-if="nominee.role.team !== 'traveler'">
|
||||||
<div
|
<div
|
||||||
|
@ -63,16 +65,16 @@
|
||||||
}"
|
}"
|
||||||
@click="setMarked"
|
@click="setMarked"
|
||||||
>
|
>
|
||||||
Mark for execution
|
{{ $t("vote.mark-execution") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="button" @click="removeMarked">
|
<div class="button" @click="removeMarked">
|
||||||
Clear mark
|
{{ $t("vote.clear-mark") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="canVote">
|
<template v-else-if="canVote">
|
||||||
<div v-if="!session.isVoteInProgress">
|
<div v-if="!session.isVoteInProgress">
|
||||||
{{ session.votingSpeed / 1000 }} seconds between votes
|
{{ session.votingSpeed / 1000 }} {{ $t("vote.seconds-between-votes") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<div
|
<div
|
||||||
|
@ -80,20 +82,18 @@
|
||||||
@click="vote(false)"
|
@click="vote(false)"
|
||||||
:class="{ disabled: !currentVote }"
|
:class="{ disabled: !currentVote }"
|
||||||
>
|
>
|
||||||
Hand DOWN
|
{{ $t("vote.hand-down") }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="button demon"
|
class="button demon"
|
||||||
@click="vote(true)"
|
@click="vote(true)"
|
||||||
:class="{ disabled: currentVote }"
|
:class="{ disabled: currentVote }"
|
||||||
>
|
>
|
||||||
Hand UP
|
{{ $t("vote.hand-up") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-else-if="!player">
|
<div v-else-if="!player">{{ $t("vote.claim-seat") }}.</div>
|
||||||
Please claim a seat to vote.
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<transition name="blur">
|
<transition name="blur">
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<Modal class="editions" v-if="modals.edition" @close="toggleModal('edition')">
|
<Modal class="editions" v-if="modals.edition" @close="toggleModal('edition')">
|
||||||
<div v-if="!isCustom">
|
<div v-if="!isCustom">
|
||||||
<h3>Select an edition:</h3>
|
<h3>{{ $t("edition-modal.select-edition") }}</h3>
|
||||||
<ul class="editions">
|
<ul class="editions">
|
||||||
<li
|
<li
|
||||||
v-for="edition in editions"
|
v-for="edition in editions"
|
||||||
|
@ -24,29 +24,34 @@
|
||||||
backgroundImage: `url(${require('../../assets/editions/custom.png')})`
|
backgroundImage: `url(${require('../../assets/editions/custom.png')})`
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
Custom Script / Characters
|
{{ $t("edition-modal.custom-script") }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="custom" v-else>
|
<div class="custom" v-else>
|
||||||
<h3>Load custom script / characters</h3>
|
<h3>{{ $t("edition-modal.load-script-title") }}</h3>
|
||||||
To play with a custom script, you need to select the characters you want
|
<i18n path="edition-modal.load-script-help" tag="span">
|
||||||
to play with in the official
|
<template #link>
|
||||||
<a href="https://bloodontheclocktower.com/script-tool/" target="_blank"
|
<a
|
||||||
>Script Tool</a
|
href="https://bloodontheclocktower.com/script-tool/"
|
||||||
|
target="_blank"
|
||||||
|
>{{ $t("edition-modal.script-tool") }}</a
|
||||||
>
|
>
|
||||||
and then upload the generated "custom-list.json" either directly here or
|
</template>
|
||||||
provide a URL to such a hosted JSON file.<br />
|
</i18n>
|
||||||
<br />
|
<br />
|
||||||
To play with custom characters, please read
|
<br />
|
||||||
|
<i18n path="edition-modal.custom-characters-notice">
|
||||||
|
<template #documentation>
|
||||||
<a
|
<a
|
||||||
href="https://github.com/bra1n/townsquare#custom-characters"
|
href="https://github.com/bra1n/townsquare#custom-characters"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>the documentation</a
|
>{{ $t("edition-modal.documentation") }}</a
|
||||||
>
|
>
|
||||||
on how to write a custom character definition file.
|
</template>
|
||||||
<b>Only load custom JSON files from sources that you trust!</b>
|
</i18n>
|
||||||
<h3>Some popular custom scripts:</h3>
|
<b> {{ $t("edition-modal.trusted-sources") }}</b>
|
||||||
|
<h3>{{ $t("edition-modal.popular-scripts") }}</h3>
|
||||||
<ul class="scripts">
|
<ul class="scripts">
|
||||||
<li
|
<li
|
||||||
v-for="(script, index) in scripts"
|
v-for="(script, index) in scripts"
|
||||||
|
@ -64,13 +69,13 @@
|
||||||
/>
|
/>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<div class="button" @click="openUpload">
|
<div class="button" @click="openUpload">
|
||||||
<font-awesome-icon icon="file-upload" /> Upload JSON
|
<font-awesome-icon icon="file-upload" /> {{ $t("edition-modal.upload-json") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="button" @click="promptURL">
|
<div class="button" @click="promptURL">
|
||||||
<font-awesome-icon icon="link" /> Enter URL
|
<font-awesome-icon icon="link" /> {{ $t("edition-modal.enter-url") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="button" @click="isCustom = false">
|
<div class="button" @click="isCustom = false">
|
||||||
<font-awesome-icon icon="undo" /> Back
|
<font-awesome-icon icon="undo" /> {{ $t("edition-modal.back") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<Modal v-if="modals.fabled && fabled.length" @close="toggleModal('fabled')">
|
<Modal v-if="modals.fabled && fabled.length" @close="toggleModal('fabled')">
|
||||||
<h3>
|
<h3>
|
||||||
Choose a fabled character to add to the game
|
{{ $t("fabled-modal.choose-fabled") }}
|
||||||
</h3>
|
</h3>
|
||||||
<ul class="tokens">
|
<ul class="tokens">
|
||||||
<li v-for="role in fabled" :key="role.id" @click="setFabled(role)">
|
<li v-for="role in fabled" :key="role.id" @click="setFabled(role)">
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
v-if="modals.gameState"
|
v-if="modals.gameState"
|
||||||
@close="toggleModal('gameState')"
|
@close="toggleModal('gameState')"
|
||||||
>
|
>
|
||||||
<h3>Current Game State</h3>
|
<h3>{{ $t("game-state-modal.current-game-state") }}</h3>
|
||||||
<textarea
|
<textarea
|
||||||
:value="gamestate"
|
:value="gamestate"
|
||||||
@input.stop="input = $event.target.value"
|
@input.stop="input = $event.target.value"
|
||||||
|
@ -13,10 +13,10 @@
|
||||||
></textarea>
|
></textarea>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<div class="button townsfolk" @click="copy">
|
<div class="button townsfolk" @click="copy">
|
||||||
<font-awesome-icon icon="copy" /> Copy JSON
|
<font-awesome-icon icon="copy" /> {{ $t("game-state-modal.copy-json") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="button demon" @click="load" v-if="!session.isSpectator">
|
<div class="button demon" @click="load" v-if="!session.isSpectator">
|
||||||
<font-awesome-icon icon="cog" /> Load State
|
<font-awesome-icon icon="cog" /> {{ $t("game-state-modal.load-state") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
@click="toggleModal('reference')"
|
@click="toggleModal('reference')"
|
||||||
icon="address-card"
|
icon="address-card"
|
||||||
class="toggle"
|
class="toggle"
|
||||||
title="Show Character Reference"
|
:title="this.$t('show-reference')"
|
||||||
/>
|
/>
|
||||||
<h3>
|
<h3>
|
||||||
Night Order
|
{{ $t("night-order-modal.night-order") }}
|
||||||
<font-awesome-icon icon="cloud-moon" />
|
<font-awesome-icon icon="cloud-moon" />
|
||||||
{{ edition.name || "Custom Script" }}
|
{{ edition.name || "Custom Script" }}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="night">
|
<div class="night">
|
||||||
<ul class="first">
|
<ul class="first">
|
||||||
<li class="headline">First Night</li>
|
<li class="headline">{{ $t("night-order-modal.first-night") }}</li>
|
||||||
<li
|
<li
|
||||||
v-for="role in rolesFirstNight"
|
v-for="role in rolesFirstNight"
|
||||||
:key="role.name"
|
:key="role.name"
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="other">
|
<ul class="other">
|
||||||
<li class="headline">Other Nights</li>
|
<li class="headline">{{ $t("night-order-modal.other-nights") }}</li>
|
||||||
<li
|
<li
|
||||||
v-for="role in rolesOtherNight"
|
v-for="role in rolesOtherNight"
|
||||||
:key="role.name"
|
:key="role.name"
|
||||||
|
@ -114,24 +114,19 @@ export default {
|
||||||
rolesFirstNight.push(
|
rolesFirstNight.push(
|
||||||
{
|
{
|
||||||
id: "evil",
|
id: "evil",
|
||||||
name: "Minion info",
|
name: this.$t("night-order-modal.minion-info"),
|
||||||
firstNight: 4,
|
firstNight: 4,
|
||||||
team: "minion",
|
team: "minion",
|
||||||
players: this.players.filter(p => p.role.team === "minion"),
|
players: this.players.filter(p => p.role.team === "minion"),
|
||||||
firstNightReminder:
|
firstNightReminder: this.$t("night-order-modal.minion-reminder")
|
||||||
"• If more than one Minion, they all make eye contact with each other. " +
|
|
||||||
"• Show the “This is the Demon” card. Point to the Demon."
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "evil",
|
id: "evil",
|
||||||
name: "Demon info & bluffs",
|
name: this.$t("night-order-modal.demon-info"),
|
||||||
firstNight: 7,
|
firstNight: 7,
|
||||||
team: "demon",
|
team: "demon",
|
||||||
players: this.players.filter(p => p.role.team === "demon"),
|
players: this.players.filter(p => p.role.team === "demon"),
|
||||||
firstNightReminder:
|
firstNightReminder: this.$t("night-order-modal.demon-reminder")
|
||||||
"• Show the “These are your minions” card. Point to each Minion. " +
|
|
||||||
"• Show the “These characters are not in play” card. Show 3 character tokens of good " +
|
|
||||||
"characters not in play."
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
@click="toggleModal('nightOrder')"
|
@click="toggleModal('nightOrder')"
|
||||||
icon="cloud-moon"
|
icon="cloud-moon"
|
||||||
class="toggle"
|
class="toggle"
|
||||||
title="Show Night Order"
|
:title="this.$t('show-night-order')"
|
||||||
/>
|
/>
|
||||||
<h3>
|
<h3>
|
||||||
Character Reference
|
{{ $t("reference-modal.character-reference") }}
|
||||||
<font-awesome-icon icon="address-card" />
|
<font-awesome-icon icon="address-card" />
|
||||||
{{ edition.name || "Custom Script" }}
|
{{ edition.name || "Custom Script" }}
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
:class="['team', team]"
|
:class="['team', team]"
|
||||||
>
|
>
|
||||||
<aside>
|
<aside>
|
||||||
<h4>{{ team }}</h4>
|
<h4>{{ $t(team) || team }}</h4>
|
||||||
</aside>
|
</aside>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="role in teamRoles" :class="[team]" :key="role.id">
|
<li v-for="role in teamRoles" :class="[team]" :key="role.id">
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
|
|
||||||
<div class="team jinxed" v-if="jinxed.length">
|
<div class="team jinxed" v-if="jinxed.length">
|
||||||
<aside>
|
<aside>
|
||||||
<h4>Jinxed</h4>
|
<h4>{{ $t("reference-modal.jinxed") }}</h4>
|
||||||
</aside>
|
</aside>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="(jinx, index) in jinxed" :key="index">
|
<li v-for="(jinx, index) in jinxed" :key="index">
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
v-if="modals.reminder && availableReminders.length && players[playerIndex]"
|
v-if="modals.reminder && availableReminders.length && players[playerIndex]"
|
||||||
@close="toggleModal('reminder')"
|
@close="toggleModal('reminder')"
|
||||||
>
|
>
|
||||||
<h3>Choose a reminder token:</h3>
|
<h3>{{ $t("reminder-token") }}:</h3>
|
||||||
<ul class="reminders">
|
<ul class="reminders">
|
||||||
<li
|
<li
|
||||||
v-for="reminder in availableReminders"
|
v-for="reminder in availableReminders"
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<Modal v-if="modals.role && availableRoles.length" @close="close">
|
<Modal v-if="modals.role && availableRoles.length" @close="close">
|
||||||
<h3>
|
<h3>
|
||||||
Choose a new character for
|
|
||||||
{{
|
{{
|
||||||
|
$t("role-modal.choose-character", {
|
||||||
|
player:
|
||||||
playerIndex >= 0 && players.length
|
playerIndex >= 0 && players.length
|
||||||
? players[playerIndex].name
|
? players[playerIndex].name
|
||||||
: "bluffing"
|
: $t("role-modal.bluffing")
|
||||||
|
})
|
||||||
}}
|
}}
|
||||||
</h3>
|
</h3>
|
||||||
<ul class="tokens" v-if="tab === 'editionRoles' || !otherTravelers.size">
|
<ul class="tokens" v-if="tab === 'editionRoles' || !otherTravelers.size">
|
||||||
|
@ -36,14 +38,16 @@
|
||||||
class="button"
|
class="button"
|
||||||
:class="{ townsfolk: tab === 'editionRoles' }"
|
:class="{ townsfolk: tab === 'editionRoles' }"
|
||||||
@click="tab = 'editionRoles'"
|
@click="tab = 'editionRoles'"
|
||||||
>Edition Roles</span
|
|
||||||
>
|
>
|
||||||
|
{{ $t("role-modal.edition-roles") }}
|
||||||
|
</span>
|
||||||
<span
|
<span
|
||||||
class="button"
|
class="button"
|
||||||
:class="{ townsfolk: tab === 'otherTravelers' }"
|
:class="{ townsfolk: tab === 'otherTravelers' }"
|
||||||
@click="tab = 'otherTravelers'"
|
@click="tab = 'otherTravelers'"
|
||||||
>Other Travelers</span
|
|
||||||
>
|
>
|
||||||
|
{{ $t("role-modal.other-travelers") }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -4,7 +4,11 @@
|
||||||
v-if="modals.roles && nonTravelers >= 5"
|
v-if="modals.roles && nonTravelers >= 5"
|
||||||
@close="toggleModal('roles')"
|
@close="toggleModal('roles')"
|
||||||
>
|
>
|
||||||
<h3>Select the characters for {{ nonTravelers }} players:</h3>
|
<i18n path="roles-modal.select-roles" tag="h3">
|
||||||
|
<template #nonTravelers>
|
||||||
|
{{ nonTravelers }}
|
||||||
|
</template>
|
||||||
|
</i18n>
|
||||||
<ul class="tokens" v-for="(teamRoles, team) in roleSelection" :key="team">
|
<ul class="tokens" v-for="(teamRoles, team) in roleSelection" :key="team">
|
||||||
<li class="count" :class="[team]">
|
<li class="count" :class="[team]">
|
||||||
{{ teamRoles.reduce((a, { selected }) => a + selected, 0) }} /
|
{{ teamRoles.reduce((a, { selected }) => a + selected, 0) }} /
|
||||||
|
@ -31,14 +35,13 @@
|
||||||
<div class="warning" v-if="hasSelectedSetupRoles">
|
<div class="warning" v-if="hasSelectedSetupRoles">
|
||||||
<font-awesome-icon icon="exclamation-triangle" />
|
<font-awesome-icon icon="exclamation-triangle" />
|
||||||
<span>
|
<span>
|
||||||
Warning: there are characters selected that modify the game setup! The
|
{{ $t("roles-modal.warning-incorrect-setup") }}
|
||||||
randomizer does not account for these characters.
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<label class="multiple" :class="{ checked: allowMultiple }">
|
<label class="multiple" :class="{ checked: allowMultiple }">
|
||||||
<font-awesome-icon :icon="allowMultiple ? 'check-square' : 'square'" />
|
<font-awesome-icon :icon="allowMultiple ? 'check-square' : 'square'" />
|
||||||
<input type="checkbox" name="allow-multiple" v-model="allowMultiple" />
|
<input type="checkbox" name="allow-multiple" v-model="allowMultiple" />
|
||||||
Allow duplicate characters
|
{{ $t("roles-modal.allow-duplicate") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<div
|
<div
|
||||||
|
@ -49,11 +52,15 @@
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<font-awesome-icon icon="people-arrows" />
|
<font-awesome-icon icon="people-arrows" />
|
||||||
Assign {{ selectedRoles }} characters randomly
|
<i18n path="roles-modal.assign-randomly" tag="span">
|
||||||
|
<template #roles>
|
||||||
|
{{ selectedRoles }}
|
||||||
|
</template>
|
||||||
|
</i18n>
|
||||||
</div>
|
</div>
|
||||||
<div class="button" @click="selectRandomRoles">
|
<div class="button" @click="selectRandomRoles">
|
||||||
<font-awesome-icon icon="random" />
|
<font-awesome-icon icon="random" />
|
||||||
Shuffle characters
|
{{ $t("roles-modal.shuffle") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
v-if="session.isSpectator"
|
v-if="session.isSpectator"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<h3>Vote history</h3>
|
<h3>{{ $t("vote-history-modal.vote-history") }}</h3>
|
||||||
|
|
||||||
<template v-if="!session.isSpectator">
|
<template v-if="!session.isSpectator">
|
||||||
<div class="options">
|
<div class="options">
|
||||||
|
@ -23,26 +23,26 @@
|
||||||
session.isVoteHistoryAllowed ? 'check-square' : 'square'
|
session.isVoteHistoryAllowed ? 'check-square' : 'square'
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
Accessible to players
|
{{ $t("vote-history-modal.accessible-players") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="option" @click="clearVoteHistory">
|
<div class="option" @click="clearVoteHistory">
|
||||||
<font-awesome-icon icon="trash-alt" />
|
<font-awesome-icon icon="trash-alt" />
|
||||||
Clear for everyone
|
{{ $t("vote-history-modal.clear") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Time</td>
|
<td>{{ $t("vote-history-modal.time") }}</td>
|
||||||
<td>Nominator</td>
|
<td>{{ $t("vote-history-modal.nominator") }}</td>
|
||||||
<td>Nominee</td>
|
<td>{{ $t("vote-history-modal.nominee") }}</td>
|
||||||
<td>Type</td>
|
<td>{{ $t("vote-history-modal.type") }}</td>
|
||||||
<td>Votes</td>
|
<td>{{ $t("vote-history-modal.votes") }}</td>
|
||||||
<td>Majority</td>
|
<td>{{ $t("vote-history-modal.majority") }}</td>
|
||||||
<td>
|
<td>
|
||||||
<font-awesome-icon icon="user-friends" />
|
<font-awesome-icon icon="user-friends" />
|
||||||
Voters
|
{{ $t("vote-history-modal.voters") }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
12
src/main.js
12
src/main.js
|
@ -1,10 +1,12 @@
|
||||||
|
import { library } from "@fortawesome/fontawesome-svg-core";
|
||||||
|
import { fab } from "@fortawesome/free-brands-svg-icons";
|
||||||
|
import { fas } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
|
import VueI18n from "vue-i18n";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
import store from "./store";
|
import store from "./store";
|
||||||
import { library } from "@fortawesome/fontawesome-svg-core";
|
import en from "./assets/translations/en.json";
|
||||||
import { fas } from "@fortawesome/free-solid-svg-icons";
|
|
||||||
import { fab } from "@fortawesome/free-brands-svg-icons";
|
|
||||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
|
||||||
|
|
||||||
const faIcons = [
|
const faIcons = [
|
||||||
"AddressCard",
|
"AddressCard",
|
||||||
|
@ -60,8 +62,10 @@ library.add(
|
||||||
);
|
);
|
||||||
Vue.component("font-awesome-icon", FontAwesomeIcon);
|
Vue.component("font-awesome-icon", FontAwesomeIcon);
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
|
Vue.use(VueI18n);
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
render: h => h(App),
|
render: h => h(App),
|
||||||
|
i18n: new VueI18n({ locale: "en", fallbackLocale: "en", messages: { en } }),
|
||||||
store
|
store
|
||||||
}).$mount("#app");
|
}).$mount("#app");
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// if the app is supposed to run on Github Pages in a subfolder, use the following config:
|
// if the app is supposed to run on Github Pages in a subfolder, use the following config:
|
||||||
// publicPath: process.env.NODE_ENV === "production" ? "/townsquare/" : "/"
|
// publicPath: process.env.NODE_ENV === "production" ? "/townsquare/" : "/"
|
||||||
publicPath: process.env.NODE_ENV === "production" ? "/" : "/"
|
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
|
||||||
|
chainWebpack: config => {
|
||||||
|
config.module
|
||||||
|
.rule("i18n")
|
||||||
|
.resourceQuery(/blockType=i18n/)
|
||||||
|
.type("javascript/auto")
|
||||||
|
.use("i18n")
|
||||||
|
.loader("@kazupon/vue-i18n-loader")
|
||||||
|
.end();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue