localization

This commit is contained in:
Alberto Xamin 2020-11-27 17:59:33 +01:00
parent c6e0f957da
commit 3062bce6ca
No known key found for this signature in database
GPG Key ID: 4F026F48309500A2
12 changed files with 195 additions and 45 deletions

View File

@ -12,6 +12,7 @@
"pretty-checkbox-vue": "^1.1.9",
"socket.io-client": "^3.0.3",
"vue": "^2.6.11",
"vue-i18n": "^8.22.2",
"vue-socket.io": "^3.0.10"
},
"devDependencies": {

View File

@ -2,29 +2,29 @@
<div id="app" class="dark-mode">
<div v-if="!isInLobby" id="logo" class="center-stuff" style="margin-bottom:10pt;">
<h1 style="margin-bottom:0pt;">PewPew!</h1>
<i style="font-size: x-small;">Bang! è un marchio registrato DVGiochi</i>
<i style="font-size: x-small;">{{$t("trademark")}}</i>
</div>
<div v-if="isConnected">
<div v-if="!didSetUsername">
<p>Scegli un username:</p>
<p>{{$t("choose_username")}}</p>
<form @submit="setUsername">
<input v-model="username" />
<input type="submit"/>
</form>
<p>Giocatori online: {{onlinePlayers}}</p>
<p>{{$t("online_players")}}{{onlinePlayers}}</p>
</div>
<div v-else>
<div v-if="!isInLobby" >
<p>Giocatori online: {{onlinePlayers}}</p>
<p>{{$t("online_players")}}{{onlinePlayers}}</p>
<Card :card="getSelfCard" style="position:absolute; bottom:10pt; right: 10pt;"/>
<h2>Lobby disponibili:</h2>
<h2>{{$t("available_lobbies")}}</h2>
<div style="display: flex">
<Card v-for="lobby in openLobbies" v-bind:key="lobby.name" :card="getLobbyCard(lobby)" @click.native="joinLobby(lobby)"/>
<p v-if="noLobbyAvailable">Nessuna lobby disponibile</p>
<p v-if="noLobbyAvailable">{{$t("no_lobby_available")}}</p>
</div>
<form @submit="createLobby">
<h2>Crea una lobby:</h2>
<p>Nome:</p>
<h2>{{$t("create_lobby")}}</h2>
<p>{{$t("lobby_name")}}</p>
<input v-model="lobbyName"/>
<input type="submit" />
</form>
@ -33,9 +33,17 @@
</div>
</div>
<div v-else class="center-stuff">
<h2>Attenzione!</h2>
<p>Connessione al server assente.</p>
<h2>{{$t("warning")}}</h2>
<p>{{$t("connection_error")}}</p>
</div>
<select style="position:absolute;bottom:4pt;right:4pt;" v-model="$i18n.locale">
<option
v-for="(lang, i) in ['it.🇮🇹', 'en.🇬🇧']"
:key="`lang-${i}`"
:value="lang.split('.')[0]">
{{lang.split('.')[1]}} {{lang.split('.')[0]}}
</option>
</select>
</div>
</template>
@ -66,7 +74,7 @@ export default {
getSelfCard() {
return {
name: this.username,
number: 'YOU',
number: this.$t('you'),
icon: '🤠',
is_character: true,
}
@ -120,7 +128,7 @@ export default {
e.preventDefault();
},
joinLobby(lobby) {
let password = lobby.locked ? prompt("Room password:", "") : '';
let password = lobby.locked ? prompt(this.$t("room_password_prompt"), "") : '';
this.$socket.emit('join_room', {name:lobby.name,password:password})
},
init() {
@ -217,7 +225,7 @@ h1,h2,h3,h4,p,span,b,label{
transform: scale(0);
}
}
input {
input, select {
border: 2px solid;
border-radius: 4px;
font-size: 1rem;
@ -227,7 +235,7 @@ input {
transition: border-color 0.5s ease-out;
}
@media (prefers-color-scheme: dark) {
:root, #app, input {
:root, #app, input, select {
background-color: #181a1b;
color: rgb(174, 194, 211);
}

View File

@ -1,6 +1,6 @@
<template>
<div class="chat">
<h3>Chat</h3>
<h3>{{$t("chat")}}</h3>
<div id="chatbox">
<p style="margin:1pt;" class="chat-message" v-for="msg in messages" v-bind:key="msg">{{msg}}</p>
<p class="end">.</p>

View File

@ -24,7 +24,7 @@ export default {
cancel: Function,
cancelText: {
type: String,
default: 'ANNULLA',
default: '',
},
text: String,
hintText: String,
@ -43,7 +43,12 @@ export default {
showDesc(card) {
this.desc = card.desc
}
},
mounted() {
if (this.cancelText == '') {
this.cancelText = this.$t('cancel')
}
},
}
</script>

View File

@ -31,7 +31,7 @@ export default {
icon: '💥',
},
endTurnCard: {
name: 'Termina turno!',
name: this.$t('end_turn'),
icon: '⛔️'
},
lastScrap: null,

View File

@ -1,11 +1,11 @@
<template>
<div class="lobby">
<div style="flex-grow: 4;">
<h2 v-if="!started">Lobby: {{ lobbyName }}</h2>
<h3>Giocatori (tu sei {{username}})</h3>
<h2 v-if="!started">{{$t('room')}}{{ lobbyName }}</h2>
<h3>{{$t('room_players', {username:username})}}</h3>
<div v-if="!started">
<PrettyCheck v-if="isRoomOwner" class="p-switch p-fill" v-model="privateRoom" style="margin-top:5px; margin-bottom:3px;">Stanza Privata</PrettyCheck>
<label v-if="password !== ''">Password: <b class="selectable" style="font-size:larger;">{{ password }}</b></label>
<PrettyCheck v-if="isRoomOwner" class="p-switch p-fill" v-model="privateRoom" style="margin-top:5px; margin-bottom:3px;">{{$t("private_room")}}</PrettyCheck>
<label v-if="password !== ''">{{$t('password')}}<b class="selectable" style="font-size:larger;">{{ password }}</b></label>
</div>
<div class="players-table">
@ -28,7 +28,7 @@
<!-- </div> -->
</div>
<div v-if="!started">
<h3>Espansioni (NON COMPLETE)</h3>
<h3>{{$t("expansions")}}</h3>
<PrettyCheck @click.native="toggleExpansions('dodge_city')" :disabled="!isRoomOwner" v-model="useDodgeCity" class="p-switch p-fill" style="margin-top:5px; margin-bottom:3px;">Dodge City</PrettyCheck>
</div>
<div v-if="started">
@ -37,10 +37,10 @@
</div>
</div>
<chat/>
<Chooser v-if="selectedInfo" text="Dettagli" :cards="selectedInfo" cancelText="OK" :cancel="()=>{selectedInfo = null}" :select="()=>{selectedInfo = null}"/>
<Chooser v-if="selectedInfo" :text="$t('details')" :cards="selectedInfo" :cancelText="$t('ok')" :cancel="()=>{selectedInfo = null}" :select="()=>{selectedInfo = null}"/>
<transition name="bounce">
<Chooser v-if="showChooser" text="Scegli il tuo personaggio" :cards="availableCharacters" :select="setCharacter"/>
<Chooser v-if="hasToChoose" :text="`Scegli una carta${target_p?' da ' + target_p:''}`" :cards="chooseCards" :select="chooseCard"/>
<Chooser v-if="showChooser" :text="$t('choose_character')" :cards="availableCharacters" :select="setCharacter"/>
<Chooser v-if="hasToChoose" :text="`${$t('choose_card')}${target_p?$t('choose_card_from') + target_p:''}`" :cards="chooseCards" :select="chooseCard"/>
</transition>
</div>
</template>
@ -122,7 +122,7 @@ export default {
startGameCard() {
if (!this.started && this.players.length > 2 && this.isRoomOwner) {
return {
name: 'Start',
name: this.$t('start_game'),
icon: '▶️',
is_equipment: true,
number: `${this.players.length}🤠`
@ -165,7 +165,7 @@ export default {
getPlayerCard(player) {
return {
name: player.name,
number: ((this.username == player.name) ? 'YOU' : (this.players[0].name == player.name) ? 'OWNER' :'') + (player.dist ? `${player.dist}` : ''),
number: ((this.username == player.name) ? this.$t('you') : (this.players[0].name == player.name) ? this.$t('owner') :'') + (player.dist ? `${player.dist}` : ''),
icon: (player.lives === undefined || player.lives > 0) ? (player.is_sheriff ? '⭐' : player.icon || ((player.ready)?'👍': '🤠') ) : '☠️',
is_character: true,
}

View File

@ -17,7 +17,7 @@
<span v-for="(n, i) in (max_lives-lives)" v-bind:key="n" :alt="i">💀</span>
</transition-group>
<div v-if="lives > 0">
<span>Mano</span>
<span>{{$t('hand')}}</span>
<transition-group name="list" tag="div" class="hand">
<Card v-for="card in hand" v-bind:key="card.name+card.number" :card="card"
@click.native="play_card(card)"
@ -25,20 +25,20 @@
</transition-group>
</div>
<p>{{hint}}</p>
<Chooser v-if="card_against" text="Contro chi vuoi giocare la carta" :cards="visiblePlayers" :select="selectAgainst" :cancel="cancelCardAgainst"/>
<Chooser v-if="card_against" :text="$t('card_against')" :cards="visiblePlayers" :select="selectAgainst" :cancel="cancelCardAgainst"/>
<Chooser v-if="pending_action == 3" :text="respondText" :cards="respondCards" :select="respond"/>
<Chooser v-if="shouldChooseCard" text="Scegli che carta pescare" :cards="available_cards" :select="choose"/>
<Chooser v-if="lives <= 0 && max_lives > 0" text="SEI MORTO" cancelText="SPETTATORE" :cancel="()=>{max_lives = 0}"/>
<Chooser v-if="win_status !== undefined" :text="win_status?'HAI VINTO':'HAI PERSO'" />
<Chooser v-if="show_role" text="Tu sei" :cards="[my_role]" :hintText="my_role.goal" :select="() => {show_role=false}" :cancel="() => {show_role=false}" cancelText="OK" />
<Chooser v-if="notifycard" :key="notifycard.card" :text="`${notifycard.player} ha pescato come seconda carta:`" :cards="[notifycard.card]" hintText="Se la carta è cuori o quadri ne pesca un'altra" class="turn-notify-4s"/>
<Chooser v-if="!show_role && is_my_turn && pending_action < 2" text="GIOCA IL TUO TURNO" :key="is_my_turn" class="turn-notify" />
<Chooser v-if="hasToPickResponse" :text="`ESTRAI UNA CARTA ${attacker?('PER DIFENDERTI DA '+attacker):''}`" :key="hasToPickResponse" class="turn-notify" />
<Chooser v-if="!card_against && card_with" :text="`SCEGLI CHE CARTA SCARTARE PER USARE ${card_with.name.toUpperCase()}`" :cards="hand.filter(x => x !== card_with)" :select="selectWith" :cancel="()=>{card_with = null}"/>
<Chooser v-if="showScrapScreen" :text="`SCARTA ${hand.length}/${lives}`" :cards="hand" :select="scrap" :cancel="cancelEndingTurn"/>
<Chooser v-if="sidWantsScrapForHealth && sidScrapForHealth.length < 2" :text="`SCARTA ${2 - sidScrapForHealth.length} PER RECUPERARE 1 VITA`"
<Chooser v-if="shouldChooseCard" :text="$t('choose_card_to_get')" :cards="available_cards" :select="choose"/>
<Chooser v-if="lives <= 0 && max_lives > 0" :text="$t('you_died')" :cancelText="$t('spectate')" :cancel="()=>{max_lives = 0}"/>
<Chooser v-if="win_status !== undefined" :text="win_status?$t('you_win'):$t('you_lose')" />
<Chooser v-if="show_role" :text="$t('you_are')" :cards="[my_role]" :hintText="my_role.goal" :select="() => {show_role=false}" :cancel="() => {show_role=false}" :cancelText="$t('ok')" />
<Chooser v-if="notifycard" :key="notifycard.card" :text="`${notifycard.player} ${$t('did_pick_as')}:`" :cards="[notifycard.card]" :hintText="$t('if_card_red')" class="turn-notify-4s"/>
<Chooser v-if="!show_role && is_my_turn && pending_action < 2" :text="$t('play_your_turn')" :key="is_my_turn" class="turn-notify" />
<Chooser v-if="hasToPickResponse" :text="`${$t('pick_a_card')} ${attacker?($t('to_defend_from')+' '+attacker):''}`" :key="hasToPickResponse" class="turn-notify" />
<Chooser v-if="!card_against && card_with" :text="`${$t('choose_scarp_card_to')} ${card_with.name.toUpperCase()}`" :cards="hand.filter(x => x !== card_with)" :select="selectWith" :cancel="()=>{card_with = null}"/>
<Chooser v-if="showScrapScreen" :text="`${$t('discard')} ${hand.length}/${lives}`" :cards="hand" :select="scrap" :cancel="cancelEndingTurn"/>
<Chooser v-if="sidWantsScrapForHealth && sidScrapForHealth.length < 2" :text="`${$t('discard')} ${2 - sidScrapForHealth.length} ${$t('to_regain_1_hp')}`"
:cards="sidScrapHand" :select="sidScrap" :cancel="() => {sidWantsScrapForHealth = false;sidScrapForHealth=[]}"/>
<button v-if="is_my_turn && character.name === 'Sid Ketchum'" @click="sidWantsScrapForHealth=true">ABILITÀ SPECIALE</button>
<button v-if="is_my_turn && character.name === 'Sid Ketchum'" @click="sidWantsScrapForHealth=true">{{$t('special_ability')}}</button>
</div>
</template>
@ -133,7 +133,7 @@ export default {
},
computed:{
respondText() {
return `Scegli come rispondere ${this.attacker?('a '+this.attacker):''}${(this.mancato_needed>1)?(' (NE OCCORRONO ' + this.mancato_needed + ')'):''}`
return `${this.$t('choose_response')}${this.attacker?(this.$t('choose_response_to')+this.attacker):''}${(this.mancato_needed>1)?(` (${this.$t('choose_response_needed')} ` + this.mancato_needed + ')'):''}`
},
showScrapScreen() {
return this.isEndingTurn && !this.canEndTurn && this.is_my_turn;
@ -159,7 +159,7 @@ export default {
vis.push({
name: this.name,
number: 0,
icon: 'TU',
icon: this.$t('you'),
is_character: true,
})
}
@ -171,7 +171,7 @@ export default {
instruction() {
if (this.pending_action == null)
return ''
let x = ['▶️ Estrai una carta', '▶️ Pesca le tue carte', '▶️ Gioca le tue carte', '▶️ Rispondi alla carta', '⏸ Attendi', '▶️ Scegli una carta']
let x = [this.$t('flip_card'), this.$t('draw_cards'), this.$t('play_cards'), this.$t('respond_card'), this.$t('wait'), this.$t('choose_cards')]
return x[this.pending_action]
},
canEndTurn() {
@ -179,7 +179,7 @@ export default {
},
respondCards() {
let cc = [{
name: 'Prendi Danno',
name: this.$t('take_dmg'),
icon: '❌',
is_equipment: true,
}]

55
frontend/src/i18n/en.json Normal file
View File

@ -0,0 +1,55 @@
{
"trademark": "Bang! is a trademark owned by DVGiochi",
"online_players": "Online players: ",
"choose_username": "Pick an username:",
"available_lobbies": "Available Lobbies:",
"no_lobby_available": "No lobbies available",
"create_lobby": "Open a lobby:",
"lobby_name": "Name:",
"warning": "Warning!",
"connection_error": "Cannot connect to server.",
"chat": "Chat",
"end_turn": "End Turn!",
"start_game": "Start!",
"expansions": "Expansions",
"details": "Details",
"ok": "OK",
"you": "YOU",
"owner": "OWNER",
"cancel": "CANCEL",
"password": "Password: ",
"room_password_prompt": "Lobby Password: ",
"private_room": "Private Lobby",
"room": "Lobby: ",
"room_players": "Players (you are {username})",
"choose_character": "Choose your character",
"choose_card": "Choose a card",
"choose_card_from": " from ",
"flip_card": "▶️ Flip a card",
"draw_cards": "▶️ Draw you cards from the deck",
"play_cards": "▶️ Play your cards",
"respond_card":"▶️ Respond to the card",
"wait": "⏸ Wait",
"choose_cards": "▶️ Choose a card",
"take_dmg": "Take damage",
"choose_response": "Choose your response ",
"choose_response_to": "to ",
"choose_response_needed": "NEEDED ",
"hand": "HAND",
"card_against": "Who will you play your card against?",
"choose_card_to_get": "Choose a card",
"you_died":"YOU DIED",
"spectate":"SPECTATE",
"you_win":"YOU WON",
"you_lose":"YOU LOST",
"special_ability": "SPECIAL ABILITY",
"discard": "DISCARD",
"to_regain_1_hp": "TO REGAIN 1 HP",
"play_your_turn": "PLAY YOUR TURN",
"you_are": "You are",
"did_pick_as": "picked this as second card",
"if_card_red":"If the card is diamonds or hearts, he picks another card.",
"choose_scarp_card_to": "CHOOSE WHICH CARD TO DISCARD TO USE",
"pick_a_card": "FLIP A CARD",
"to_defend_from": "TO DEFEND YOURSELF FROM"
}

View File

@ -0,0 +1,9 @@
import it from './it.json'
import en from './en.json'
export const defaultLocale = 'it'
export const languages = {
it: it,
en: en,
}

55
frontend/src/i18n/it.json Normal file
View File

@ -0,0 +1,55 @@
{
"trademark": "Bang! è un marchio registrato DVGiochi",
"online_players": "Giocatori online: ",
"choose_username": "Scegli un username:",
"available_lobbies": "Stanze disponibili:",
"no_lobby_available": "Nessuna stanza disponibile",
"create_lobby": "Crea una stanza:",
"lobby_name": "Nome:",
"warning": "Attenzione!",
"connection_error": "Connessione al server assente.",
"chat": "Chat",
"end_turn": "Termina turno!",
"start_game": "Avvia!",
"expansions": "Espansioni",
"details": "Dettagli",
"ok": "OK",
"you": "TU",
"owner": "GESTORE",
"cancel": "ANNULLA",
"password": "Password: ",
"room_password_prompt": "Password Stanza: ",
"private_room": "Stanza Privata",
"room": "Stanza: ",
"room_players": "Giocatori (tu sei {username})",
"choose_character": "Scegli il tuo personaggio",
"choose_card": "Scegli una carta",
"choose_card_from": " da ",
"flip_card": "▶️ Estrai una carta",
"draw_cards": "▶️ Pesca le tue carte",
"play_cards": "▶️ Gioca le tue carte",
"respond_card": "▶️ Rispondi alla carta",
"wait": "⏸ Attendi",
"choose_cards": "▶️ Scegli una carta",
"take_dmg": "Prendi Danno",
"choose_response": "Scegli come rispondere ",
"choose_response_to": "a ",
"choose_response_needed": "NE OCCORRONO ",
"hand": "MANO",
"card_against": "Contro chi vuoi giocare la carta",
"choose_card_to_get": "Scegli che carta pescare",
"you_died": "SEI MORTO",
"spectate": "SPETTATORE",
"you_win": "HAI VINTO",
"you_lose": "HAI PERSO",
"special_ability": "ABILITÀ SPECIALE",
"discard": "SCARTA",
"to_regain_1_hp": "PER RECUPERARE 1 VITA",
"play_your_turn": "GIOCA IL TUO TURNO",
"you_are": "Tu sei",
"did_pick_as": "ha pescato come seconda carta",
"if_card_red": "Se la carta è cuori o quadri ne pesca un'altra",
"choose_scarp_card_to": "SCEGLI CHE CARTA SCARTARE PER USARE",
"pick_a_card": "ESTRAI UNA CARTA",
"to_defend_from": "PER DIFENDERTI DA"
}

View File

@ -11,6 +11,18 @@ Vue.use(new VueSocketIO({
import PrettyCheckbox from 'pretty-checkbox-vue';
Vue.use(PrettyCheckbox)
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
import { languages, defaultLocale } from './i18n';
const messages = Object.assign(languages)
const i18n = new VueI18n({
locale: defaultLocale,
messages
})
new Vue({
i18n,
render: h => h(App),
}).$mount('#app')

View File

@ -8310,6 +8310,11 @@ vue-hot-reload-api@^2.3.0:
resolved "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"
integrity sha1-UylVzB6yCKPZkLOp+acFdGV+CPI=
vue-i18n@^8.22.2:
version "8.22.2"
resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.22.2.tgz#58299a5a050e67b4f799d96fee7dd8bd269e0907"
integrity sha512-rb569fVJInPUgS/bbCxEQ9DrAoFTntuJvYoK4Fpk2VfNbA09WzdTKk57ppjz3S+ps9hW+p9H+2ASgMvojedkow==
"vue-loader-v16@npm:vue-loader@^16.0.0-beta.7":
version "16.0.0-rc.2"
resolved "https://registry.npm.taobao.org/vue-loader/download/vue-loader-16.0.0-rc.2.tgz?cache=0&sync_timestamp=1605670716799&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-16.0.0-rc.2.tgz#b6a7e7f30d28f35659a83de41f4a1831a4232a04"