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.

actions.js 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // @flow
  2. import type { Dispatch } from 'redux';
  3. import { setRoom } from '../base/conference';
  4. import {
  5. configWillLoad,
  6. loadConfigError,
  7. restoreConfig,
  8. setConfig,
  9. storeConfig
  10. } from '../base/config';
  11. import { setLocationURL } from '../base/connection';
  12. import { loadConfig } from '../base/lib-jitsi-meet';
  13. import { parseURIString, toURLString } from '../base/util';
  14. import { setFatalError } from '../overlay';
  15. import { getDefaultURL } from './functions';
  16. const logger = require('jitsi-meet-logger').getLogger(__filename);
  17. declare var APP: Object;
  18. /**
  19. * Triggers an in-app navigation to a specific route. Allows navigation to be
  20. * abstracted between the mobile/React Native and Web/React applications.
  21. *
  22. * @param {string|undefined} uri - The URI to which to navigate. It may be a
  23. * full URL with an HTTP(S) scheme, a full or partial URI with the app-specific
  24. * scheme, or a mere room name.
  25. * @returns {Function}
  26. */
  27. export function appNavigate(uri: ?string) {
  28. return async (dispatch: Dispatch<any>, getState: Function) => {
  29. let location = parseURIString(uri);
  30. // If the specified location (URI) does not identify a host, use the app's
  31. // default.
  32. if (!location || !location.host) {
  33. const defaultLocation = parseURIString(getDefaultURL(getState));
  34. if (location) {
  35. location.host = defaultLocation.host;
  36. // FIXME Turn location's host, hostname, and port properties into
  37. // setters in order to reduce the risks of inconsistent state.
  38. location.hostname = defaultLocation.hostname;
  39. location.pathname
  40. = defaultLocation.pathname + location.pathname.substr(1);
  41. location.port = defaultLocation.port;
  42. location.protocol = defaultLocation.protocol;
  43. } else {
  44. location = defaultLocation;
  45. }
  46. }
  47. location.protocol || (location.protocol = 'https:');
  48. const { contextRoot, host, room } = location;
  49. const locationURL = new URL(location.toString());
  50. dispatch(configWillLoad(locationURL, room));
  51. let protocol = location.protocol.toLowerCase();
  52. // The React Native app supports an app-specific scheme which is sure to not
  53. // be supported by fetch.
  54. protocol !== 'http:' && protocol !== 'https:' && (protocol = 'https:');
  55. const baseURL = `${protocol}//${host}${contextRoot || '/'}`;
  56. let url = `${baseURL}config.js`;
  57. // XXX In order to support multiple shards, tell the room to the deployment.
  58. room && (url += `?room=${room.toLowerCase()}`);
  59. let config;
  60. try {
  61. config = await loadConfig(url);
  62. dispatch(storeConfig(baseURL, config));
  63. } catch (error) {
  64. config = restoreConfig(baseURL);
  65. if (!config) {
  66. dispatch(loadConfigError(error, locationURL));
  67. return;
  68. }
  69. }
  70. if (getState()['features/base/config'].locationURL === locationURL) {
  71. dispatch(setLocationURL(locationURL));
  72. dispatch(setConfig(config));
  73. dispatch(setRoom(room));
  74. } else {
  75. dispatch(loadConfigError(new Error('Config no longer needed!'), locationURL));
  76. }
  77. };
  78. }
  79. /**
  80. * Redirects to another page generated by replacing the path in the original URL
  81. * with the given path.
  82. *
  83. * @param {(string)} pathname - The path to navigate to.
  84. * @returns {Function}
  85. */
  86. export function redirectWithStoredParams(pathname: string) {
  87. return (dispatch: Dispatch<any>, getState: Function) => {
  88. const { locationURL } = getState()['features/base/connection'];
  89. const newLocationURL = new URL(locationURL.href);
  90. newLocationURL.pathname = pathname;
  91. window.location.assign(newLocationURL.toString());
  92. };
  93. }
  94. /**
  95. * Reloads the page.
  96. *
  97. * @protected
  98. * @returns {Function}
  99. */
  100. export function reloadNow() {
  101. return (dispatch: Dispatch<Function>, getState: Function) => {
  102. dispatch(setFatalError(undefined));
  103. const { locationURL } = getState()['features/base/connection'];
  104. logger.info(`Reloading the conference using URL: ${locationURL}`);
  105. if (navigator.product === 'ReactNative') {
  106. dispatch(appNavigate(toURLString(locationURL)));
  107. } else {
  108. dispatch(reloadWithStoredParams());
  109. }
  110. };
  111. }
  112. /**
  113. * Reloads the page by restoring the original URL.
  114. *
  115. * @returns {Function}
  116. */
  117. export function reloadWithStoredParams() {
  118. return (dispatch: Dispatch<any>, getState: Function) => {
  119. const { locationURL } = getState()['features/base/connection'];
  120. const windowLocation = window.location;
  121. const oldSearchString = windowLocation.search;
  122. windowLocation.replace(locationURL.toString());
  123. if (window.self !== window.top
  124. && locationURL.search === oldSearchString) {
  125. // NOTE: Assuming that only the hash or search part of the URL will
  126. // be changed!
  127. // location.reload will not trigger redirect/reload for iframe when
  128. // only the hash params are changed. That's why we need to call
  129. // reload in addition to replace.
  130. windowLocation.reload();
  131. }
  132. };
  133. }