feat: add i18n support and translations
This commit is contained in:
parent
ec9a1ef35e
commit
f62b8db662
@ -1,18 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="game-controls__container">
|
<div class="game-controls__container">
|
||||||
<Button class="game-controls__control" :border="!disabled.collect" :disabled="disabled.collect" @click="collect">Collect Quotes</Button>
|
<Button class="game-controls__control" :border="!disabled.collect" :disabled="disabled.collect" @click="collect">{{ $t('collect-quotes') }}</Button>
|
||||||
<Button class="game-controls__control" :border="!disabled.start" :disabled="disabled.start" @click="start">Start</Button>
|
<Button class="game-controls__control" :border="!disabled.start" :disabled="disabled.start" @click="start">{{ $t('start') }}</Button>
|
||||||
<Button class="game-controls__control" :border="!disabled.cont" :disabled="disabled.cont" @click="cont">Continue</Button>
|
<Button class="game-controls__control" :border="!disabled.cont" :disabled="disabled.cont" @click="cont">{{ $t('continue') }}</Button>
|
||||||
<Button class="game-controls__control" :border="!disabled.idle" :disabled="disabled.idle" @click="idle">Idle</Button>
|
<Button class="game-controls__control" :border="!disabled.idle" :disabled="disabled.idle" @click="idle">{{ $t('idle') }}</Button>
|
||||||
<Button class="game-controls__control" :border="!disabled.finish" :disabled="disabled.finish" @click="finish">Finish</Button>
|
<Button class="game-controls__control" :border="!disabled.finish" :disabled="disabled.finish" @click="finish">{{ $t('finish') }}</Button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import useEngine from '@/composables/useEngine'
|
import useEngine from '@/composables/useEngine'
|
||||||
|
import useI18n from '@/composables/useI18n'
|
||||||
import { useGameinfoStore } from "@/stores/GameinfoStore"
|
import { useGameinfoStore } from "@/stores/GameinfoStore"
|
||||||
|
|
||||||
|
const { $t } = useI18n({
|
||||||
|
'collect-quotes': { en: 'Collect Quotes', de: 'Aussagen sammeln' },
|
||||||
|
'start': { en: 'Start', de: 'Start' },
|
||||||
|
'continue': { en: 'Continue', de: 'Weiter' },
|
||||||
|
'idle': { en: 'Lobby', de: 'Lobby' },
|
||||||
|
'finish': { en: 'Highscores', de: 'Highscores' },
|
||||||
|
})
|
||||||
|
|
||||||
const game = useGameinfoStore()
|
const game = useGameinfoStore()
|
||||||
const engine = useEngine()
|
const engine = useEngine()
|
||||||
const disabled = computed(() => {
|
const disabled = computed(() => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="lobby__container">
|
<div class="lobby__container">
|
||||||
<div class="lobby__message">
|
<div class="lobby__message">
|
||||||
waiting for gamemaster to start the game ...
|
{{ $t('waiting-for-gamemaster') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="lobby__players-list">
|
<div class="lobby__players-list">
|
||||||
<PlayerList :players="players" :hide-scores="true" />
|
<PlayerList :players="players" :hide-scores="true" />
|
||||||
@ -10,7 +10,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import useI18n from '@/composables/useI18n'
|
||||||
import { usePlayersStore } from '@/stores/PlayersStore'
|
import { usePlayersStore } from '@/stores/PlayersStore'
|
||||||
|
|
||||||
|
const { $t } = useI18n({
|
||||||
|
'waiting-for-gamemaster': { en: 'waiting for gamemaster to start the game ...', de: 'warten, bis der/die Gamemaster:in das Spiel startet ...'},
|
||||||
|
})
|
||||||
|
|
||||||
const players = usePlayersStore().players
|
const players = usePlayersStore().players
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<form class="login-box__container-inner" @submit.prevent="login">
|
<form class="login-box__container-inner" @submit.prevent="login">
|
||||||
<input v-model="authCode" v-focus class="login-box__authinput" type="text" size="6" maxlength="6"
|
<input v-model="authCode" v-focus class="login-box__authinput" type="text" size="6" maxlength="6"
|
||||||
placeholder="Code" />
|
placeholder="Code" />
|
||||||
<Button type="submit">Go!</Button>
|
<Button type="submit">{{ $t('login') }}</Button>
|
||||||
<div v-if="errorMessage" class="login-box__error">{{ errorMessage }}</div>
|
<div v-if="errorMessage" class="login-box__error">{{ errorMessage }}</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -13,6 +13,11 @@
|
|||||||
import { useRouter } from '#app'
|
import { useRouter } from '#app'
|
||||||
import { ref, Ref } from 'vue'
|
import { ref, Ref } from 'vue'
|
||||||
import useAuth from '@/composables/useAuth';
|
import useAuth from '@/composables/useAuth';
|
||||||
|
import useI18n from '@/composables/useI18n';
|
||||||
|
|
||||||
|
const { $t } = useI18n({
|
||||||
|
'login': { en: 'log in', de: 'login'},
|
||||||
|
})
|
||||||
|
|
||||||
const vFocus = { mounted: (el: HTMLElement) => el.focus() }
|
const vFocus = { mounted: (el: HTMLElement) => el.focus() }
|
||||||
|
|
||||||
@ -36,7 +41,6 @@ const login = (): void => {
|
|||||||
.login-box {
|
.login-box {
|
||||||
&__container-outer {
|
&__container-outer {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 240px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__container-inner {
|
&__container-inner {
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="topbar__separator" />
|
<div class="topbar__separator" />
|
||||||
<div class="topbar__logout-button-container">
|
<div class="topbar__logout-button-container">
|
||||||
<Button class="topbar__logout-button" :border="false" @click="actionLogout">Logout</Button>
|
<Button class="topbar__logout-button" :border="false" @click="actionLogout">{{ $t('logout') }}</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -25,9 +25,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRouter } from '#app'
|
import { useRouter } from '#app'
|
||||||
import useAuth from '@/composables/useAuth';
|
import useAuth from '@/composables/useAuth';
|
||||||
|
import useI18n from '@/composables/useI18n';
|
||||||
import { useUserinfoStore } from "@/stores/UserinfoStore"
|
import { useUserinfoStore } from "@/stores/UserinfoStore"
|
||||||
import { useGameinfoStore } from "@/stores/GameinfoStore"
|
import { useGameinfoStore } from "@/stores/GameinfoStore"
|
||||||
|
|
||||||
|
const { $t, setLang } = useI18n({
|
||||||
|
'logout': { en: 'Logout', de: 'abmelden' },
|
||||||
|
})
|
||||||
|
|
||||||
const user = useUserinfoStore()
|
const user = useUserinfoStore()
|
||||||
const game = useGameinfoStore()
|
const game = useGameinfoStore()
|
||||||
|
|
||||||
|
30
client/src/composables/useI18n.ts
Normal file
30
client/src/composables/useI18n.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
export type i18nMap = {
|
||||||
|
[key: string]: {
|
||||||
|
en: string,
|
||||||
|
de: string,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
let lang = 'de'
|
||||||
|
const defaultLang = navigator.language ? navigator.language.substr(0, 2) : 'en'
|
||||||
|
|
||||||
|
export interface useI18n {
|
||||||
|
setLang(lang: string): void
|
||||||
|
$t(key: string): string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (map: i18nMap): useI18n => {
|
||||||
|
return {
|
||||||
|
setLang: (_lang: string): void => {
|
||||||
|
lang = _lang
|
||||||
|
},
|
||||||
|
$t: (key: string): string => {
|
||||||
|
const t = map[key]
|
||||||
|
if (!t) {
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
return t[lang] || t[defaultLang] || key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="page-index__separator" />
|
<div class="page-index__separator" />
|
||||||
<div class="page-index__create-team">
|
<div class="page-index__create-team">
|
||||||
<Button disabled>Create Team</Button>
|
<Button disabled>{{ $t('create-team') }}</Button>
|
||||||
</div>
|
</div>
|
||||||
<div class="page-index__space" />
|
<div class="page-index__space" />
|
||||||
</div>
|
</div>
|
||||||
@ -21,6 +21,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRuntimeConfig, navigateTo } from '#app'
|
import { useRuntimeConfig, navigateTo } from '#app'
|
||||||
import useAuth from '@/composables/useAuth'
|
import useAuth from '@/composables/useAuth'
|
||||||
|
import useI18n from '@/composables/useI18n'
|
||||||
|
|
||||||
|
const { $t } = useI18n({
|
||||||
|
'create-team': { en: 'Create Team', de: 'Team erstellen' },
|
||||||
|
})
|
||||||
|
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
|
|
||||||
@ -51,7 +56,7 @@ body {
|
|||||||
|
|
||||||
&__login,
|
&__login,
|
||||||
&__create-team {
|
&__create-team {
|
||||||
width: 240px;
|
width: 320px;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<div class="page-play__container">
|
<div class="page-play__container">
|
||||||
<TopBar />
|
<TopBar />
|
||||||
<AlertBox v-if="!isConnected" mode="alert">
|
<AlertBox v-if="!isConnected" mode="alert">
|
||||||
connection to server broken
|
{{ $t('connection-broken') }}
|
||||||
<div v-if="retry >= 0">retrying {{ '...'.slice(0, retry % 4) }}</div>
|
<div v-if="retry >= 0">{{ $t('retrying') }} {{ '...'.slice(0, retry % 4) }}</div>
|
||||||
</AlertBox>
|
</AlertBox>
|
||||||
<div class="page-play__playfield-container">
|
<div class="page-play__playfield-container">
|
||||||
<div class="page-play__playfield-content">
|
<div class="page-play__playfield-content">
|
||||||
@ -24,6 +24,13 @@ import { computed, onMounted, onBeforeUnmount } from 'vue';
|
|||||||
import useAuth from '@/composables/useAuth';
|
import useAuth from '@/composables/useAuth';
|
||||||
import useEngine from '@/composables/useEngine';
|
import useEngine from '@/composables/useEngine';
|
||||||
import { useGameinfoStore } from "@/stores/GameinfoStore"
|
import { useGameinfoStore } from "@/stores/GameinfoStore"
|
||||||
|
import useI18n from '@/composables/useI18n'
|
||||||
|
|
||||||
|
const { $t } = useI18n({
|
||||||
|
'connection-broken': { en: 'connection to server broken.', de: 'Verbindung zum Server ist unterbrochen.' },
|
||||||
|
'retrying': { en: 'retrying', de: 'verbinde erneut'},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// ensure user is authenticated
|
// ensure user is authenticated
|
||||||
const { authenticateAndLoadUserInfo } = useAuth()
|
const { authenticateAndLoadUserInfo } = useAuth()
|
||||||
|
Loading…
Reference in New Issue
Block a user