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.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /* @flow */
  2. import { setConfigFromURLParams } from '../../base/config';
  3. import { toState } from '../../base/redux';
  4. import { loadScript } from '../../base/util';
  5. import JitsiMeetJS from './_';
  6. declare var APP: Object;
  7. const JitsiConferenceErrors = JitsiMeetJS.errors.conference;
  8. const JitsiConnectionErrors = JitsiMeetJS.errors.connection;
  9. /**
  10. * Creates a JitsiLocalTrack model from the given device id.
  11. *
  12. * @param {string} type - The media type of track being created. Expected values
  13. * are "video" or "audio".
  14. * @param {string} deviceId - The id of the target media source.
  15. * @returns {Promise<JitsiLocalTrack>}
  16. */
  17. export function createLocalTrack(type: string, deviceId: string) {
  18. return (
  19. JitsiMeetJS.createLocalTracks({
  20. cameraDeviceId: deviceId,
  21. devices: [ type ],
  22. // eslint-disable-next-line camelcase
  23. firefox_fake_device:
  24. window.config && window.config.firefox_fake_device,
  25. micDeviceId: deviceId
  26. })
  27. .then(([ jitsiLocalTrack ]) => jitsiLocalTrack));
  28. }
  29. /**
  30. * Determines whether analytics is enabled in a specific redux {@code store}.
  31. *
  32. * @param {Function|Object} stateful - The redux store, state, or
  33. * {@code getState} function.
  34. * @returns {boolean} If analytics is enabled, {@code true}; {@code false},
  35. * otherwise.
  36. */
  37. export function isAnalyticsEnabled(stateful: Function | Object) {
  38. const {
  39. analyticsScriptUrls,
  40. disableThirdPartyRequests
  41. } = toState(stateful)['features/base/config'];
  42. return (
  43. !disableThirdPartyRequests
  44. && Array.isArray(analyticsScriptUrls)
  45. && Boolean(analyticsScriptUrls.length));
  46. }
  47. /**
  48. * Determines whether a specific JitsiConferenceErrors instance indicates a
  49. * fatal JitsiConference error.
  50. *
  51. * FIXME Figure out the category of errors defined by the function and describe
  52. * that category. I've currently named the category fatal because it appears to
  53. * be used in the cases of unrecoverable errors that necessitate a reload.
  54. *
  55. * @param {Object|string} error - The JitsiConferenceErrors instance to
  56. * categorize/classify or an Error-like object.
  57. * @returns {boolean} True if the specified JitsiConferenceErrors instance
  58. * indicates a fatal JitsiConference error; otherwise, false.
  59. */
  60. export function isFatalJitsiConferenceError(error: Object | string) {
  61. if (typeof error !== 'string') {
  62. error = error.name; // eslint-disable-line no-param-reassign
  63. }
  64. return (
  65. error === JitsiConferenceErrors.FOCUS_DISCONNECTED
  66. || error === JitsiConferenceErrors.FOCUS_LEFT
  67. || error === JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE);
  68. }
  69. /**
  70. * Determines whether a specific JitsiConnectionErrors instance indicates a
  71. * fatal JitsiConnection error.
  72. *
  73. * FIXME Figure out the category of errors defined by the function and describe
  74. * that category. I've currently named the category fatal because it appears to
  75. * be used in the cases of unrecoverable errors that necessitate a reload.
  76. *
  77. * @param {Object|string} error - The JitsiConnectionErrors instance to
  78. * categorize/classify or an Error-like object.
  79. * @returns {boolean} True if the specified JitsiConnectionErrors instance
  80. * indicates a fatal JitsiConnection error; otherwise, false.
  81. */
  82. export function isFatalJitsiConnectionError(error: Object | string) {
  83. if (typeof error !== 'string') {
  84. error = error.name; // eslint-disable-line no-param-reassign
  85. }
  86. return (
  87. error === JitsiConnectionErrors.CONNECTION_DROPPED_ERROR
  88. || error === JitsiConnectionErrors.OTHER_ERROR
  89. || error === JitsiConnectionErrors.SERVER_ERROR);
  90. }
  91. /**
  92. * Loads config.js from a specific remote server.
  93. *
  94. * @param {string} url - The URL to load.
  95. * @returns {Promise<Object>}
  96. */
  97. export function loadConfig(url: string) {
  98. let promise;
  99. if (typeof APP === 'undefined') {
  100. promise
  101. = loadScript(url)
  102. .then(() => {
  103. const { config } = window;
  104. // We don't want to pollute the global scope.
  105. window.config = undefined;
  106. if (typeof config !== 'object') {
  107. throw new Error('window.config is not an object');
  108. }
  109. return config;
  110. })
  111. .catch(err => {
  112. console.error(`Failed to load config from ${url}`, err);
  113. throw err;
  114. });
  115. } else {
  116. // Return "the config.js file" from the global scope - that is how the
  117. // Web app on both the client and the server was implemented before the
  118. // React Native app was even conceived.
  119. promise = Promise.resolve(window.config);
  120. }
  121. // FIXME It's neither here nor there at the time of this writing where
  122. // config, interfaceConfig, and loggingConfig should be overwritten by URL
  123. // params.
  124. promise = promise.then(value => {
  125. setConfigFromURLParams();
  126. return value;
  127. });
  128. return promise;
  129. }