Replace features/unsupported-browser SET_UNSUPPORTED_BROWSER with features/base/lib-jitsi-meet SET_WEBRTC_READY
The error raised by JitsiMeetJS.init() is already in the state of features/base/lib-jitsi-meet so it's not a good design to store the same error in the state of features/unsupported-browser.
This commit is contained in:
parent
a8877d82b6
commit
0ed85b9d25
|
@ -2,15 +2,17 @@
|
|||
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { JitsiConferenceEvents } from '../lib-jitsi-meet';
|
||||
import {
|
||||
JitsiConferenceEvents,
|
||||
libInitError,
|
||||
WEBRTC_NOT_READY,
|
||||
WEBRTC_NOT_SUPPORTED
|
||||
} from '../lib-jitsi-meet';
|
||||
|
||||
import UIEvents from '../../../../service/UI/UIEvents';
|
||||
|
||||
import { SET_DOMAIN } from './actionTypes';
|
||||
|
||||
import { appNavigate } from '../../app';
|
||||
import { setUnsupportedBrowser } from '../../unsupported-browser';
|
||||
|
||||
declare var APP: Object;
|
||||
declare var config: Object;
|
||||
|
||||
|
@ -77,28 +79,19 @@ export function connect() {
|
|||
APP.UI.promptDisplayName();
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
.catch(error => {
|
||||
APP.UI.hideRingOverLay();
|
||||
APP.API.notifyConferenceLeft(APP.conference.roomName);
|
||||
logger.error(err);
|
||||
logger.error(error);
|
||||
|
||||
dispatch(setUnsupportedBrowser(err));
|
||||
|
||||
// If during the conference initialization was defined that
|
||||
// browser doesn't support WebRTC then we should define
|
||||
// which route to render.
|
||||
dispatch(appNavigate(room));
|
||||
|
||||
// Force reinitialization of the conference if WebRTC is ready.
|
||||
if (err.webRTCReadyPromise) {
|
||||
err.webRTCReadyPromise.then(() => {
|
||||
// Setting plugin required flag to false because
|
||||
// it's already been installed.
|
||||
dispatch(setUnsupportedBrowser({
|
||||
name: 'OK'
|
||||
}));
|
||||
dispatch(appNavigate(room));
|
||||
});
|
||||
// TODO The following are in fact Errors raised by
|
||||
// JitsiMeetJS.init() which should be taken care of in
|
||||
// features/base/lib-jitsi-meet but we are not there yet on the
|
||||
// Web at the time of this writing.
|
||||
switch (error.name) {
|
||||
case WEBRTC_NOT_READY:
|
||||
case WEBRTC_NOT_SUPPORTED:
|
||||
dispatch(libInitError(error));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -58,3 +58,13 @@ export const LIB_WILL_INIT = Symbol('LIB_WILL_INIT');
|
|||
* }
|
||||
*/
|
||||
export const SET_CONFIG = Symbol('SET_CONFIG');
|
||||
|
||||
/**
|
||||
* The type of Redux action which indicates whether WebRTC is ready.
|
||||
*
|
||||
* {
|
||||
* type: SET_WEBRTC_READY,
|
||||
* webRTCReady: boolean | Promise
|
||||
* }
|
||||
*/
|
||||
export const SET_WEBRTC_READY = Symbol('SET_WEBRTC_READY');
|
||||
|
|
|
@ -7,7 +7,8 @@ import {
|
|||
LIB_INIT_ERROR,
|
||||
LIB_WILL_DISPOSE,
|
||||
LIB_WILL_INIT,
|
||||
SET_CONFIG
|
||||
SET_CONFIG,
|
||||
SET_WEBRTC_READY
|
||||
} from './actionTypes';
|
||||
|
||||
declare var APP: Object;
|
||||
|
@ -100,3 +101,54 @@ export function setConfig(config: Object) {
|
|||
config
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the indicator which determines whether WebRTC is ready. In execution
|
||||
* environments in which WebRTC is supported via a known plugin such
|
||||
* as Temasys WebRTC may start not ready and then become ready. Of course, there
|
||||
* are execution enviroments such as old Mozilla Firefox versions or
|
||||
* certains Microsoft Edge versions in which WebRTC is not supported at all.
|
||||
*
|
||||
* @param {boolean|Promise} webRTCReady - The indicator which determines
|
||||
* whether WebRTC is ready. If a Promise is specified, its resolution will be
|
||||
* awaited.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function setWebRTCReady(webRTCReady: boolean | Promise<*>) {
|
||||
return (dispatch: Dispatch<*>, getState: Function) => {
|
||||
if (getState()['features/base/lib-jitsi-meet'].webRTCReady
|
||||
!== webRTCReady) {
|
||||
dispatch({
|
||||
type: SET_WEBRTC_READY,
|
||||
webRTCReady
|
||||
});
|
||||
|
||||
// If the specified webRTCReady is a thenable (i.e. a Promise), then
|
||||
// await its resolution.
|
||||
switch (typeof webRTCReady) {
|
||||
case 'function':
|
||||
case 'object': {
|
||||
const { then } = webRTCReady;
|
||||
|
||||
if (typeof then === 'function') {
|
||||
const onFulfilled = value => {
|
||||
// Is the app still interested in the specified
|
||||
// webRTCReady?
|
||||
if (getState()['features/base/lib-jitsi-meet']
|
||||
.webRTCReady
|
||||
=== webRTCReady) {
|
||||
dispatch(setWebRTCReady(value));
|
||||
}
|
||||
};
|
||||
|
||||
then.call(
|
||||
webRTCReady,
|
||||
/* onFulfilled */ () => onFulfilled(true),
|
||||
/* onRejected*/ () => onFulfilled(false));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* The name of the Error thrown by {@link JitsiMeetJS.init()} which indicates
|
||||
* that WebRTC is not ready and its readiness may be tracked via the
|
||||
* webRTCReadyPromise property value of the Error.
|
||||
*/
|
||||
export const WEBRTC_NOT_READY = 'WEBRTC_NOT_READY';
|
||||
|
||||
/**
|
||||
* The name of the Error thrown by {@link JitsiMeetJS.init()} which indicates
|
||||
* that WebRTC is not supported by the execution environment either natively or
|
||||
* via a known plugin such as Temasys.
|
||||
*/
|
||||
export const WEBRTC_NOT_SUPPORTED = 'WEBRTC_NOT_SUPPORTED';
|
|
@ -15,6 +15,7 @@ export const JitsiTrackEvents = JitsiMeetJS.events.track;
|
|||
|
||||
export * from './actions';
|
||||
export * from './actionTypes';
|
||||
export * from './constants';
|
||||
export * from './functions';
|
||||
|
||||
import './middleware';
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { PARTICIPANT_LEFT } from '../participants';
|
||||
import { MiddlewareRegistry } from '../redux';
|
||||
|
||||
import { disposeLib, initLib } from './actions';
|
||||
import { SET_CONFIG } from './actionTypes';
|
||||
import { disposeLib, initLib, setWebRTCReady } from './actions';
|
||||
import { LIB_DID_INIT, LIB_INIT_ERROR, SET_CONFIG } from './actionTypes';
|
||||
import { WEBRTC_NOT_READY, WEBRTC_NOT_SUPPORTED } from './constants';
|
||||
|
||||
/**
|
||||
* Middleware that captures PARTICIPANT_LEFT action for a local participant
|
||||
|
@ -16,6 +17,13 @@ import { SET_CONFIG } from './actionTypes';
|
|||
*/
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
switch (action.type) {
|
||||
case LIB_DID_INIT:
|
||||
store.dispatch(setWebRTCReady(true));
|
||||
break;
|
||||
|
||||
case LIB_INIT_ERROR:
|
||||
return _libInitError(store, next, action);
|
||||
|
||||
case PARTICIPANT_LEFT:
|
||||
action.participant.local && store.dispatch(disposeLib());
|
||||
break;
|
||||
|
@ -27,6 +35,44 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
return next(action);
|
||||
});
|
||||
|
||||
/**
|
||||
* Notifies the feature base/lib-jitsi-meet that the action LIB_INIT_ERROR 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 LIB_INIT_ERROR which is being
|
||||
* dispatched in the specified store.
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified action.
|
||||
* @private
|
||||
*/
|
||||
function _libInitError(store, next, action) {
|
||||
const nextState = next(action);
|
||||
|
||||
const error = action.error;
|
||||
|
||||
if (error) {
|
||||
let webRTCReady;
|
||||
|
||||
switch (error.name) {
|
||||
case WEBRTC_NOT_READY:
|
||||
webRTCReady = error.webRTCReadyPromise;
|
||||
break;
|
||||
|
||||
case WEBRTC_NOT_SUPPORTED:
|
||||
webRTCReady = false;
|
||||
break;
|
||||
}
|
||||
typeof webRTCReady === 'undefined'
|
||||
|| store.dispatch(setWebRTCReady(webRTCReady));
|
||||
}
|
||||
|
||||
return nextState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the feature base/lib-jitsi-meet that the action SET_CONFIG is being
|
||||
* dispatched within a specific Redux store.
|
||||
|
|
|
@ -4,7 +4,8 @@ import {
|
|||
LIB_DID_DISPOSE,
|
||||
LIB_DID_INIT,
|
||||
LIB_INIT_ERROR,
|
||||
SET_CONFIG
|
||||
SET_CONFIG,
|
||||
SET_WEBRTC_READY
|
||||
} from './actionTypes';
|
||||
|
||||
/**
|
||||
|
@ -66,6 +67,12 @@ ReducerRegistry.register(
|
|||
case SET_CONFIG:
|
||||
return _setConfig(state, action);
|
||||
|
||||
case SET_WEBRTC_READY:
|
||||
return {
|
||||
...state,
|
||||
webRTCReady: action.webRTCReady
|
||||
};
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ if (userAgent.match(/Android/i)) {
|
|||
OS = 'android';
|
||||
} else if (userAgent.match(/iP(ad|hone|od)/i)) {
|
||||
OS = 'ios';
|
||||
} else if (userAgent.match(/windows/i)) {
|
||||
} else if (userAgent.match(/Mac(intosh| OS X)/i)) {
|
||||
OS = 'macos';
|
||||
} else if (userAgent.match(/Windows/i)) {
|
||||
OS = 'windows';
|
||||
} else if (userAgent.match(/mac/i)) {
|
||||
OS = 'mac';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -44,12 +44,22 @@ const _RULES = [
|
|||
}
|
||||
},
|
||||
state => {
|
||||
switch (state['features/unsupported-browser'].name) {
|
||||
case 'WEBRTC_NOT_READY':
|
||||
return PluginRequiredBrowser;
|
||||
const { webRTCReady } = state['features/base/lib-jitsi-meet'];
|
||||
|
||||
case 'WEBRTC_NOT_SUPPORTED':
|
||||
return UnsupportedDesktopBrowser;
|
||||
switch (typeof webRTCReady) {
|
||||
case 'boolean':
|
||||
if (webRTCReady === false) {
|
||||
return UnsupportedDesktopBrowser;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'undefined':
|
||||
// If webRTCReady is not set, then we cannot use it to take a
|
||||
// decision.
|
||||
break;
|
||||
|
||||
default:
|
||||
return PluginRequiredBrowser;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
|
@ -16,14 +16,3 @@ import { Symbol } from '../base/react';
|
|||
* }
|
||||
*/
|
||||
export const DISMISS_MOBILE_APP_PROMO = Symbol('DISMISS_MOBILE_APP_PROMO');
|
||||
|
||||
/**
|
||||
* The type of Redux action which signals to change information about
|
||||
* unsupported browser in Redux store.
|
||||
*
|
||||
* {
|
||||
* type: SET_UNSUPPORTED_BROWSER,
|
||||
* unsupportedBrowser: Object
|
||||
* }
|
||||
*/
|
||||
export const SET_UNSUPPORTED_BROWSER = Symbol('SET_UNSUPPORTED_BROWSER');
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import {
|
||||
DISMISS_MOBILE_APP_PROMO,
|
||||
SET_UNSUPPORTED_BROWSER
|
||||
} from './actionTypes';
|
||||
import { DISMISS_MOBILE_APP_PROMO } from './actionTypes';
|
||||
|
||||
/**
|
||||
* Returns a Redux action which signals that the UnsupportedMobileBrowser which
|
||||
|
@ -22,20 +19,3 @@ export function dismissMobileAppPromo() {
|
|||
type: DISMISS_MOBILE_APP_PROMO
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets unsupported browser object.
|
||||
*
|
||||
* @param {Object} unsupportedBrowser - Object describing the unsupported
|
||||
* browser.
|
||||
* @returns {{
|
||||
* type: SET_UNSUPPORTED_BROWSER,
|
||||
* unsupportedBrowser: Object
|
||||
* }}
|
||||
*/
|
||||
export function setUnsupportedBrowser(unsupportedBrowser) {
|
||||
return {
|
||||
type: SET_UNSUPPORTED_BROWSER,
|
||||
unsupportedBrowser
|
||||
};
|
||||
}
|
||||
|
|
|
@ -39,8 +39,9 @@ export default class UnsupportedDesktopBrowser extends Component {
|
|||
<a
|
||||
className = { `${NS}__link` }
|
||||
href = { FIREFOX }>Firefox</a> or
|
||||
{ this._showSafariLinkIfRequired() }
|
||||
{ this._showIELinkIfRequired() }.
|
||||
{
|
||||
this._renderOSSpecificBrowserDownloadLink()
|
||||
}
|
||||
</p>
|
||||
|
||||
<HideNotificationBarStyle />
|
||||
|
@ -48,36 +49,36 @@ export default class UnsupportedDesktopBrowser extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on the platform returns the link to IE browser.
|
||||
*
|
||||
* @returns {ReactElement|null}
|
||||
* @private
|
||||
*/
|
||||
_showIELinkIfRequired() {
|
||||
if (Platform.OS === 'windows') {
|
||||
return (
|
||||
<a
|
||||
className = { `${NS}__link` }
|
||||
href = { IE }>IE</a>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on the platform returns the link to Safari browser.
|
||||
*
|
||||
* @returns {ReactElement|null}
|
||||
* @private
|
||||
*/
|
||||
_showSafariLinkIfRequired() {
|
||||
if (Platform.OS === 'mac') {
|
||||
_renderOSSpecificBrowserDownloadLink() {
|
||||
let link;
|
||||
let text;
|
||||
|
||||
switch (Platform.OS) {
|
||||
case 'macos':
|
||||
link = SAFARI;
|
||||
text = 'Safari';
|
||||
break;
|
||||
|
||||
case 'windows':
|
||||
link = IE;
|
||||
text = 'Internet Explorer';
|
||||
break;
|
||||
}
|
||||
if (typeof link !== 'undefined') {
|
||||
return (
|
||||
<a
|
||||
className = { `${NS}__link` }
|
||||
href = { SAFARI }>Safari</a>
|
||||
href = { link }>
|
||||
{
|
||||
text
|
||||
}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export * from './actions';
|
||||
export * from './components';
|
||||
|
||||
import './middleware';
|
||||
import './reducer';
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
import { appNavigate } from '../app';
|
||||
import { SET_WEBRTC_READY } from '../base/lib-jitsi-meet';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
|
||||
/**
|
||||
* Middleware that dispatches appNavigate when WebRTC readiness changes.
|
||||
*
|
||||
* @param {Store} store - The Redux store.
|
||||
* @returns {Function}
|
||||
* @private
|
||||
*/
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
switch (action.type) {
|
||||
case SET_WEBRTC_READY:
|
||||
return _setWebRTCReady(store, next, action);
|
||||
}
|
||||
|
||||
return next(action);
|
||||
});
|
||||
|
||||
/**
|
||||
* Notifies the feature unsupported-browser that the action SET_WEBRTC_READY 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_WEBRTC_READY which is being
|
||||
* dispatched in the specified store.
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified action.
|
||||
* @private
|
||||
*/
|
||||
function _setWebRTCReady(store, next, action) {
|
||||
const nextState = next(action);
|
||||
|
||||
// FIXME The feature unsupported-browser needs to notify the app that it may
|
||||
// need to render a different Component at its current location because the
|
||||
// execution enviroment has changed. The current location is not necessarily
|
||||
// available through window.location (e.g. on mobile) but the following
|
||||
// works at the time of this writing.
|
||||
const windowLocation = window.location;
|
||||
|
||||
if (windowLocation) {
|
||||
const href = windowLocation.href;
|
||||
|
||||
href && store.dispatch(appNavigate(href));
|
||||
}
|
||||
|
||||
return nextState;
|
||||
}
|
|
@ -1,9 +1,6 @@
|
|||
import { ReducerRegistry } from '../base/redux';
|
||||
|
||||
import {
|
||||
DISMISS_MOBILE_APP_PROMO,
|
||||
SET_UNSUPPORTED_BROWSER
|
||||
} from './actionTypes';
|
||||
import { DISMISS_MOBILE_APP_PROMO } from './actionTypes';
|
||||
|
||||
ReducerRegistry.register(
|
||||
'features/unsupported-browser',
|
||||
|
@ -24,11 +21,6 @@ ReducerRegistry.register(
|
|||
*/
|
||||
mobileAppPromoDismissed: true
|
||||
};
|
||||
case SET_UNSUPPORTED_BROWSER:
|
||||
return {
|
||||
...state,
|
||||
...action.unsupportedBrowser
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
Loading…
Reference in New Issue