You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

functions.web.js 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /* @flow */
  2. import Logger from 'jitsi-meet-logger';
  3. import { isRoomValid } from '../base/conference';
  4. import JitsiMeetJS from '../base/lib-jitsi-meet';
  5. import { Platform, RouteRegistry } from '../base/react';
  6. import { Conference } from '../conference';
  7. import {
  8. NoMobileApp,
  9. PluginRequiredBrowser,
  10. UnsupportedDesktopBrowser,
  11. UnsupportedMobileBrowser
  12. } from '../unsupported-browser';
  13. import { WelcomePage } from '../welcome';
  14. import URLProcessor from '../../../modules/config/URLProcessor';
  15. import KeyboardShortcut
  16. from '../../../modules/keyboardshortcut/keyboardshortcut';
  17. import getTokenData from '../../../modules/tokendata/TokenData';
  18. import JitsiMeetLogStorage from '../../../modules/util/JitsiMeetLogStorage';
  19. declare var APP: Object;
  20. declare var interfaceConfig: Object;
  21. declare var loggingConfig: Object;
  22. /**
  23. * Array of rules defining whether we should {@link _interceptComponent} to
  24. * render.
  25. *
  26. * @private
  27. * @param {Object} state - Object containing current Redux state.
  28. * @returns {ReactElement|void}
  29. * @type {Function[]}
  30. */
  31. const _INTERCEPT_COMPONENT_RULES = [
  32. /**
  33. * This rule describes case when user opens application using mobile
  34. * browser. In order to promote the app, we choose to suggest the mobile
  35. * app even if the browser supports the app (e.g. Google Chrome with
  36. * WebRTC support on Android).
  37. *
  38. * @param {Object} state - Redux state of the app.
  39. * @returns {UnsupportedMobileBrowser|void} If the rule is satisfied then
  40. * we should intercept existing component by UnsupportedMobileBrowser.
  41. */
  42. () => {
  43. const OS = Platform.OS;
  44. if (OS === 'android' || OS === 'ios') {
  45. const mobileAppPromo
  46. = typeof interfaceConfig === 'object'
  47. && interfaceConfig.MOBILE_APP_PROMO;
  48. return (
  49. typeof mobileAppPromo === 'undefined' || Boolean(mobileAppPromo)
  50. ? UnsupportedMobileBrowser
  51. : NoMobileApp);
  52. }
  53. },
  54. state => {
  55. const { webRTCReady } = state['features/base/lib-jitsi-meet'];
  56. switch (typeof webRTCReady) {
  57. case 'boolean':
  58. if (webRTCReady === false) {
  59. return UnsupportedDesktopBrowser;
  60. }
  61. break;
  62. case 'undefined':
  63. // If webRTCReady is not set, then we cannot use it to take a
  64. // decision.
  65. break;
  66. default:
  67. return PluginRequiredBrowser;
  68. }
  69. }
  70. ];
  71. export { _parseURIString } from './functions.native';
  72. /**
  73. * Determines which route is to be rendered in order to depict a specific Redux
  74. * store.
  75. *
  76. * @param {(Object|Function)} stateOrGetState - Redux state or Regux getState()
  77. * method.
  78. * @returns {Route}
  79. */
  80. export function _getRouteToRender(stateOrGetState: Object | Function) {
  81. const state
  82. = typeof stateOrGetState === 'function'
  83. ? stateOrGetState()
  84. : stateOrGetState;
  85. // If mobile browser page was shown, there is no need to show it again.
  86. const { room } = state['features/base/conference'];
  87. const component = isRoomValid(room) ? Conference : WelcomePage;
  88. const route = RouteRegistry.getRouteByComponent(component);
  89. // Intercepts route components if any of component interceptor rules
  90. // is satisfied.
  91. route.component = _interceptComponent(state, component);
  92. return route;
  93. }
  94. /**
  95. * Temporary solution. Later we'll get rid of global APP and set its properties
  96. * in redux store.
  97. *
  98. * @returns {void}
  99. */
  100. export function init() {
  101. URLProcessor.setConfigParametersFromUrl();
  102. _initLogging();
  103. APP.keyboardshortcut = KeyboardShortcut;
  104. APP.tokenData = getTokenData();
  105. // Force enable the API if jwt token is passed because most probably
  106. // jitsi meet is displayed inside of wrapper that will need to communicate
  107. // with jitsi meet.
  108. APP.API.init(APP.tokenData.jwt ? { forceEnable: true } : undefined);
  109. APP.translation.init();
  110. }
  111. /**
  112. * Adjusts the logging levels.
  113. *
  114. * @private
  115. * @returns {void}
  116. */
  117. function _configureLoggingLevels() {
  118. // NOTE The library Logger is separated from the app loggers, so the levels
  119. // have to be set in two places
  120. // Set default logging level
  121. const defaultLogLevel
  122. = loggingConfig.defaultLogLevel || JitsiMeetJS.logLevels.TRACE;
  123. Logger.setLogLevel(defaultLogLevel);
  124. JitsiMeetJS.setLogLevel(defaultLogLevel);
  125. // NOTE console was used on purpose here to go around the logging and always
  126. // print the default logging level to the console
  127. console.info(`Default logging level set to: ${defaultLogLevel}`);
  128. // Set log level for each logger
  129. if (loggingConfig) {
  130. Object.keys(loggingConfig).forEach(loggerName => {
  131. if (loggerName !== 'defaultLogLevel') {
  132. const level = loggingConfig[loggerName];
  133. Logger.setLogLevelById(level, loggerName);
  134. JitsiMeetJS.setLogLevelById(level, loggerName);
  135. }
  136. });
  137. }
  138. }
  139. /**
  140. * Initializes logging in the app.
  141. *
  142. * @private
  143. * @returns {void}
  144. */
  145. function _initLogging() {
  146. // Adjust logging level
  147. _configureLoggingLevels();
  148. // Create the LogCollector and register it as the global log transport. It
  149. // is done early to capture as much logs as possible. Captured logs will be
  150. // cached, before the JitsiMeetLogStorage gets ready (statistics module is
  151. // initialized).
  152. if (!APP.logCollector && !loggingConfig.disableLogCollector) {
  153. APP.logCollector = new Logger.LogCollector(new JitsiMeetLogStorage());
  154. Logger.addGlobalTransport(APP.logCollector);
  155. JitsiMeetJS.addGlobalLogTransport(APP.logCollector);
  156. }
  157. }
  158. /**
  159. * Intercepts route components based on a {@link _INTERCEPT_COMPONENT_RULES}.
  160. *
  161. * @param {Object|Function} stateOrGetState - Either Redux state object or
  162. * getState() function.
  163. * @param {ReactElement} component - Current route component to render.
  164. * @private
  165. * @returns {ReactElement} If any of the pre-defined rules is satisfied, returns
  166. * intercepted component.
  167. */
  168. function _interceptComponent(
  169. stateOrGetState: Object,
  170. component: ReactElement<*>) {
  171. let result;
  172. const state
  173. = typeof stateOrGetState === 'function'
  174. ? stateOrGetState()
  175. : stateOrGetState;
  176. for (const rule of _INTERCEPT_COMPONENT_RULES) {
  177. result = rule(state);
  178. if (result) {
  179. break;
  180. }
  181. }
  182. return result || component;
  183. }