Browse Source

[RN] Add proper locale support to MomentJS

master
zbettenbuk 7 years ago
parent
commit
d08bbae770
1 changed files with 94 additions and 8 deletions
  1. 94
    8
      react/features/recent-list/functions.js

+ 94
- 8
react/features/recent-list/functions.js View File

2
 
2
 
3
 import moment from 'moment';
3
 import moment from 'moment';
4
 
4
 
5
+import { RECENT_URL_STORAGE } from './constants';
6
+
5
 import { i18next } from '../base/i18n';
7
 import { i18next } from '../base/i18n';
6
 import { parseURIString } from '../base/util';
8
 import { parseURIString } from '../base/util';
7
 
9
 
8
-import { RECENT_URL_STORAGE } from './constants';
10
+/**
11
+ * MomentJS uses static language bundle loading, so in order to support
12
+ * dynamic language selection in the app we need to load all bundles that we
13
+ * support in the app.
14
+ * FIXME: If we decide to support MomentJS in other features as well
15
+ * we may need to move this import and the lenient matcher to the i18n feature.
16
+ */
17
+require('moment/locale/bg');
18
+require('moment/locale/de');
19
+require('moment/locale/eo');
20
+require('moment/locale/es');
21
+require('moment/locale/fr');
22
+require('moment/locale/hy-am');
23
+require('moment/locale/it');
24
+require('moment/locale/nb');
25
+
26
+// OC is not available. Please submit OC translation
27
+// to the MomentJS project.
28
+
29
+require('moment/locale/pl');
30
+require('moment/locale/pt');
31
+require('moment/locale/pt-br');
32
+require('moment/locale/ru');
33
+require('moment/locale/sk');
34
+require('moment/locale/sl');
35
+require('moment/locale/sv');
36
+require('moment/locale/tr');
37
+require('moment/locale/zh-cn');
9
 
38
 
10
 /**
39
 /**
11
  * Retreives the recent room list and generates all the data needed to be
40
  * Retreives the recent room list and generates all the data needed to be
21
                 const recentRoomDS = [];
50
                 const recentRoomDS = [];
22
 
51
 
23
                 if (recentURLs) {
52
                 if (recentURLs) {
53
+                    // we init the locale on every list render, so then it
54
+                    // changes immediately if a language change happens
55
+                    // in the app.
56
+                    const locale = _getSupportedLocale();
57
+
24
                     for (const e of JSON.parse(recentURLs)) {
58
                     for (const e of JSON.parse(recentURLs)) {
25
                         const location = parseURIString(e.conference);
59
                         const location = parseURIString(e.conference);
26
 
60
 
31
                                 conference: e.conference,
65
                                 conference: e.conference,
32
                                 conferenceDuration: e.conferenceDuration,
66
                                 conferenceDuration: e.conferenceDuration,
33
                                 conferenceDurationString:
67
                                 conferenceDurationString:
34
-                                    _getDurationString(e.conferenceDuration),
35
-                                dateString: _getDateString(e.date),
68
+                                    _getDurationString(
69
+                                        e.conferenceDuration,
70
+                                        locale
71
+                                    ),
72
+                                dateString: _getDateString(e.date, locale),
36
                                 dateTimeStamp: e.date,
73
                                 dateTimeStamp: e.date,
37
                                 initials: _getInitials(location.room),
74
                                 initials: _getInitials(location.room),
38
                                 room: location.room,
75
                                 room: location.room,
76
  * Returns a well formatted date string to be displayed in the list.
113
  * Returns a well formatted date string to be displayed in the list.
77
  *
114
  *
78
  * @param {number} dateTimeStamp - The UTC timestamp to be converted to String.
115
  * @param {number} dateTimeStamp - The UTC timestamp to be converted to String.
116
+ * @param {string} locale - The locale to init the formatter with. Note: This
117
+ * locale must be supported by the formatter so ensure this prerequisite
118
+ * before invoking the function.
79
  * @private
119
  * @private
80
  * @returns {string}
120
  * @returns {string}
81
  */
121
  */
82
-function _getDateString(dateTimeStamp: number) {
122
+function _getDateString(dateTimeStamp: number, locale: string) {
83
     const date = new Date(dateTimeStamp);
123
     const date = new Date(dateTimeStamp);
84
-    const m = moment(date).locale(i18next.language);
124
+    const m = _getLocalizedFormatter(date, locale);
85
 
125
 
86
     if (date.toDateString() === new Date().toDateString()) {
126
     if (date.toDateString() === new Date().toDateString()) {
87
         // The date is today, we use fromNow format.
127
         // The date is today, we use fromNow format.
96
  * length.
136
  * length.
97
  *
137
  *
98
  * @param {number} duration - The duration in MS.
138
  * @param {number} duration - The duration in MS.
139
+ * @param {string} locale - The locale to init the formatter with. Note: This
140
+ * locale must be supported by the formatter so ensure this prerequisite
141
+ * before invoking the function.
99
  * @private
142
  * @private
100
  * @returns {string}
143
  * @returns {string}
101
  */
144
  */
102
-function _getDurationString(duration: number) {
103
-    return moment.duration(duration)
104
-            .locale(i18next.language)
145
+function _getDurationString(duration: number, locale: string) {
146
+    return _getLocalizedFormatter(duration, locale)
105
             .humanize();
147
             .humanize();
106
 }
148
 }
107
 
149
 
115
 function _getInitials(room: string) {
157
 function _getInitials(room: string) {
116
     return room && room.charAt(0) ? room.charAt(0).toUpperCase() : '?';
158
     return room && room.charAt(0) ? room.charAt(0).toUpperCase() : '?';
117
 }
159
 }
160
+
161
+/**
162
+ * Returns a localized date formatter initialized with the
163
+ * provided date (@code Date) or duration (@code Number).
164
+ *
165
+ * @private
166
+ * @param {Date | number} dateToFormat - The date or duration to format.
167
+ * @param {string} locale - The locale to init the formatter with. Note: This
168
+ * locale must be supported by the formatter so ensure this prerequisite
169
+ * before invoking the function.
170
+ * @returns {Object}
171
+ */
172
+function _getLocalizedFormatter(dateToFormat: Date | number, locale: string) {
173
+    if (typeof dateToFormat === 'number') {
174
+        return moment.duration(dateToFormat).locale(locale);
175
+    }
176
+
177
+    return moment(dateToFormat).locale(locale);
178
+}
179
+
180
+/**
181
+ * A lenient locale matcher to match language and dialect if possible.
182
+ *
183
+ * @private
184
+ * @returns {string}
185
+ */
186
+function _getSupportedLocale() {
187
+    const i18nLocale = i18next.language.toLowerCase();
188
+    const localeRegexp = new RegExp('^([a-z]{2,2})(-)*([a-z]{2,2})*$');
189
+    const localeResult = localeRegexp.exec(i18nLocale);
190
+
191
+    if (localeResult) {
192
+        const currentLocaleRegexp = new RegExp(
193
+            `^${localeResult[1]}(-)*${`(${localeResult[3]})*` || ''}`
194
+        );
195
+
196
+        return moment.locales().find(
197
+            lang => currentLocaleRegexp.exec(lang)
198
+        ) || 'en';
199
+    }
200
+
201
+    // default fallback
202
+    return 'en';
203
+}

Loading…
Cancel
Save