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.

middleware.web.js 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // @flow
  2. import { maybeRedirectToWelcomePage } from '../app/actions';
  3. import {
  4. CONFERENCE_FAILED,
  5. CONFERENCE_JOINED,
  6. CONFERENCE_LEFT
  7. } from '../base/conference';
  8. import { CONNECTION_ESTABLISHED } from '../base/connection';
  9. import { hideDialog, isDialogOpen } from '../base/dialog';
  10. import {
  11. JitsiConferenceErrors
  12. } from '../base/lib-jitsi-meet';
  13. import { MiddlewareRegistry } from '../base/redux';
  14. import {
  15. CANCEL_LOGIN,
  16. STOP_WAIT_FOR_OWNER,
  17. UPGRADE_ROLE_FINISHED,
  18. WAIT_FOR_OWNER
  19. } from './actionTypes';
  20. import {
  21. hideLoginDialog,
  22. openWaitForOwnerDialog,
  23. stopWaitForOwner,
  24. waitForOwner
  25. } from './actions.web';
  26. import { LoginDialog, WaitForOwnerDialog } from './components';
  27. /**
  28. * Middleware that captures connection or conference failed errors and controls
  29. * {@link WaitForOwnerDialog} and {@link LoginDialog}.
  30. *
  31. * FIXME Some of the complexity was introduced by the lack of dialog stacking.
  32. *
  33. * @param {Store} store - Redux store.
  34. * @returns {Function}
  35. */
  36. MiddlewareRegistry.register(store => next => action => {
  37. switch (action.type) {
  38. case CANCEL_LOGIN: {
  39. const { dispatch, getState } = store;
  40. if (!isDialogOpen(store, WaitForOwnerDialog)) {
  41. if (_isWaitingForOwner(store)) {
  42. dispatch(openWaitForOwnerDialog());
  43. return next(action);
  44. }
  45. dispatch(hideLoginDialog());
  46. const { authRequired, conference } = getState()['features/base/conference'];
  47. // Only end the meeting if we are not already inside and trying to upgrade.
  48. if (authRequired && !conference) {
  49. dispatch(maybeRedirectToWelcomePage());
  50. }
  51. }
  52. break;
  53. }
  54. case CONFERENCE_FAILED: {
  55. const { error } = action;
  56. let recoverable;
  57. if (error.name === JitsiConferenceErrors.AUTHENTICATION_REQUIRED) {
  58. if (typeof error.recoverable === 'undefined') {
  59. error.recoverable = true;
  60. }
  61. recoverable = error.recoverable;
  62. }
  63. if (recoverable) {
  64. store.dispatch(waitForOwner());
  65. } else {
  66. store.dispatch(stopWaitForOwner());
  67. }
  68. break;
  69. }
  70. case CONFERENCE_JOINED:
  71. if (_isWaitingForOwner(store)) {
  72. store.dispatch(stopWaitForOwner());
  73. }
  74. store.dispatch(hideLoginDialog());
  75. break;
  76. case CONFERENCE_LEFT:
  77. store.dispatch(stopWaitForOwner());
  78. break;
  79. case CONNECTION_ESTABLISHED:
  80. store.dispatch(hideLoginDialog());
  81. break;
  82. case STOP_WAIT_FOR_OWNER:
  83. _clearExistingWaitForOwnerTimeout(store);
  84. store.dispatch(hideDialog(WaitForOwnerDialog));
  85. break;
  86. case UPGRADE_ROLE_FINISHED: {
  87. const { error, progress } = action;
  88. if (!error && progress === 1) {
  89. store.dispatch(hideLoginDialog());
  90. }
  91. break;
  92. }
  93. case WAIT_FOR_OWNER: {
  94. _clearExistingWaitForOwnerTimeout(store);
  95. const { handler, timeoutMs } = action;
  96. action.waitForOwnerTimeoutID = setTimeout(handler, timeoutMs);
  97. isDialogOpen(store, LoginDialog)
  98. || store.dispatch(openWaitForOwnerDialog());
  99. break;
  100. }
  101. }
  102. return next(action);
  103. });
  104. /**
  105. * Will clear the wait for conference owner timeout handler if any is currently
  106. * set.
  107. *
  108. * @param {Object} store - The redux store.
  109. * @returns {void}
  110. */
  111. function _clearExistingWaitForOwnerTimeout(
  112. { getState }: { getState: Function }) {
  113. const { waitForOwnerTimeoutID } = getState()['features/authentication'];
  114. waitForOwnerTimeoutID && clearTimeout(waitForOwnerTimeoutID);
  115. }
  116. /**
  117. * Checks if the cyclic "wait for conference owner" task is currently scheduled.
  118. *
  119. * @param {Object} store - The redux store.
  120. * @returns {void}
  121. */
  122. function _isWaitingForOwner({ getState }: { getState: Function }) {
  123. return getState()['features/authentication'].waitForOwnerTimeoutID;
  124. }