Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

functions.js 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // @flow
  2. import moment from 'moment';
  3. import { i18next } from '../base/i18n';
  4. import { parseURIString } from '../base/util';
  5. /**
  6. * MomentJS uses static language bundle loading, so in order to support dynamic
  7. * language selection in the app we need to load all bundles that we support in
  8. * the app.
  9. * FIXME: If we decide to support MomentJS in other features as well we may need
  10. * to move this import and the lenient matcher to the i18n feature.
  11. */
  12. require('moment/locale/bg');
  13. require('moment/locale/de');
  14. require('moment/locale/eo');
  15. require('moment/locale/es');
  16. require('moment/locale/fr');
  17. require('moment/locale/hy-am');
  18. require('moment/locale/it');
  19. require('moment/locale/nb');
  20. // OC is not available. Please submit OC translation to the MomentJS project.
  21. require('moment/locale/pl');
  22. require('moment/locale/pt');
  23. require('moment/locale/pt-br');
  24. require('moment/locale/ru');
  25. require('moment/locale/sk');
  26. require('moment/locale/sl');
  27. require('moment/locale/sv');
  28. require('moment/locale/tr');
  29. require('moment/locale/zh-cn');
  30. /**
  31. * Retrieves the recent room list and generates all the data needed to be
  32. * displayed.
  33. *
  34. * @param {Array<Object>} list - The stored recent list retrieved from Redux.
  35. * @returns {Array}
  36. */
  37. export function getRecentRooms(list: Array<Object>): Array<Object> {
  38. const recentRoomDS = [];
  39. if (list.length) {
  40. // We init the locale on every list render, so then it changes
  41. // immediately if a language change happens in the app.
  42. const locale = _getSupportedLocale();
  43. for (const e of list) {
  44. const location = parseURIString(e.conference);
  45. if (location && location.room && location.hostname) {
  46. recentRoomDS.push({
  47. baseURL: `${location.protocol}//${location.host}`,
  48. conference: e.conference,
  49. conferenceDuration: e.conferenceDuration,
  50. conferenceDurationString:
  51. _getDurationString(
  52. e.conferenceDuration,
  53. locale),
  54. dateString: _getDateString(e.date, locale),
  55. dateTimeStamp: e.date,
  56. initials: _getInitials(location.room),
  57. room: location.room,
  58. serverName: location.hostname
  59. });
  60. }
  61. }
  62. }
  63. return recentRoomDS.reverse();
  64. }
  65. /**
  66. * Returns a well formatted date string to be displayed in the list.
  67. *
  68. * @param {number} dateTimeStamp - The UTC timestamp to be converted to String.
  69. * @param {string} locale - The locale to init the formatter with. Note: This
  70. * locale must be supported by the formatter so ensure this prerequisite before
  71. * invoking the function.
  72. * @private
  73. * @returns {string}
  74. */
  75. function _getDateString(dateTimeStamp: number, locale: string) {
  76. const date = new Date(dateTimeStamp);
  77. const m = _getLocalizedFormatter(date, locale);
  78. if (date.toDateString() === new Date().toDateString()) {
  79. // The date is today, we use fromNow format.
  80. return m.fromNow();
  81. }
  82. return m.format('lll');
  83. }
  84. /**
  85. * Returns a well formatted duration string to be displayed as the conference
  86. * length.
  87. *
  88. * @param {number} duration - The duration in MS.
  89. * @param {string} locale - The locale to init the formatter with. Note: This
  90. * locale must be supported by the formatter so ensure this prerequisite before
  91. * invoking the function.
  92. * @private
  93. * @returns {string}
  94. */
  95. function _getDurationString(duration: number, locale: string) {
  96. return _getLocalizedFormatter(duration, locale).humanize();
  97. }
  98. /**
  99. * Returns the initials supposed to be used based on the room name.
  100. *
  101. * @param {string} room - The room name.
  102. * @private
  103. * @returns {string}
  104. */
  105. function _getInitials(room: string) {
  106. return room && room.charAt(0) ? room.charAt(0).toUpperCase() : '?';
  107. }
  108. /**
  109. * Returns a localized date formatter initialized with the provided date
  110. * (@code Date) or duration (@code number).
  111. *
  112. * @private
  113. * @param {Date | number} dateOrDuration - The date or duration to format.
  114. * @param {string} locale - The locale to init the formatter with. Note: This
  115. * locale must be supported by the formatter so ensure this prerequisite before
  116. * invoking the function.
  117. * @returns {Object}
  118. */
  119. function _getLocalizedFormatter(dateOrDuration: Date | number, locale: string) {
  120. const m
  121. = typeof dateOrDuration === 'number'
  122. ? moment.duration(dateOrDuration)
  123. : moment(dateOrDuration);
  124. return m.locale(locale);
  125. }
  126. /**
  127. * A lenient locale matcher to match language and dialect if possible.
  128. *
  129. * @private
  130. * @returns {string}
  131. */
  132. function _getSupportedLocale() {
  133. const i18nLocale = i18next.language;
  134. let supportedLocale;
  135. if (i18nLocale) {
  136. const localeRegexp = new RegExp('^([a-z]{2,2})(-)*([a-z]{2,2})*$');
  137. const localeResult = localeRegexp.exec(i18nLocale.toLowerCase());
  138. if (localeResult) {
  139. const currentLocaleRegexp
  140. = new RegExp(
  141. `^${localeResult[1]}(-)*${`(${localeResult[3]})*` || ''}`);
  142. supportedLocale
  143. = moment.locales().find(lang => currentLocaleRegexp.exec(lang));
  144. }
  145. }
  146. return supportedLocale || 'en';
  147. }