French translation + automatic select best matching locale

This commit is contained in:
Lucas Verney 2018-06-28 11:15:48 +02:00
parent 56b38eba06
commit 57bf538325
4 changed files with 84 additions and 8 deletions

View File

@ -1,17 +1,17 @@
<template> <template>
<v-container fluid> <v-container fluid>
<v-layout row> <v-layout row>
<v-flex xs12> <v-flex xs6 offset-xs3>
<p>This app lets you track and share issues with bike lanes.</p> <p>{{ $t('about.summary') }}</p>
<h2 class="body-2">The available reports so far are:</h2> <h2 class="body-2">{{ $t('about.availableReportsTitle') }}</h2>
<ul class="ml-3"> <ul class="ml-3">
<li><strong>GCUM</strong>: A car poorly parked on a bike lane.</li> <li><strong>{{ $t('reportLabels.gcum') }}</strong>{{ $t('misc.spaceBeforeDoublePunctuations') }}: {{ $t('about.gcumDescription') }}</li>
<li><strong>Interrupt</strong>: An interruption of the bike lane (works, unexpected end of the bike lane, etc.).</li> <li><strong>{{ $t('reportLabels.interrupt') }}</strong>{{ $t('misc.spaceBeforeDoublePunctuations') }}: {{ $t('about.interruptDescription') }}</li>
<li><strong>Pothole</strong>: A pothole in the ground.</li> <li><strong>{{ $t('reportLabels.pothole') }}</strong>{{ $t('misc.spaceBeforeDoublePunctuations') }}: {{ $t('about.potholeDescription') }}</li>
</ul> </ul>
<p class="mt-3">It is released under an <a href="">MIT license</a>. The map background is using tiles from <a href="https://www.opencyclemap.org/docs/">OpenCycleMap</a>, thanks to <a href="">OpenStreetMap contributors</a> and <a href="">Leaflet</a>.</p> <p class="mt-3" v-html="$t('about.license')"></p>
</v-flex> </v-flex>
</v-layout> </v-layout>

View File

@ -1,5 +1,13 @@
// Keys should be sorted alphabetically // Keys should be sorted alphabetically
export default { export default {
about: {
availableReportsTitle: 'The available reports so far are:',
gcumDescription: 'A car poorly parked on a bike lane.',
interruptDescription: 'An interruption of the bike lane (works, unexpected end of the bike lane, etc.).',
license: 'It is released under an <a href="https://opensource.org/licenses/MIT">MIT license</a>. The map background is using tiles from <a href="https://www.opencyclemap.org/docs/">OpenCycleMap</a>, thanks to <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a> and <a href="http://leafletjs.com/">Leaflet</a>.',
potholeDescription: 'A pothole in the ground.',
summary: 'This app lets you track and share issues with bike lanes.',
},
geolocation: { geolocation: {
fetching: 'Fetching current position…', fetching: 'Fetching current position…',
unavailable: 'Sorry, geolocation is not available in your browser.', unavailable: 'Sorry, geolocation is not available in your browser.',
@ -7,6 +15,9 @@ export default {
menu: { menu: {
About: 'About', About: 'About',
}, },
misc: {
spaceBeforeDoublePunctuations: '',
},
reportLabels: { reportLabels: {
gcum: 'GCUM', gcum: 'GCUM',
interrupt: 'Interruption', interrupt: 'Interruption',

26
src/i18n/fr.js Normal file
View File

@ -0,0 +1,26 @@
// Keys should be sorted alphabetically
export default {
about: {
availableReportsTitle: "Les signalements disponibles pour l'instant sont :",
gcumDescription: 'Une voiture (mal) garée sur la piste cyclable.',
interruptDescription: "Une interruption d'itinéraire cyclable (travaux, arrêt inattendu d'une piste cyclable, etc)",
license: "Le code source est sous <a href='https://opensource.org/licenses/MIT'>licence MIT license</a>. Les tuiles de fond de carte proviennent de chez <a href='https://www.opencyclemap.org/docs/'>OpenCycleMap</a>, grace aux <a href='https://www.openstreetmap.org/copyright'>contributeurs OpenStreetMap</a> et à <a href='http://leafletjs.com/'>Leaflet</a>.",
potholeDescription: 'Un nid de poule dans la route.',
summary: 'Cette application vous permet de signaler et de partager des problèmes avec les itinéraires cyclables.',
},
geolocation: {
fetching: 'En attente de votre position…',
unavailable: "Désolé, la géolocalisation n'est pas disponible dans votre navigateur.",
},
menu: {
About: 'À-propos',
},
misc: {
spaceBeforeDoublePunctuations: ' ',
},
reportLabels: {
gcum: 'GCUM',
interrupt: 'Interruption',
pothole: 'Nid de poule',
},
};

View File

@ -2,14 +2,53 @@ import Vue from 'vue';
import VueI18n from 'vue-i18n'; import VueI18n from 'vue-i18n';
import en from './en'; import en from './en';
import fr from './fr';
Vue.use(VueI18n); Vue.use(VueI18n);
export function getBrowserLocales() {
let langs = [];
if (navigator.languages) {
// Chrome does not currently set navigator.language correctly
// https://code.google.com/p/chromium/issues/detail?id=101138
// but it does set the first element of navigator.languages correctly
langs = navigator.languages;
} else if (navigator.userLanguage) {
// IE only
langs = [navigator.userLanguage];
} else {
// as of this writing the latest version of firefox + safari set this correctly
langs = [navigator.language];
}
// Some browsers does not return uppercase for second part
const locales = langs.map((lang) => {
const locale = lang.split('-');
return locale[1] ? `${locale[0]}-${locale[1].toUpperCase()}` : lang;
});
return locales;
}
const messages = { const messages = {
en, en,
fr,
}; };
const locales = getBrowserLocales();
let locale = 'en'; // Safe default
// Get best matching locale
for (let i = 0; i < locales.length; i += 1) {
if (messages[locales[i]]) {
locale = locales[i];
break; // Break at first matching locale
}
}
export default new VueI18n({ export default new VueI18n({
locale: 'en', locale,
messages, messages,
}); });