diff --git a/changes/changelog.d/670.enhancement b/changes/changelog.d/670.enhancement new file mode 100644 index 0000000000000000000000000000000000000000..8da3f97f8e288cf0ac9cf263a6299ec9b33eaca2 --- /dev/null +++ b/changes/changelog.d/670.enhancement @@ -0,0 +1 @@ +Use proper locale for date-related/duration strings (#670) diff --git a/front/src/App.vue b/front/src/App.vue index 2ce3ba3ed74a17bfa97b903ed383e8ebeca70da1..02383e6cfbf41e17e45c5382f57d75e764eadc7f 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -57,11 +57,10 @@ import _ from '@/lodash' import {mapState} from 'vuex' import { WebSocketBridge } from 'django-channels' import GlobalEvents from '@/components/utils/global-events' - import Sidebar from '@/components/Sidebar' import AppFooter from '@/components/Footer' import ServiceMessages from '@/components/ServiceMessages' - +import moment from 'moment' import locales from './locales' import PlaylistModal from '@/components/playlists/PlaylistModal' import ShortcutsModal from '@/components/ShortcutsModal' @@ -153,14 +152,7 @@ export default { } else { return } - import(`./translations/${candidate}.json`).then((response) =>{ - Vue.$translations[candidate] = response.default[candidate] - }).finally(() => { - // set current language twice, otherwise we seem to have a cache somewhere - // and rendering does not happen - self.$language.current = 'noop' - self.$language.current = candidate - }) + this.$store.commit('ui/currentLanguage', candidate) }, disconnect () { if (!this.bridge) { @@ -191,7 +183,7 @@ export default { bridge.socket.addEventListener('open', function () { console.log('Connected to WebSocket') }) - } + }, }, computed: { ...mapState({ @@ -235,8 +227,35 @@ export default { this.openWebsocket() } }, - '$language.current' (newValue) { - this.$store.commit('ui/currentLanguage', newValue) + '$store.state.ui.currentLanguage': { + immediate: true, + handler(newValue) { + let self = this + import(`./translations/${newValue}.json`).then((response) =>{ + Vue.$translations[newValue] = response.default[newValue] + }).finally(() => { + // set current language twice, otherwise we seem to have a cache somewhere + // and rendering does not happen + self.$language.current = 'noop' + self.$language.current = newValue + }) + if (newValue === 'en_US') { + return self.$store.commit('ui/momentLocale', 'en') + } + let momentLocale = newValue.replace('_', '-').toLowerCase() + import(`moment/locale/${momentLocale}.js`).then(() => { + self.$store.commit('ui/momentLocale', momentLocale) + }).catch(() => { + console.log('No momentjs locale available for', momentLocale) + let shortLocale = momentLocale.split('-')[0] + import(`moment/locale/${shortLocale}.js`).then(() => { + self.$store.commit('ui/momentLocale', shortLocale) + }).catch(() => { + console.log('No momentjs locale available for', shortLocale) + }) + }) + console.log(moment.locales()) + } } } } diff --git a/front/src/components/Footer.vue b/front/src/components/Footer.vue index f62bc548b98a0b715b3534c5533bac3d2b81e309..2767167e2fc30cf097047e61b4915df593884b06 100644 --- a/front/src/components/Footer.vue +++ b/front/src/components/Footer.vue @@ -20,7 +20,7 @@ <div class="ui form"> <div class="ui field"> <label><translate>Change language</translate></label> - <select class="ui dropdown" :value="$language.current" @change="updateLanguage($event.target.value)"> + <select class="ui dropdown" :value="$language.current" @change="$store.commit('ui/currentLanguage', $event.target.value)"> <option v-for="(language, key) in $language.available" :key="key" :value="key">{{ language }}</option> </select> </div> @@ -76,14 +76,6 @@ export default { if (confirm) { this.$store.commit("instance/instanceUrl", null) } - }, - updateLanguage(value) { - let self = this - import(`../translations/${value}.json`).then((response) =>{ - Vue.$translations[value] = response.default[value] - }).finally(() => { - self.$language.current = value - }) } }, computed: { diff --git a/front/src/components/common/HumanDate.vue b/front/src/components/common/HumanDate.vue index 9ff8e48bdce8a8d366d7f8394571a7c00a8ec6f8..eed245ea6ce1538d9b0afcd9bcd6297e5695f3a7 100644 --- a/front/src/components/common/HumanDate.vue +++ b/front/src/components/common/HumanDate.vue @@ -1,5 +1,5 @@ <template> - <time :datetime="date" :title="date | moment">{{ realDate | ago }}</time> + <time :datetime="date" :title="date | moment">{{ realDate | ago($store.state.ui.momentLocale) }}</time> </template> <script> import {mapState} from 'vuex' diff --git a/front/src/filters.js b/front/src/filters.js index 97dd2d5ee3abf93929ca67df2f87dabe56478f1d..145a982531f1e3a9547db47fc6b3d97991affc59 100644 --- a/front/src/filters.js +++ b/front/src/filters.js @@ -13,8 +13,10 @@ export function truncate (str, max, ellipsis) { Vue.filter('truncate', truncate) -export function ago (date) { +export function ago (date, locale) { + locale = locale || 'en' const m = moment(date) + m.locale(locale) return m.fromNow() } diff --git a/front/src/store/index.js b/front/src/store/index.js index 1ef33f2b04872f7b4887c4320af4e2ad5f8be129..2454dd20a1497333d5a7b3416859952fdd323d32 100644 --- a/front/src/store/index.js +++ b/front/src/store/index.js @@ -38,7 +38,7 @@ export default new Vuex.Store({ }), createPersistedState({ key: 'ui', - paths: ['ui.currentLanguage'] + paths: ['ui.currentLanguage', 'ui.momentLocale'] }), createPersistedState({ key: 'radios', diff --git a/front/src/store/ui.js b/front/src/store/ui.js index b366f233d89ea31cda7fb2eb0d2474a28d3acc09..fa4624c700c73b0581d9f2d881e70f81096a2b57 100644 --- a/front/src/store/ui.js +++ b/front/src/store/ui.js @@ -1,9 +1,11 @@ import axios from 'axios' +import moment from 'moment' export default { namespaced: true, state: { currentLanguage: 'en_US', + momentLocale: 'en', lastDate: new Date(), maxMessages: 100, messageDisplayDuration: 10000, @@ -26,6 +28,10 @@ export default { currentLanguage: (state, value) => { state.currentLanguage = value }, + momentLocale: (state, value) => { + state.momentLocale = value + moment.locale(value) + }, computeLastDate: (state) => { state.lastDate = new Date() },