From 05bef9f133e4691f85a5eba5e78d46248c8bad2f Mon Sep 17 00:00:00 2001 From: wvffle Date: Sun, 27 Nov 2022 23:43:54 +0000 Subject: [PATCH] Add polish pluralization rule --- front/src/init/locale.ts | 21 ++++--- front/src/locales.json | 126 --------------------------------------- front/src/locales.ts | 121 +++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 133 deletions(-) delete mode 100644 front/src/locales.json create mode 100644 front/src/locales.ts diff --git a/front/src/init/locale.ts b/front/src/init/locale.ts index fb0485d72..7bb72d686 100644 --- a/front/src/init/locale.ts +++ b/front/src/init/locale.ts @@ -1,10 +1,11 @@ import type { InitModule } from '~/types' +import type { SupportedLanguages } from '~/locales' import { usePreferredLanguages } from '@vueuse/core' import { createI18n } from 'vue-i18n' import { nextTick } from 'vue' -import locales from '~/locales.json' +import { locales } from '~/locales' import store from '~/store' import useLogger from '~/composables/useLogger' @@ -16,10 +17,11 @@ const localeFactory = import.meta.glob('../locales/*.json') as Record, locale) => { - map[locale.code] = locale.label - return map -}, {}) + +export const SUPPORTED_LOCALES = Object.fromEntries( + Object.entries(locales) + .map(([key, value]) => [key, value.label]) +) as Record export const i18n = createI18n({ formatFallbackMessages: true, @@ -27,11 +29,16 @@ export const i18n = createI18n({ fallbackLocale: 'en_US', legacy: false, locale: 'en_US', - messages: { en_US: en } + messages: { en_US: en }, + pluralizationRules: Object.fromEntries( + Object.entries(locales) + .map(([key, value]) => [key, value.pluralizationRule]) + .filter(i => i[1]) + ) }) export const setI18nLanguage = async (locale: string) => { - if (!Object.keys(SUPPORTED_LOCALES).includes(locale)) { + if (!(locale in locales)) { throw new Error(`Unsupported locale: ${locale}`) } diff --git a/front/src/locales.json b/front/src/locales.json deleted file mode 100644 index 7f6cd8e3f..000000000 --- a/front/src/locales.json +++ /dev/null @@ -1,126 +0,0 @@ -[ - { - "code": "ar", - "label": "العربية" - }, - { - "code": "ca", - "label": "Català" - }, - { - "code": "cs", - "label": "Čeština" - }, - { - "code": "de", - "label": "Deutsch" - }, - { - "code": "en_GB", - "label": "English (UK)" - }, - { - "code": "en_US", - "label": "English (United-States)" - }, - { - "code": "eo", - "label": "Esperanto" - }, - { - "code": "es", - "label": "Español" - }, - { - "code": "eu", - "label": "Euskara" - }, - { - "code": "fr_FR", - "label": "Français" - }, - { - "code": "gl", - "label": "Galego" - }, - { - "code": "hu", - "label": "Magyar" - }, - { - "code": "it", - "label": "Italiano" - }, - { - "code": "ja_JP", - "label": "日本語" - }, - { - "code": "kab_DZ", - "label": "Taqbaylit" - }, - { - "code": "ko_KR", - "label": "한국어" - }, - { - "code": "nb_NO", - "label": "Bokmål" - }, - { - "code": "nn_NO", - "label": "Nynorsk" - }, - { - "code": "nl", - "label": "Nederlands" - }, - { - "code": "oc", - "label": "Occitan" - }, - { - "code": "pl", - "label": "Polski" - }, - { - "code": "pt_BR", - "label": "Português (Brasil)" - }, - { - "code": "pt_PT", - "label": "Português (Portugal)" - }, - { - "code": "ru", - "label": "Русский" - }, - { - "code": "sq", - "label": "Shqip" - }, - { - "code": "zh_Hans", - "label": "中文(简体)" - }, - { - "code": "zh_Hant", - "label": "中文(繁體)" - }, - { - "code": "fa_IR", - "label": "فارسی" - }, - { - "code": "ml", - "label": "മലയാളം" - }, - { - "code": "sv", - "label": "Svenska" - }, - { - "code": "el", - "label": "Ελληνικά" - } -] diff --git a/front/src/locales.ts b/front/src/locales.ts new file mode 100644 index 000000000..490a2c530 --- /dev/null +++ b/front/src/locales.ts @@ -0,0 +1,121 @@ +import type { VueI18nOptions } from 'vue-i18n' + +export type SupportedLanguages = 'ar' | 'ca' | 'cs' | 'de' | 'en_GB' | 'en_US' | 'eo' | 'es' | 'eu' | 'fr_FR' + | 'gl' | 'hu' | 'it' | 'ja_JP' | 'kab_DZ' | 'ko_KR' | 'nb_NO' | 'nl' | 'oc' | 'pl' | 'pt_BR' | 'pt_PT' + | 'ru' | 'sq' | 'zh_Hans' | 'zh_Hant' | 'fa_IR' | 'ml' | 'sv' | 'el' | 'nn_NO' + +export interface Locale { + label: string + pluralizationRule?: Exclude[string] +} + +export const locales: Record = { + ar: { + label: 'العربية' + }, + ca: { + label: 'Català' + }, + cs: { + label: 'Čeština' + }, + de: { + label: 'Deutsch' + }, + en_GB: { + label: 'English (UK)' + }, + en_US: { + label: 'English (United-States)' + }, + eo: { + label: 'Esperanto' + }, + es: { + label: 'Español' + }, + eu: { + label: 'Euskara' + }, + fr_FR: { + label: 'Français' + }, + gl: { + label: 'Galego' + }, + hu: { + label: 'Magyar' + }, + it: { + label: 'Italiano' + }, + ja_JP: { + label: '日本語' + }, + kab_DZ: { + label: 'Taqbaylit' + }, + ko_KR: { + label: '한국어' + }, + nb_NO: { + label: 'Bokmål' + }, + nn_NO: { + label: 'Nynorsk' + }, + nl: { + label: 'Nederlands' + }, + oc: { + label: 'Occitan' + }, + pl: { + label: 'Polski', + pluralizationRule: (n, choices) => { + // 0 rowerow | 1 rower | 2-4 rowery | 5-21 rowerow + // 1 rower | 2-4 rowery | 5-21 rowerow + + const isFew = (n % 10 >= 2 && n % 10 <= 4) && (n % 100 < 10 || n % 100 >= 20) + + if (choices === 3) { + if (n === 0) return 2 + if (n === 1) return 0 + return isFew ? 1 : 2 + } + + if (n === 0 || n === 1) return n + return isFew ? 2 : 3 + } + }, + pt_BR: { + label: 'Português (Brasil)' + }, + pt_PT: { + label: 'Português (Portugal)' + }, + ru: { + label: 'Русский' + }, + sq: { + label: 'Shqip' + }, + zh_Hans: { + label: '中文(简体)' + }, + zh_Hant: { + label: '中文(繁體)' + }, + fa_IR: { + label: 'فارسی' + }, + ml: { + label: 'മലയാളം' + }, + sv: { + label: 'Svenska' + }, + el: { + label: 'Ελληνικά' + } +}