2022-09-23 09:03:25 +00:00
|
|
|
import { AnyAction } from 'redux';
|
2016-10-05 14:36:59 +00:00
|
|
|
|
2022-09-23 09:03:25 +00:00
|
|
|
import { IStore } from '../../app/types';
|
|
|
|
import { SET_CONFIG } from '../config/actionTypes';
|
|
|
|
import { SET_NETWORK_INFO } from '../net-info/actionTypes';
|
|
|
|
import { PARTICIPANT_LEFT } from '../participants/actionTypes';
|
|
|
|
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
|
|
|
|
|
|
|
// @ts-ignore
|
2018-04-16 12:44:08 +00:00
|
|
|
import JitsiMeetJS from './_';
|
core: refactor routing
Unfortunately, as the Jitsi Meet development evolved the routing mechanism
became more complex and thre logic ended up spread across multiple parts of the
codebase, which made it hard to follow and extend.
This change aims to fix that by rewriting the routing logic and centralizing it
in (pretty much) a single place, with no implicit inter-dependencies.
In order to arrive there, however, some extra changes were needed, which were
not caught early enough and are thus part of this change:
- JitsiMeetJS initialization is now synchronous: there is nothing async about
it, and the only async requirement (Temasys support) was lifted. See [0].
- WebRTC support can be detected early: building on top of the above, WebRTC
support can now be detected immediately, so take advantage of this to simplify
how we handle unsupported browsers. See [0].
The new router takes decissions based on the Redux state at the time of
invocation. A route can be represented by either a component or a URl reference,
with the latter taking precedence. On mobile, obviously, there is no concept of
URL reference so routing is based solely on components.
[0]: https://github.com/jitsi/lib-jitsi-meet/pull/779
2018-06-29 07:58:31 +00:00
|
|
|
import { LIB_WILL_INIT } from './actionTypes';
|
2020-05-20 10:57:03 +00:00
|
|
|
import { disposeLib, initLib } from './actions';
|
2016-10-05 14:36:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Middleware that captures PARTICIPANT_LEFT action for a local participant
|
|
|
|
* (which signalizes that we finally left the app) and disposes lib-jitsi-meet.
|
|
|
|
* Also captures SET_CONFIG action and disposes previous instance (if any) of
|
|
|
|
* lib-jitsi-meet, and initializes a new one with new config.
|
|
|
|
*
|
|
|
|
* @param {Store} store - Redux store.
|
2017-02-27 22:45:53 +00:00
|
|
|
* @private
|
2017-04-22 22:57:08 +00:00
|
|
|
* @returns {Function}
|
2016-10-05 14:36:59 +00:00
|
|
|
*/
|
|
|
|
MiddlewareRegistry.register(store => next => action => {
|
|
|
|
switch (action.type) {
|
2018-04-16 12:44:08 +00:00
|
|
|
case LIB_WILL_INIT:
|
|
|
|
// Moved from conference.js init method. It appears the error handlers
|
|
|
|
// are not used for mobile.
|
|
|
|
if (typeof APP !== 'undefined') {
|
|
|
|
_setErrorHandlers();
|
|
|
|
}
|
|
|
|
break;
|
2017-02-28 03:22:32 +00:00
|
|
|
|
2020-03-30 13:50:26 +00:00
|
|
|
case SET_NETWORK_INFO:
|
|
|
|
JitsiMeetJS.setNetworkInfo({
|
|
|
|
isOnline: action.isOnline
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
|
2016-10-05 14:36:59 +00:00
|
|
|
case PARTICIPANT_LEFT:
|
2016-10-25 16:43:15 +00:00
|
|
|
action.participant.local && store.dispatch(disposeLib());
|
2016-10-05 14:36:59 +00:00
|
|
|
break;
|
|
|
|
|
2017-02-16 19:51:01 +00:00
|
|
|
case SET_CONFIG:
|
|
|
|
return _setConfig(store, next, action);
|
2016-10-05 14:36:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return next(action);
|
|
|
|
});
|
2017-02-16 19:51:01 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Notifies the feature base/lib-jitsi-meet that the action SET_CONFIG is being
|
|
|
|
* dispatched within a specific Redux store.
|
|
|
|
*
|
|
|
|
* @param {Store} store - The Redux store in which the specified action is being
|
|
|
|
* dispatched.
|
|
|
|
* @param {Dispatch} next - The Redux dispatch function to dispatch the
|
|
|
|
* specified action to the specified store.
|
|
|
|
* @param {Action} action - The Redux action SET_CONFIG which is being
|
|
|
|
* dispatched in the specified store.
|
2017-04-22 22:57:08 +00:00
|
|
|
* @private
|
2017-02-16 19:51:01 +00:00
|
|
|
* @returns {Object} The new state that is the result of the reduction of the
|
|
|
|
* specified action.
|
|
|
|
*/
|
2022-09-23 09:03:25 +00:00
|
|
|
function _setConfig({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
2017-02-16 19:51:01 +00:00
|
|
|
const { initialized } = getState()['features/base/lib-jitsi-meet'];
|
|
|
|
|
|
|
|
// XXX Since the config is changing, the library lib-jitsi-meet must be
|
2017-04-22 22:57:08 +00:00
|
|
|
// initialized again with the new config. Consequently, it may need to be
|
2017-02-16 19:51:01 +00:00
|
|
|
// disposed of first.
|
|
|
|
// TODO Currently, disposeLib actually does not dispose of lib-jitsi-meet
|
|
|
|
// because lib-jitsi-meet does not implement such functionality.
|
2017-05-17 21:44:28 +00:00
|
|
|
if (initialized) {
|
|
|
|
dispatch(disposeLib());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Let the new config into the Redux store (because initLib will read it
|
|
|
|
// from there).
|
|
|
|
const result = next(action);
|
|
|
|
|
|
|
|
dispatch(initLib());
|
|
|
|
|
|
|
|
return result;
|
2017-02-16 19:51:01 +00:00
|
|
|
}
|
2018-04-16 12:44:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Attaches our custom error handlers to the window object.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
function _setErrorHandlers() {
|
|
|
|
// attaches global error handler, if there is already one, respect it
|
|
|
|
if (JitsiMeetJS.getGlobalOnErrorHandler) {
|
|
|
|
const oldOnErrorHandler = window.onerror;
|
|
|
|
|
2022-09-30 20:04:41 +00:00
|
|
|
// TODO: Don't remove this ignore. The build fails on macOS and we don't know yet why.
|
|
|
|
|
|
|
|
// @ts-ignore
|
2022-09-26 14:13:22 +00:00
|
|
|
window.onerror = (message, source, lineno, colno, error) => { // eslint-disable-line max-params
|
2022-09-23 09:03:25 +00:00
|
|
|
const errMsg = message || error?.message;
|
|
|
|
const stack = error?.stack;
|
2020-10-27 03:57:23 +00:00
|
|
|
|
|
|
|
JitsiMeetJS.getGlobalOnErrorHandler(errMsg, source, lineno, colno, stack);
|
2018-04-16 12:44:08 +00:00
|
|
|
|
|
|
|
if (oldOnErrorHandler) {
|
|
|
|
oldOnErrorHandler(message, source, lineno, colno, error);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const oldOnUnhandledRejection = window.onunhandledrejection;
|
|
|
|
|
|
|
|
window.onunhandledrejection = function(event) {
|
2020-10-27 03:57:23 +00:00
|
|
|
let message = event.reason;
|
2022-09-23 09:03:25 +00:00
|
|
|
let stack: string | undefined = 'n/a';
|
2020-10-27 03:57:23 +00:00
|
|
|
|
|
|
|
if (event.reason instanceof Error) {
|
|
|
|
({ message, stack } = event.reason);
|
|
|
|
}
|
|
|
|
|
|
|
|
JitsiMeetJS.getGlobalOnErrorHandler(message, null, null, null, stack);
|
2018-04-16 12:44:08 +00:00
|
|
|
|
|
|
|
if (oldOnUnhandledRejection) {
|
2022-09-23 09:03:25 +00:00
|
|
|
// @ts-ignore
|
2018-04-16 12:44:08 +00:00
|
|
|
oldOnUnhandledRejection(event);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|