🌐 (app) init 18n in en and french

This commit is contained in:
2020-07-18 23:32:47 +02:00
parent 4cae3c7a49
commit 62749a3bf7
14 changed files with 311 additions and 40 deletions

View File

@@ -1,7 +1,7 @@
<template>
<div class="chilled-music">
<transition name="fade">
<img v-show="!ready" src="@/assets/loader.svg" alt="loading" />
<img v-show="!ready" src="@/assets/loader.svg" :alt="$t('loading')" />
</transition>
<section v-show="false">
<div
@@ -114,3 +114,14 @@ img {
animation: rotating 4s linear infinite;
}
</style>
<i18n>
{
"en": {
"loading": "loading..."
},
"fr": {
"loading": "chargement..."
}
}
</i18n>

View File

@@ -1,23 +1,30 @@
<template>
<div class="interval-input">
<transition name="fade" mode="out-in">
<button v-if="editable" class="spacer" @click="minus">
<img key="minus" src="@/assets/minus.svg" alt="minus" />
</button>
<div v-else class="spacer"></div>
</transition>
<h3>{{ label }}</h3>
<transition name="fade" mode="out-in">
<button v-if="editable" class="spacer" @click="plus">
<img key="plus" src="@/assets/plus.svg" alt="plus" />
</button>
<div v-else class="spacer"></div>
</transition>
<div class="button-container minus">
<transition name="fade" mode="out-in">
<button v-if="editable" class="spacer" @click="minus">
<img key="minus" src="@/assets/minus.svg" alt="minus" />
</button>
<div v-else class="spacer"></div>
</transition>
</div>
<h3 v-if="isMinuteSession">
{{ $tc('minuteSession', interval, { interval }) }}
</h3>
<h3 v-else>{{ $t('secondSession') }}</h3>
<div class="button-container plus">
<transition name="fade" mode="out-in">
<button v-if="editable" class="spacer" @click="plus">
<img key="plus" src="@/assets/plus.svg" alt="plus" />
</button>
<div v-else class="spacer"></div>
</transition>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, computed } from '@vue/composition-api'
import { defineComponent } from '@vue/composition-api'
import { useInterval } from '../hooks/useInterval'
export default defineComponent({
@@ -26,20 +33,13 @@ export default defineComponent({
editable: { type: Boolean, required: true }
},
setup() {
const { interval, minInterval, minus, plus } = useInterval()
const label = computed(() => {
if (interval.value === minInterval) {
return '30 second session'
}
return `${interval.value} minute session`
})
const { interval, isMinuteSession, minus, plus } = useInterval()
return {
interval,
isMinuteSession,
minus,
plus,
label
plus
}
}
})
@@ -53,12 +53,25 @@ $button-size: 50px;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
h3 {
flex: 1;
flex: 2;
line-height: 2rem;
}
.button-container {
flex: 1;
display: flex;
&.minus {
justify-content: flex-end;
}
&.plus {
justify-content: flex-start;
}
}
button {
display: flex;
justify-content: center;
@@ -73,3 +86,16 @@ $button-size: 50px;
}
}
</style>
<i18n>
{
"en": {
"minuteSession": "{interval} minute session",
"secondSession": "30 second session"
},
"fr": {
"minuteSession": "session de {interval} minute | session de {interval} minutes",
"secondSession": "session de 30 secondes"
}
}
</i18n>

View File

@@ -2,9 +2,11 @@
<div class="zone-music plume" v-if="isMusicAvailable">
<div class="pm-field">
<label for="use-music" data-pm-holder>
<span class="focus" :class="{ selected: !hasMusic, disabled: hasMusic }"
>focus</span
>
<span
class="focus"
:class="{ selected: !hasMusic, disabled: hasMusic }"
v-t="'focus'"
></span>
<input
type="checkbox"
name="use-music"
@@ -17,7 +19,7 @@
class="chill"
:class="{ selected: hasMusic, disabled: !hasMusic }"
>
chill
<span v-t="'chill'"></span>
<ChilledMusic
class="chilled-music"
v-if="hasMusic"
@@ -92,6 +94,10 @@ label[data-pm-holder] {
align-items: center;
justify-content: flex-start;
span {
text-align: left;
}
.chilled-music {
margin-left: 0.5rem;
}
@@ -105,3 +111,16 @@ label[data-pm-holder] {
color: desaturate($color, 70%);
}
</style>
<i18n>
{
"en": {
"focus": "focus",
"chill": "chill"
},
"fr": {
"focus": "concentré",
"chill": "détendu"
}
}
</i18n>

View File

@@ -1,6 +1,7 @@
import { useGetters, useActions } from 'vuex-composition-helpers'
import { GetterTree } from 'vuex'
import { State, RootActions } from '@/store'
import { computed } from '@vue/composition-api'
const MIN_INTERVAL = 0.5
const MAX_INTERVAL = 60
@@ -19,8 +20,11 @@ export const useInterval = () => {
setInterval(Math.min(Math.floor(interval.value + 1), MAX_INTERVAL))
}
const isMinuteSession = computed(() => interval.value >= 1)
return {
interval,
isMinuteSession,
minInterval: MIN_INTERVAL,
minus,
plus

View File

@@ -28,8 +28,8 @@ export const useTimer = () => {
const session = computed(() => formatSeconds(sessionSeconds.value))
const intervalSeconds = computed(() => interval.value * 60)
let stopwatchId: number | null = null
let stopWatchSessionId: number | null = null
let stopwatchId: NodeJS.Timeout | null = null
let stopWatchSessionId: NodeJS.Timeout | null = null
watch(interval, () => {
sessionSeconds.value = interval.value * 60

32
src/i18n.ts Normal file
View File

@@ -0,0 +1,32 @@
import Vue from 'vue'
import VueI18n, { LocaleMessages } from 'vue-i18n'
Vue.use(VueI18n)
function loadLocaleMessages(): LocaleMessages {
const locales = require.context(
'./locales',
true,
/[A-Za-z0-9-_,\s]+\.json$/i
)
const messages: LocaleMessages = {}
locales.keys().forEach((key) => {
const matched = key.match(/([A-Za-z0-9-_]+)\./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key)
}
})
return messages
}
const lang = navigator.language
?.split('-')
.shift()
?.toLowerCase()
export default new VueI18n({
locale: lang || 'en',
fallbackLocale: 'en',
messages: loadLocaleMessages()
})

View File

@@ -4,6 +4,7 @@ import './registerServiceWorker'
import router from './router'
import store from './store'
import VueCompositionAPI from '@vue/composition-api'
import i18n from './i18n'
Vue.use(VueCompositionAPI)
@@ -12,5 +13,6 @@ Vue.config.productionTip = false
new Vue({
router,
store,
i18n,
render: (h) => h(App)
}).$mount('#app')

View File

@@ -12,7 +12,7 @@ const routes: RouteConfig[] = [
},
{
path: '/play',
name: 'Home',
name: 'HomePlay',
component: Home,
props: { play: true }
}

View File

@@ -165,3 +165,20 @@ footer {
font-size: 1rem;
}
</style>
<i18n>
{
"en": {
"madeBy": "Made by",
"juju": "juju",
"chillWith": "chill with",
"chilled cow": "chilled cow"
},
"fr": {
"madeBy": "Fait par",
"juju": "juju",
"chillWith": "Détendez-vous avec",
"chilled cow": "chilled cow"
}
}
</i18n>