Add support for Russian plurals

String given as "0 items | items ending with 1 (except 11) | items ending 2-4 (except 12-14) | other" or without the 0 option as "items ending with 1 (except 11) | items ending 2-4 (except 12-14) | other".
This commit is contained in:
N-Pex 2024-12-10 15:49:23 +01:00
parent d7a28f511b
commit cae78e860f
2 changed files with 41 additions and 11 deletions

View file

@ -74,12 +74,12 @@
"sending_progress": "Отправка...",
"close": "Закрыть",
"files": "Файлы",
"files_sent": "Отправлен 1 файл! | {count} отправленных файлов!",
"files_sent": "Отправлен {count} файл! | {count} отправленных файлов! | {count} отправленных файлов!",
"any_file_format_accepted": "Принимаются файлы любого формата",
"send_more_files": "Отправить больше файлов",
"secure_file_send": "безопасная отправка файлов",
"add_a_message": "Добавить сообщение",
"files_sent_with_note": "1 файл отправлен с примечанием! | {count} файлов, отправленных с примечанием!",
"files_sent_with_note": "{count} файл отправлен с примечанием! | {count} файлов, отправленных с примечанием! | {count} файлов, отправленных с примечанием!",
"choose_files": "Выбрать файл"
},
"global": {
@ -88,9 +88,9 @@
"show_more": "Показать больше",
"time": {
"recently": "только что",
"minutes": "1 минуту назад | {n} минут назад",
"hours": "1 час назад | {n} часов назад",
"days": "1 день назад | {n} дней назад"
"minutes": "{n} минуту назад | {n} минут назад | {n} минут назад",
"hours": "{n} час назад | {n} часов назад | {n} часов назад",
"days": "{n} день назад | {n} дней назад | {n} дней назад"
},
"notify": "Оповестить",
"password_didnot_match": "Пароль не совпадает",
@ -158,10 +158,10 @@
"replying_to": "Отвечая на {user}",
"your_message": "Ваше сообщение...",
"scale_image": "Масштаб изображения",
"time_ago": "Сегодня | Вчера | {count} дней назад",
"time_ago": "Сегодня | Вчера | {count} дней назад | {count} дней назад",
"not_allowed_to_send": "Только администраторы и модераторы могут отправлять сообщения в комнату",
"reaction_count_more": "{reactionCount} больше",
"seen_by_count": "Видели ни один участник | Видел 1 участник | Видели {count} участников",
"seen_by_count": "Видели ни один участник | Видел {count} участник | Видели {count} участников | Видели {count} участников",
"send_attachements_dialog_title": "Вы хотите отправить следующие вложения?",
"failed_to_render": "Не удалось отрендерить событие"
},
@ -242,14 +242,14 @@
"leave": "Оставить",
"room_list_invites": "Приглашения",
"room_list_rooms": "Комнаты",
"unseen_messages": "У вас нет непросмотренных сообщений | У вас 1 непросмотренное сообщение | У вас {count} непросмотренных сообщений",
"members": "нет членов | 1 член | {count} членов",
"unseen_messages": "У вас нет непросмотренных сообщений | У вас {count} непросмотренное сообщение | У вас {count} непросмотренных сообщений | У вас {count} непросмотренных сообщений",
"members": "нет членов | {count} член | {count} членов | {count} членов",
"purge_set_room_state": "Установка состояния комнаты",
"purge_removing_members": "Удаление членов ({count} из {total})",
"purge_failed": "Не удалось очистить комнату!",
"room_name_required": "Название комнаты обязательно",
"room_topic_required": "Описание номера обязательно",
"invitations": "У вас нет приглашений | У вас есть 1 приглашение | У вас есть {count} приглашений",
"invitations": "У вас нет приглашений | У вас есть {count} приглашение | У вас есть {count} приглашений | У вас есть {count} приглашений",
"purge_redacting_events": "Сокращение событий ({count} из {total})",
"room_list_new_messages": "{count} новых сообщений"
},

View file

@ -20,5 +20,35 @@ export default new VueI18n({
locale: 'en',
fallbackLocale: 'en',
silentFallbackWarn: true,
messages: messages
messages: messages,
pluralizationRules: {
/**
* @param choice {number} a choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)`
* @param choicesLength {number} an overall amount of available choices
* @returns a final choice index to select plural word by
*/
'ru': function(choice, choicesLength) {
// this === VueI18n instance, so the locale property also exists here
if (choice === 0) {
return 0;
}
const zeroChoiseOffset = (choicesLength == 4) ? 1 : 0;
const teen = choice > 10 && choice < 20;
const endsWithOne = choice % 10 === 1;
if (!teen && endsWithOne) {
console.log("Not teen, ends with one", zeroChoiseOffset, choice);
return zeroChoiseOffset + 0;
}
if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
console.log("Ends with 2-4", zeroChoiseOffset, choice);
return zeroChoiseOffset + 1;
}
console.log("Other", choice);
return (choicesLength < 4) ? 2 : 3;
}
}
})