Skip to content

Instantly share code, notes, and snippets.

@ElpixZero
Created August 14, 2021 12:05
Show Gist options
  • Save ElpixZero/1808d7904e8fe51a10fd17eda0822b1a to your computer and use it in GitHub Desktop.
Save ElpixZero/1808d7904e8fe51a10fd17eda0822b1a to your computer and use it in GitHub Desktop.
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import { LOCALE_NAME_RU, LOCALE_NAME_EN } from '@/i18n/utils';
Vue.use(VueI18n);
function loadLocaleMessages() {
const locales = require.context(
'./locales',
true,
/[A-Za-z0-9-_,\s]+\.json$/i
);
const messages = {};
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 dateTimeFormats = {
[LOCALE_NAME_EN]: {
short: {
year: 'numeric',
month: 'short',
day: 'numeric',
},
long: {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
},
officeTask: {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
},
lesson: {
day: 'numeric',
month: 'long',
weekday: 'long',
},
bitrhDateFormatMonthAndDay: {
month: 'long',
day: 'numeric',
timeZone: 'UTC',
},
birthDate: {
year: 'numeric',
month: 'numeric',
day: 'numeric',
timeZone: 'UTC',
},
news: {
year: 'numeric',
month: 'numeric',
day: 'numeric',
timeZone: 'UTC',
},
topNotification: {
year: 'numeric',
month: 'numeric',
day: 'numeric',
},
applications: {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
},
passport: {
day: 'numeric',
month: 'numeric',
year: 'numeric',
},
},
[LOCALE_NAME_RU]: {
short: {
year: 'numeric',
month: 'short',
day: 'numeric',
},
long: {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
},
officeTask: {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
},
lesson: {
day: 'numeric',
month: 'long',
weekday: 'long',
},
bitrhDateFormatMonthAndDay: {
month: 'long',
day: 'numeric',
timeZone: 'UTC',
},
birthDate: {
year: 'numeric',
month: 'numeric',
day: 'numeric',
timeZone: 'UTC',
},
news: {
year: 'numeric',
month: 'numeric',
day: 'numeric',
timeZone: 'UTC',
},
topNotification: {
day: 'numeric',
month: 'numeric',
year: 'numeric',
},
applications: {
day: 'numeric',
month: 'numeric',
year: 'numeric',
hour: 'numeric',
minute: 'numeric',
},
passport: {
day: 'numeric',
month: 'numeric',
year: 'numeric',
},
},
};
export default new VueI18n({
dateTimeFormats,
silentFallbackWarn: true,
locale: 'ru',
fallbackLocale: 'ru',
messages: loadLocaleMessages(),
pluralizationRules: {
en: function (choice, choicesLength) {
if (choice === 0) {
return 0;
}
if (choicesLength === 4) {
if (choice > 3) return 3;
return choice - 1;
}
if (choicesLength === 2) {
if (choice > 1) return 1;
return 0;
}
if (choice > 1) {
return 2;
}
return choice;
},
/**
* @param choice {number} индекс выбора, переданный в $tc: `$tc('path.to.rule', choiceIndex)`
* @param choicesLength {number} общее количество доступных вариантов
* @returns финальный индекс для выбора соответственного варианта слова
*/
ru: function (choice, choicesLength) {
// this === VueI18n экземпляра, так что свойство locale также существует здесь
if (choice === 0) {
return 0;
}
const teen = choice > 10 && choice < 20;
const endsWithOne = choice % 10 === 1;
if (choicesLength < 4) {
return !teen && endsWithOne ? 1 : 2;
}
if (!teen && endsWithOne) {
return 1;
}
if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
return 2;
}
return choicesLength < 4 ? 2 : 3;
},
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment