[RN] Add proper locale support to MomentJS
This commit is contained in:
parent
30b51ff384
commit
d08bbae770
|
@ -2,10 +2,39 @@
|
|||
|
||||
import moment from 'moment';
|
||||
|
||||
import { RECENT_URL_STORAGE } from './constants';
|
||||
|
||||
import { i18next } from '../base/i18n';
|
||||
import { parseURIString } from '../base/util';
|
||||
|
||||
import { RECENT_URL_STORAGE } from './constants';
|
||||
/**
|
||||
* MomentJS uses static language bundle loading, so in order to support
|
||||
* dynamic language selection in the app we need to load all bundles that we
|
||||
* support in the app.
|
||||
* FIXME: If we decide to support MomentJS in other features as well
|
||||
* we may need to move this import and the lenient matcher to the i18n feature.
|
||||
*/
|
||||
require('moment/locale/bg');
|
||||
require('moment/locale/de');
|
||||
require('moment/locale/eo');
|
||||
require('moment/locale/es');
|
||||
require('moment/locale/fr');
|
||||
require('moment/locale/hy-am');
|
||||
require('moment/locale/it');
|
||||
require('moment/locale/nb');
|
||||
|
||||
// OC is not available. Please submit OC translation
|
||||
// to the MomentJS project.
|
||||
|
||||
require('moment/locale/pl');
|
||||
require('moment/locale/pt');
|
||||
require('moment/locale/pt-br');
|
||||
require('moment/locale/ru');
|
||||
require('moment/locale/sk');
|
||||
require('moment/locale/sl');
|
||||
require('moment/locale/sv');
|
||||
require('moment/locale/tr');
|
||||
require('moment/locale/zh-cn');
|
||||
|
||||
/**
|
||||
* Retreives the recent room list and generates all the data needed to be
|
||||
|
@ -21,6 +50,11 @@ export function getRecentRooms(): Promise<Array<Object>> {
|
|||
const recentRoomDS = [];
|
||||
|
||||
if (recentURLs) {
|
||||
// we init the locale on every list render, so then it
|
||||
// changes immediately if a language change happens
|
||||
// in the app.
|
||||
const locale = _getSupportedLocale();
|
||||
|
||||
for (const e of JSON.parse(recentURLs)) {
|
||||
const location = parseURIString(e.conference);
|
||||
|
||||
|
@ -31,8 +65,11 @@ export function getRecentRooms(): Promise<Array<Object>> {
|
|||
conference: e.conference,
|
||||
conferenceDuration: e.conferenceDuration,
|
||||
conferenceDurationString:
|
||||
_getDurationString(e.conferenceDuration),
|
||||
dateString: _getDateString(e.date),
|
||||
_getDurationString(
|
||||
e.conferenceDuration,
|
||||
locale
|
||||
),
|
||||
dateString: _getDateString(e.date, locale),
|
||||
dateTimeStamp: e.date,
|
||||
initials: _getInitials(location.room),
|
||||
room: location.room,
|
||||
|
@ -76,12 +113,15 @@ export function updateRecentURLs(recentURLs: Array<Object>) {
|
|||
* Returns a well formatted date string to be displayed in the list.
|
||||
*
|
||||
* @param {number} dateTimeStamp - The UTC timestamp to be converted to String.
|
||||
* @param {string} locale - The locale to init the formatter with. Note: This
|
||||
* locale must be supported by the formatter so ensure this prerequisite
|
||||
* before invoking the function.
|
||||
* @private
|
||||
* @returns {string}
|
||||
*/
|
||||
function _getDateString(dateTimeStamp: number) {
|
||||
function _getDateString(dateTimeStamp: number, locale: string) {
|
||||
const date = new Date(dateTimeStamp);
|
||||
const m = moment(date).locale(i18next.language);
|
||||
const m = _getLocalizedFormatter(date, locale);
|
||||
|
||||
if (date.toDateString() === new Date().toDateString()) {
|
||||
// The date is today, we use fromNow format.
|
||||
|
@ -96,12 +136,14 @@ function _getDateString(dateTimeStamp: number) {
|
|||
* length.
|
||||
*
|
||||
* @param {number} duration - The duration in MS.
|
||||
* @param {string} locale - The locale to init the formatter with. Note: This
|
||||
* locale must be supported by the formatter so ensure this prerequisite
|
||||
* before invoking the function.
|
||||
* @private
|
||||
* @returns {string}
|
||||
*/
|
||||
function _getDurationString(duration: number) {
|
||||
return moment.duration(duration)
|
||||
.locale(i18next.language)
|
||||
function _getDurationString(duration: number, locale: string) {
|
||||
return _getLocalizedFormatter(duration, locale)
|
||||
.humanize();
|
||||
}
|
||||
|
||||
|
@ -115,3 +157,47 @@ function _getDurationString(duration: number) {
|
|||
function _getInitials(room: string) {
|
||||
return room && room.charAt(0) ? room.charAt(0).toUpperCase() : '?';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a localized date formatter initialized with the
|
||||
* provided date (@code Date) or duration (@code Number).
|
||||
*
|
||||
* @private
|
||||
* @param {Date | number} dateToFormat - The date or duration to format.
|
||||
* @param {string} locale - The locale to init the formatter with. Note: This
|
||||
* locale must be supported by the formatter so ensure this prerequisite
|
||||
* before invoking the function.
|
||||
* @returns {Object}
|
||||
*/
|
||||
function _getLocalizedFormatter(dateToFormat: Date | number, locale: string) {
|
||||
if (typeof dateToFormat === 'number') {
|
||||
return moment.duration(dateToFormat).locale(locale);
|
||||
}
|
||||
|
||||
return moment(dateToFormat).locale(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* A lenient locale matcher to match language and dialect if possible.
|
||||
*
|
||||
* @private
|
||||
* @returns {string}
|
||||
*/
|
||||
function _getSupportedLocale() {
|
||||
const i18nLocale = i18next.language.toLowerCase();
|
||||
const localeRegexp = new RegExp('^([a-z]{2,2})(-)*([a-z]{2,2})*$');
|
||||
const localeResult = localeRegexp.exec(i18nLocale);
|
||||
|
||||
if (localeResult) {
|
||||
const currentLocaleRegexp = new RegExp(
|
||||
`^${localeResult[1]}(-)*${`(${localeResult[3]})*` || ''}`
|
||||
);
|
||||
|
||||
return moment.locales().find(
|
||||
lang => currentLocaleRegexp.exec(lang)
|
||||
) || 'en';
|
||||
}
|
||||
|
||||
// default fallback
|
||||
return 'en';
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue