Merge pull request #2946 from jitsi/fix-app-props-typeerror
[Android] Fix possible TypeError in multi-JitsiMeetView SDK consumers
This commit is contained in:
commit
b797b0b201
|
@ -0,0 +1,28 @@
|
|||
// @flow
|
||||
|
||||
import { toState } from '../base/redux';
|
||||
|
||||
/**
|
||||
* Gets the value of a specific React {@code Component} prop of the currently
|
||||
* mounted {@link App}.
|
||||
*
|
||||
* @param {Function|Object} stateful - The redux store or {@code getState}
|
||||
* function.
|
||||
* @param {string} propName - The name of the React {@code Component} prop of
|
||||
* the currently mounted {@code App} to get.
|
||||
* @returns {*} The value of the specified React {@code Compoennt} prop of the
|
||||
* currently mounted {@code App}.
|
||||
*/
|
||||
export function getAppProp(stateful: Function | Object, propName: string) {
|
||||
const state = toState(stateful)['features/app'];
|
||||
|
||||
if (state) {
|
||||
const { app } = state;
|
||||
|
||||
if (app) {
|
||||
return app.props[propName];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import { NativeModules } from 'react-native';
|
||||
|
||||
export * from './functions.any';
|
||||
export * from './getRouteToRender';
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* @flow */
|
||||
// @flow
|
||||
|
||||
import { toState } from '../base/redux';
|
||||
import { getDeepLinkingPage } from '../deep-linking';
|
||||
|
@ -49,6 +49,8 @@ const _INTERCEPT_COMPONENT_RULES = [
|
|||
}
|
||||
];
|
||||
|
||||
export * from './functions.any';
|
||||
|
||||
/**
|
||||
* Determines which route is to be rendered in order to depict a specific redux
|
||||
* store.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import { getAppProp } from '../app';
|
||||
import { getLocalParticipant, PARTICIPANT_ROLE } from '../base/participants';
|
||||
import { doGetJSON } from '../base/util';
|
||||
|
||||
|
@ -282,8 +283,7 @@ export function isAddPeopleEnabled(state: Object): boolean {
|
|||
// XXX The mobile/react-native app is capable of disabling the
|
||||
// adding/inviting of people in the current conference. Anyway, the
|
||||
// Web/React app does not have that capability so default appropriately.
|
||||
const { app } = state['features/app'];
|
||||
const addPeopleEnabled = app && app.props.addPeopleEnabled;
|
||||
const addPeopleEnabled = getAppProp(state, 'addPeopleEnabled');
|
||||
|
||||
return (
|
||||
(typeof addPeopleEnabled === 'undefined')
|
||||
|
@ -313,9 +313,7 @@ export function isDialOutEnabled(state: Object): boolean {
|
|||
// XXX The mobile/react-native app is capable of disabling of dial-out.
|
||||
// Anyway, the Web/React app does not have that capability so default
|
||||
// appropriately.
|
||||
const { app } = state['features/app'];
|
||||
|
||||
dialOutEnabled = app && app.props.dialoOutEnabled;
|
||||
dialOutEnabled = getAppProp(state, 'dialOutEnabled');
|
||||
|
||||
return (
|
||||
(typeof dialOutEnabled === 'undefined') || Boolean(dialOutEnabled));
|
||||
|
|
|
@ -4,7 +4,7 @@ import i18next from 'i18next';
|
|||
import { NativeEventEmitter, NativeModules } from 'react-native';
|
||||
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app';
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT, getAppProp } from '../app';
|
||||
|
||||
import { invite } from './actions';
|
||||
import {
|
||||
|
@ -107,21 +107,15 @@ function _appWillMount({ dispatch, getState }, next, action) {
|
|||
* @private
|
||||
* @returns {*} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _beginAddPeople({ getState }, next, action) {
|
||||
function _beginAddPeople(store, next, action) {
|
||||
const result = next(action);
|
||||
|
||||
// The JavaScript App needs to provide uniquely identifying information to
|
||||
// the native Invite module so that the latter may match the former to the
|
||||
// native JitsiMeetView which hosts it.
|
||||
const { app } = getState()['features/app'];
|
||||
const externalAPIScope = getAppProp(store, 'externalAPIScope');
|
||||
|
||||
if (app) {
|
||||
const { externalAPIScope } = app.props;
|
||||
|
||||
if (externalAPIScope) {
|
||||
Invite.beginAddPeople(externalAPIScope);
|
||||
}
|
||||
}
|
||||
externalAPIScope && Invite.beginAddPeople(externalAPIScope);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -139,8 +133,7 @@ function _onInvite({ addPeopleControllerScope, externalAPIScope, invitees }) {
|
|||
// If there are multiple JitsiMeetView instances alive, they will all get
|
||||
// the event, since there is a single bridge, so make sure we don't act if
|
||||
// the event is not for us.
|
||||
if (getState()['features/app'].app.props.externalAPIScope
|
||||
!== externalAPIScope) {
|
||||
if (getAppProp(getState, 'externalAPIScope') !== externalAPIScope) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -167,7 +160,7 @@ function _onPerformQuery(
|
|||
// If there are multiple JitsiMeetView instances alive, they will all get
|
||||
// the event, since there is a single bridge, so make sure we don't act if
|
||||
// the event is not for us.
|
||||
if (state['features/app'].app.props.externalAPIScope !== externalAPIScope) {
|
||||
if (getAppProp(state, 'externalAPIScope') !== externalAPIScope) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/* @flow */
|
||||
// @flow
|
||||
|
||||
import { NativeModules } from 'react-native';
|
||||
|
||||
import { getAppProp } from '../../app';
|
||||
import {
|
||||
CONFERENCE_FAILED,
|
||||
CONFERENCE_JOINED,
|
||||
|
@ -215,22 +216,14 @@ function _sendConferenceFailedOnConnectionError(store, action) {
|
|||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _sendEvent(
|
||||
{ getState }: { getState: Function },
|
||||
name: string,
|
||||
data: Object) {
|
||||
function _sendEvent(store: Object, name: string, data: Object) {
|
||||
// The JavaScript App needs to provide uniquely identifying information to
|
||||
// the native ExternalAPI module so that the latter may match the former to
|
||||
// the native JitsiMeetView which hosts it.
|
||||
const { app } = getState()['features/app'];
|
||||
const externalAPIScope = getAppProp(store, 'externalAPIScope');
|
||||
|
||||
if (app) {
|
||||
const { externalAPIScope } = app.props;
|
||||
|
||||
if (externalAPIScope) {
|
||||
NativeModules.ExternalAPI.sendEvent(name, data, externalAPIScope);
|
||||
}
|
||||
}
|
||||
externalAPIScope
|
||||
&& NativeModules.ExternalAPI.sendEvent(name, data, externalAPIScope);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import { NativeModules } from 'react-native';
|
||||
|
||||
import { getAppProp } from '../../app';
|
||||
import { Platform } from '../../base/react';
|
||||
|
||||
import { ENTER_PICTURE_IN_PICTURE } from './actionTypes';
|
||||
|
@ -18,13 +19,10 @@ import { ENTER_PICTURE_IN_PICTURE } from './actionTypes';
|
|||
*/
|
||||
export function enterPictureInPicture() {
|
||||
return (dispatch: Dispatch, getState: Function) => {
|
||||
const state = getState();
|
||||
const { app } = state['features/app'];
|
||||
|
||||
// XXX At the time of this writing this action can only be dispatched by
|
||||
// the button which is on the conference view, which means that it's
|
||||
// fine to enter PiP mode.
|
||||
if (app && app.props.pictureInPictureEnabled) {
|
||||
if (getAppProp(getState, 'pictureInPictureEnabled')) {
|
||||
const { PictureInPicture } = NativeModules;
|
||||
const p
|
||||
= Platform.OS === 'android'
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { getAppProp } from '../../../app';
|
||||
import { ToolbarButton } from '../../../toolbox';
|
||||
|
||||
import { enterPictureInPicture } from '../actions';
|
||||
|
@ -93,8 +94,6 @@ function _mapDispatchToProps(dispatch) {
|
|||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
const { app } = state['features/app'];
|
||||
|
||||
return {
|
||||
|
||||
/**
|
||||
|
@ -104,7 +103,7 @@ function _mapStateToProps(state) {
|
|||
* @type {boolean}
|
||||
*/
|
||||
_pictureInPictureEnabled:
|
||||
Boolean(app && app.props.pictureInPictureEnabled)
|
||||
Boolean(getAppProp(state, 'pictureInPictureEnabled'))
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* @flow */
|
||||
// @flow
|
||||
|
||||
import { getAppProp } from '../app';
|
||||
import { toState } from '../base/redux';
|
||||
|
||||
declare var APP: Object;
|
||||
|
@ -12,12 +13,12 @@ export * from './roomnameGenerator';
|
|||
* (e.g. programmatically via the Jitsi Meet SDK for Android and iOS). Not to be
|
||||
* confused with {@link isWelcomePageUserEnabled}.
|
||||
*
|
||||
* @param {Object|Function} stateOrGetState - The redux state or
|
||||
* {@link getState} function.
|
||||
* @param {Function|Object} stateful - The redux state or {@link getState}
|
||||
* function.
|
||||
* @returns {boolean} If the {@code WelcomePage} is enabled by the app, then
|
||||
* {@code true}; otherwise, {@code false}.
|
||||
*/
|
||||
export function isWelcomePageAppEnabled(stateOrGetState: Object | Function) {
|
||||
export function isWelcomePageAppEnabled(stateful: Function | Object) {
|
||||
let b;
|
||||
|
||||
if (navigator.product === 'ReactNative') {
|
||||
|
@ -28,9 +29,7 @@ export function isWelcomePageAppEnabled(stateOrGetState: Object | Function) {
|
|||
// - Enabling/disabling the Welcome page on Web historically
|
||||
// automatically redirects to a random room and that does not make sense
|
||||
// on mobile (right now).
|
||||
const { app } = toState(stateOrGetState)['features/app'];
|
||||
|
||||
b = Boolean(app && app.props.welcomePageEnabled);
|
||||
b = Boolean(getAppProp(stateful, 'welcomePageEnabled'));
|
||||
} else {
|
||||
b = true;
|
||||
}
|
||||
|
@ -43,15 +42,14 @@ export function isWelcomePageAppEnabled(stateOrGetState: Object | Function) {
|
|||
* herself or through her deployment config(uration). Not to be confused with
|
||||
* {@link isWelcomePageAppEnabled}.
|
||||
*
|
||||
* @param {Object|Function} stateOrGetState - The redux state or
|
||||
* {@link getState} function.
|
||||
* @param {Function|Object} stateful - The redux state or {@link getState}
|
||||
* function.
|
||||
* @returns {boolean} If the {@code WelcomePage} is enabled by the user, then
|
||||
* {@code true}; otherwise, {@code false}.
|
||||
*/
|
||||
export function isWelcomePageUserEnabled(stateOrGetState: Object | Function) {
|
||||
export function isWelcomePageUserEnabled(stateful: Function | Object) {
|
||||
return (
|
||||
typeof APP === 'undefined'
|
||||
? true
|
||||
: toState(stateOrGetState)['features/base/config']
|
||||
.enableWelcomePage);
|
||||
: toState(stateful)['features/base/config'].enableWelcomePage);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue