Add translations for most of the rest of the UI

This commit is contained in:
Matt Isenhower
2017-12-04 12:57:37 -08:00
parent 211e48fc91
commit 0684e434f4
24 changed files with 460 additions and 19 deletions

View File

@@ -38,7 +38,7 @@
<div class="level-item" v-if="merchandises && merchandises.length">
<button class="button is-translucent-dark is-rounded" @click="splatNetGearOpen = true">
<span class="font-splatoon2">SplatNet Gear</span>
<span class="font-splatoon2">{{ $t('splatnet_gear.button') }}</span>
</button>
</div>
</div>
@@ -163,6 +163,7 @@
<script>
import axios from 'axios';
import { mapActions } from 'vuex';
import regions from '@/js/regions';
import Dropdown from './Dropdown.vue';
import ScheduleBox from './splatoon/ScheduleBox.vue';
@@ -178,7 +179,6 @@ export default {
components: { Dropdown, ScheduleBox, SalmonRunBox, SplatfestBox, NewWeaponBox, AboutDialog, SplatNetGearDialog },
data() {
return {
regions: regions.splatoonRegions,
actualSelectedRegionKey: null,
now: null,
splatnet: {
@@ -197,6 +197,12 @@ export default {
loading() { return !this.splatnet.schedules; },
// Selected region
regions() {
return regions.splatoonRegions.map(({ key }) => {
let name = (key) ? this.$t(`regions.${key}.name`) : this.$t('regions.global.name');
return { key, name };
});
},
selectedRegionKey: {
get() { return this.actualSelectedRegionKey; },
set(value) { this.setRegion(value); },
@@ -289,8 +295,10 @@ export default {
window.removeEventListener('storage', this.loadRegion);
},
methods: {
...mapActions(['loadLocale']),
loadLanguage() {
this.language = regions.detectSplatoonLanguage();
this.loadLocale(this.language);
this.$i18n.set(this.language || 'en');
},
loadRegion(autoDetect = false) {

View File

@@ -26,7 +26,7 @@ export default {
},
name() {
if (this.isFestival)
return 'Splatfest Battle';
return this.$t('splatfest.battle');
return this.$t(`splatnet.game_modes.${this.gameMode.key}.name`, this.gameMode.name);
},
},

View File

@@ -2,7 +2,7 @@
<div class="new-weapon-box font-splatoon2">
<div class="font-splatoon1 is-size-5 title-squid">
{{ title }}
{{ displayTitle }}
</div>
<div class="main-content-wrapper">
@@ -36,9 +36,12 @@
export default {
props: {
weapon: {},
title: { default: 'New Weapon' },
title: {},
},
computed: {
displayTitle() {
return this.title || this.$t('new_weapon');
},
name() {
return this.$t(`splatnet.weapons.${this.weapon.id}.name`, this.weapon.name);
},

View File

@@ -10,7 +10,7 @@
</div>
<div class="level-item">
<h2 class="title is-3 is-size-2-fullhd font-splatoon1">
Salmon Run
{{ $t('coop.title') }}
</h2>
</div>
</div>
@@ -23,7 +23,7 @@
<template v-if="!screenshotMode && coop && coop.reward_gear">
<div class="salmon-run-gear-text">
This month's gear
{{ $t('coop.this_months_gear') }}
</div>
<div class="salmon-run-gear-image hand" @click="gearDialogOpen = true" :title="rewardGearName">
<div class="image is-32x32">
@@ -64,7 +64,7 @@
<div v-if="!screenshotMode && upcomingSchedules.length > 0">
<div class="salmon-run-future">
<div class="is-size-6 title-squid font-splatoon1">
Soon
{{ $t('times.soon') }}
</div>
<div v-for="event in upcomingSchedules" class="event">
<div class="columns is-marginless is-gapless is-mobile">

View File

@@ -10,13 +10,13 @@
<div class="column" :class="{ 'is-5': mini }" style="display: flex; align-items: center;" v-if="schedule.weapons">
<div style="width: 100%">
<div class="has-text-centered" v-if="!mini">Supplied Weapons</div>
<div class="has-text-centered" v-if="!mini">{{ $t('coop.supplied_weapons') }}</div>
<div class="columns is-mobile is-slimmer">
<div class="column" v-for="weapon in schedule.weapons">
<div class="image is-square weapon">
<img :src="weapon.image | localSplatNetImageUrl" :title="$t(`splatnet.weapons.${weapon.id}.name`, weapon.name)" v-if="weapon" />
<img src="~@/img/salmon-run-random-weapon.png" title="Random" style="padding: 8px" v-else />
<img src="~@/img/salmon-run-random-weapon.png" :title="$t('coop.random_weapon')" style="padding: 8px" v-else />
</div>
</div>
</div>

View File

@@ -26,7 +26,7 @@
<template v-if="upcomingSchedules && upcomingSchedules[0]">
<div class="is-size-5 title-squid font-splatoon1">
Next
{{ $t('times.next') }}
</div>
<ScheduleRow

View File

@@ -2,8 +2,8 @@
<div>
<div v-if="first">
<div class="is-size-5 title-squid font-splatoon1">
<span v-if="first.start_time <= this.now">Now</span>
<span v-else>Soon!</span>
<span v-if="first.start_time <= this.now">{{ $t('times.now') }}</span>
<span v-else>{{ $t('times.soon') }}</span>
</div>
<ScheduleRow :schedule="first" :now="now"></ScheduleRow>
@@ -11,7 +11,7 @@
<template>
<div v-if="second">
<div class="is-size-5 title-squid font-splatoon1" style="margin-top: 10px">
Next
{{ $t('times.next') }}
</div>
<ScheduleRow :schedule="second" :now="now"></ScheduleRow>
@@ -19,7 +19,7 @@
<div v-if="others && others.length">
<div class="is-size-5 title-squid font-splatoon1" style="margin-top: 10px">
Future
{{ $t('times.future') }}
</div>
<ScheduleRow

View File

@@ -2,7 +2,7 @@
<Modal @close="$emit('close')">
<div class="modal-content">
<div class="splatnet-gear-dialog">
<h3 class="title is-3 has-text-centered font-splatoon1 text-shadow">Current SplatNet Gear</h3>
<h3 class="title is-3 has-text-centered font-splatoon1 text-shadow">{{ $t('splatnet_gear.title') }}</h3>
<div class="columns is-marginless is-multiline is-mobile is-centered">
<div class="column is-half-mobile is-one-third-tablet" v-for="(merchandise, index) in merchandises">
<MerchandiseBox

View File

@@ -88,10 +88,10 @@ export default {
},
title() {
if (this.state == 'upcoming')
return 'Upcoming Splatfest';
return this.$t('splatfest.upcoming');
if (this.state == 'past' && !this.screenshotMode)
return 'Recent Splatfest';
return 'Splatfest';
return this.$t('splatfest.recent');
return this.$t('splatfest.title');
},
image() {
if (this.festival)

View File

@@ -4,5 +4,8 @@ import store from '../store';
Vue.use(VuexI18n.plugin, store);
// Make sure English is always loaded
Vue.i18n.add('en', require('@/locale/en'));
Vue.i18n.set('en');
Vue.i18n.fallback('en');

6
src/js/store/actions.js Normal file
View File

@@ -0,0 +1,6 @@
export default {
loadLocale({ dispatch }, locale) {
import(/* webpackChunkName: "lang-[request]" */ `@/locale/${locale}`)
.then(translations => dispatch('addLocale', { locale, translations }));
}
}

View File

@@ -6,5 +6,6 @@ Vue.use(Vuex);
const debug = process.env.NODE_ENV !== 'production';
export default new Vuex.Store({
actions: require('./actions').default,
strict: debug,
});

39
src/locale/de.json Normal file
View File

@@ -0,0 +1,39 @@
{
"coop": {
"random_weapon": "Zufall",
"supplied_weapons": "Verfügbare Waffen",
"this_months_gear": "Ausrüstung des Monats",
"title": "Salmon Run"
},
"new_weapon": "Neue Waffe",
"regions": {
"eu": {
"name": "Europa"
},
"global": {
"name": "Alle Regionen"
},
"jp": {
"name": "Japan"
},
"na": {
"name": "Nordamerika, Australien, Neuseeland"
}
},
"splatfest": {
"battle": "Splatfestkämpfe",
"recent": "Splatfest",
"title": "Splatfest",
"upcoming": "Splatfest"
},
"splatnet_gear": {
"button": "TentaWorld",
"title": "TentaWorld"
},
"times": {
"future": "Danach",
"next": "Demnächst",
"now": "Jetzt",
"soon": "Demnächst"
}
}

39
src/locale/en.json Normal file
View File

@@ -0,0 +1,39 @@
{
"coop": {
"random_weapon": "Random",
"supplied_weapons": "Supplied Weapons",
"this_months_gear": "This month's gear",
"title": "Salmon Run"
},
"new_weapon": "New Weapon",
"regions": {
"eu": {
"name": "Europe"
},
"global": {
"name": "All regions"
},
"jp": {
"name": "Japan"
},
"na": {
"name": "North America, AU/NZ"
}
},
"splatfest": {
"battle": "Splatfest Battle",
"recent": "Recent Splatfest",
"title": "Splatfest",
"upcoming": "Upcoming Splatfest"
},
"splatnet_gear": {
"button": "SplatNet Gear",
"title": "Current SplatNet Gear"
},
"times": {
"future": "Future",
"next": "Next",
"now": "Now",
"soon": "Soon!"
}
}

39
src/locale/es-MX.json Normal file
View File

@@ -0,0 +1,39 @@
{
"coop": {
"random_weapon": "Al azar",
"supplied_weapons": "Armas disponibles",
"this_months_gear": "Objeto del mes",
"title": "Salmon Run"
},
"new_weapon": "Nueva Arma",
"regions": {
"eu": {
"name": "Europa"
},
"global": {
"name": "Todas las regiones"
},
"jp": {
"name": "Japón"
},
"na": {
"name": "América, Australia y Nueva Zelanda"
}
},
"splatfest": {
"battle": "Festival del Teñido",
"recent": "Festival",
"title": "Festival",
"upcoming": "Festival"
},
"splatnet_gear": {
"button": "Tienda SplatNet",
"title": "Tienda SplatNet"
},
"times": {
"future": "Posteriores",
"next": "Próximo",
"now": "Ahora",
"soon": "Siguiente"
}
}

39
src/locale/es.json Normal file
View File

@@ -0,0 +1,39 @@
{
"coop": {
"random_weapon": "Al azar",
"supplied_weapons": "Armas asignadas",
"this_months_gear": "Objeto del mes",
"title": "Salmon Run"
},
"new_weapon": "Arma Nueva",
"regions": {
"eu": {
"name": "Europa"
},
"global": {
"name": "Todas las regiones"
},
"jp": {
"name": "Japón"
},
"na": {
"name": "Norteamérica, Australia y Nueva Zelanda"
}
},
"splatfest": {
"battle": "Combates temáticos",
"recent": "Festival",
"title": "Festival",
"upcoming": "Festival"
},
"splatnet_gear": {
"button": "Tentatienda",
"title": "Tentatienda"
},
"times": {
"future": "Posteriores",
"next": "Próximos",
"now": "Ahora",
"soon": "Próximo"
}
}

39
src/locale/fr-CA.json Normal file
View File

@@ -0,0 +1,39 @@
{
"coop": {
"random_weapon": "Aléatoire",
"supplied_weapons": "Armes fournies",
"this_months_gear": "Pièce d'équipement du mois",
"title": "Salmon Run"
},
"new_weapon": "Nouvelle arme",
"regions": {
"eu": {
"name": "Europe"
},
"global": {
"name": "Toutes les régions"
},
"jp": {
"name": "Japon"
},
"na": {
"name": "Amérique du Nord, Australie, Nouvelle-Zélande"
}
},
"splatfest": {
"battle": "Festimatch",
"recent": "Festival",
"title": "Festival",
"upcoming": "Festival"
},
"splatnet_gear": {
"button": "Boutique SplatNet",
"title": "Boutique SplatNet"
},
"times": {
"future": "Prochains",
"next": "Suivants",
"now": "À présent",
"soon": "Bientôt!"
}
}

39
src/locale/fr.json Normal file
View File

@@ -0,0 +1,39 @@
{
"coop": {
"random_weapon": "Aléatoire",
"supplied_weapons": "Armes fournies",
"this_months_gear": "Pièce d'équipement du mois",
"title": "Salmon Run"
},
"new_weapon": "Nouvelle arme",
"regions": {
"eu": {
"name": "Europe"
},
"global": {
"name": "Toutes les régions"
},
"jp": {
"name": "Japon"
},
"na": {
"name": "Amérique du Nord, Australie, Nouvelle-Zélande"
}
},
"splatfest": {
"battle": "Festimatchs",
"recent": "Festival",
"title": "Festival",
"upcoming": "Festival"
},
"splatnet_gear": {
"button": "Céphalochic",
"title": "Céphalochic"
},
"times": {
"future": "Prochains",
"next": "Suivants",
"now": "À présent",
"soon": "Bientôt !"
}
}

39
src/locale/it.json Normal file
View File

@@ -0,0 +1,39 @@
{
"coop": {
"random_weapon": "Casuale",
"supplied_weapons": "Armi fornite",
"this_months_gear": "Equipaggiamento del mese",
"title": "Salmon Run"
},
"new_weapon": "Nuova Arma",
"regions": {
"eu": {
"name": "Europa"
},
"global": {
"name": "Tutte le regioni"
},
"jp": {
"name": "Giappone"
},
"na": {
"name": "America del Nord, Australia, Nuova Zelanda"
}
},
"splatfest": {
"battle": "Partite tematiche",
"recent": "Festival",
"title": "Festival",
"upcoming": "Festival"
},
"splatnet_gear": {
"button": "Calama-zone",
"title": "Calama-zone"
},
"times": {
"future": "Successivi",
"next": "Prossimi",
"now": "Adesso",
"soon": "Presto!"
}
}

39
src/locale/ja.json Normal file
View File

@@ -0,0 +1,39 @@
{
"coop": {
"random_weapon": "ランダム",
"supplied_weapons": "支給ブキ",
"this_months_gear": "今月のギア",
"title": "SALMON RUN"
},
"new_weapon": "新しいブキ",
"regions": {
"eu": {
"name": "欧州"
},
"global": {
"name": "すべての地域"
},
"jp": {
"name": "日本"
},
"na": {
"name": "北米、オセアニア"
}
},
"splatfest": {
"battle": "フェスマッチ",
"recent": "フェス",
"title": "フェス",
"upcoming": "フェス"
},
"splatnet_gear": {
"button": "ゲソタウン",
"title": "ゲソタウン"
},
"times": {
"future": "そのつぎ",
"next": "つぎ",
"now": "今",
"soon": "もうすぐ"
}
}

39
src/locale/nl.json Normal file
View File

@@ -0,0 +1,39 @@
{
"coop": {
"random_weapon": "Willekeurig",
"supplied_weapons": "Beschikbare wapens",
"this_months_gear": "Uitrusting van de maand",
"title": "Salmon Run"
},
"new_weapon": "Nieuw Wapen",
"regions": {
"eu": {
"name": "Europa"
},
"global": {
"name": "Alle regio's"
},
"jp": {
"name": "Japan"
},
"na": {
"name": "Noord-Amerika, Australië, Nieuw-Zeeland"
}
},
"splatfest": {
"battle": "Splatfest-gevecht",
"recent": "Splatfest",
"title": "Splatfest",
"upcoming": "Splatfest"
},
"splatnet_gear": {
"button": "Tentashop",
"title": "Tentashop"
},
"times": {
"future": "Daarna",
"next": "Volgende",
"now": "Nu",
"soon": "Binnenkort!"
}
}

39
src/locale/ru.json Normal file
View File

@@ -0,0 +1,39 @@
{
"coop": {
"random_weapon": "Случайное",
"supplied_weapons": "Табельное оружие",
"this_months_gear": "Снаряжение месяца",
"title": "Salmon Run"
},
"new_weapon": "Новое оружие",
"regions": {
"eu": {
"name": "Европа"
},
"global": {
"name": "Все регионы"
},
"jp": {
"name": "Япония"
},
"na": {
"name": "Северная Америка, Австралия, Новая Зеландия"
}
},
"splatfest": {
"battle": "Сплатфест-бой",
"recent": "Сплатфест",
"title": "Сплатфест",
"upcoming": "Сплатфест"
},
"splatnet_gear": {
"button": "«Щупозон»",
"title": "«Щупозон»"
},
"times": {
"future": "Скоро",
"next": "Далее",
"now": "Теперь",
"soon": "Далее"
}
}

View File

@@ -0,0 +1,29 @@
// This file copies translations from SplatNet language files to our own language files
require('./bootstrap');
const path = require('path');
const fs = require('fs');
const _ = require('lodash');
const { readJson, writeFormattedJson } = require('./utilities');
const { languages } = require('../js/regions');
const SplatNet = require('./splatnet');
const sourcePath = path.resolve('storage/lang');
const destinationPath = path.resolve('src/locale');
function copyTranslation(source, destination) {
for (let { region, language } of languages) {
let sourceLang = readJson(`${sourcePath}/${region}-${language}.json`);
let outputFile = `${destinationPath}/${language}.json`;
let output = readJson(outputFile);
console.log(`${language}: ${sourceLang[source]}`);
_.setWith(output, destination, sourceLang[source], Object);
writeFormattedJson(outputFile, output);
}
}
module.exports = {
copyTranslation,
};
require('make-runnable/custom')({ printOutputFrame: false });

View File

@@ -27,6 +27,7 @@ module.exports = function(env) {
output: {
path: path.resolve(__dirname, './public'),
filename: 'assets/js/[name].[hash:6].js',
chunkFilename: 'assets/js/[name].[hash:6].js',
},
devtool: (production) ? false : '#cheap-module-eval-source-map',
devServer: { overlay: true },