fix(rn,navigation) wait until the root navigator is initialized
There is a race condition in the root navigatior's initialization. It's possible that it's initialized a touch too late and SDK users who try to navigate to a conference end up stuck in the connecting screen because the navigator is null. This PR waits for it to be initilized by very unorthodox means, it's a horrible hack which we need to undo, but for that we need to break appart the inheritance relationship between App.{web,native}, AbstractApp and BaseApp because it's very inflexible. The flags are now initialized very early so the naviggator sees if the welcome page is enabled or not.
This commit is contained in:
parent
0c021868b5
commit
e6ce5fd75f
|
@ -28,11 +28,6 @@ declare var __DEV__;
|
|||
*/
|
||||
type Props = AbstractAppProps & {
|
||||
|
||||
/**
|
||||
* An object of colors that override the default colors of the app/sdk.
|
||||
*/
|
||||
colorScheme: ?Object,
|
||||
|
||||
/**
|
||||
* Identifier for this app on the native side.
|
||||
*/
|
||||
|
@ -100,13 +95,31 @@ export class App extends AbstractApp {
|
|||
*/
|
||||
async _extraInit() {
|
||||
const { dispatch, getState } = this.state.store;
|
||||
|
||||
// We set these early enough so then we avoid any unnecessary re-renders.
|
||||
dispatch(updateFlags(this.props.flags));
|
||||
|
||||
const route = await _getRouteToRender();
|
||||
|
||||
// We need the root navigator to be set early.
|
||||
await this._navigate(route);
|
||||
|
||||
// We set these early enough so then we avoid any unnecessary re-renders.
|
||||
dispatch(updateFlags(this.props.flags));
|
||||
// HACK ALERT!
|
||||
// Wait until the root navigator is ready.
|
||||
// We really need to break the inheritance relationship between App,
|
||||
// AbstractApp and BaseApp, it's very inflexible and cumbersome right now.
|
||||
const rootNavigationReady = new Promise(resolve => {
|
||||
const i = setInterval(() => {
|
||||
const { ready } = getState()['features/app'] || {};
|
||||
|
||||
if (ready) {
|
||||
clearInterval(i);
|
||||
resolve();
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
|
||||
await rootNavigationReady;
|
||||
|
||||
// Check if serverURL is configured externally and not allowed to change.
|
||||
const serverURLChangeEnabled = getFeatureFlag(getState(), SERVER_URL_CHANGE_ENABLED, true);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import { ReducerRegistry } from '../base/redux';
|
||||
import { _ROOT_NAVIGATION_READY } from '../mobile/navigation/actionTypes';
|
||||
|
||||
/**
|
||||
* Listen for actions which changes the state of the app feature.
|
||||
*
|
||||
* @param {Object} state - The Redux state of the feature features/app.
|
||||
* @param {Object} action - Action object.
|
||||
* @param {string} action.type - Type of action.
|
||||
* @returns {Object}
|
||||
*/
|
||||
ReducerRegistry.register('features/app', (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case _ROOT_NAVIGATION_READY:
|
||||
return {
|
||||
...state,
|
||||
ready: action.ready
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
});
|
|
@ -8,4 +8,6 @@ import '../mobile/full-screen/reducer';
|
|||
import '../mobile/watchos/reducer';
|
||||
import '../shared-video/reducer';
|
||||
|
||||
import './reducer.native';
|
||||
|
||||
import './reducers.any';
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export const _ROOT_NAVIGATION_READY = '_ROOT_NAVIGATION_READY';
|
|
@ -1,9 +1,10 @@
|
|||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createStackNavigator } from '@react-navigation/stack';
|
||||
import React from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import { connect } from '../../../base/redux';
|
||||
import { DialInSummary } from '../../../invite';
|
||||
import { _ROOT_NAVIGATION_READY } from '../actionTypes';
|
||||
import { rootNavigationRef } from '../rootNavigationContainerRef';
|
||||
import { screen } from '../routes';
|
||||
import {
|
||||
|
@ -23,6 +24,11 @@ const RootStack = createStackNavigator();
|
|||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Redux dispatch function.
|
||||
*/
|
||||
dispatch: Function,
|
||||
|
||||
/**
|
||||
* Is welcome page available?
|
||||
*/
|
||||
|
@ -30,13 +36,20 @@ type Props = {
|
|||
}
|
||||
|
||||
|
||||
const RootNavigationContainer = ({ isWelcomePageAvailable }: Props) => {
|
||||
const RootNavigationContainer = ({ dispatch, isWelcomePageAvailable }: Props) => {
|
||||
const initialRouteName = isWelcomePageAvailable
|
||||
? screen.root : screen.connecting;
|
||||
const onReady = useCallback(() => {
|
||||
dispatch({
|
||||
type: _ROOT_NAVIGATION_READY,
|
||||
ready: true
|
||||
});
|
||||
}, [ dispatch ]);
|
||||
|
||||
return (
|
||||
<NavigationContainer
|
||||
independent = { true }
|
||||
onReady = { onReady }
|
||||
ref = { rootNavigationRef }
|
||||
theme = { navigationContainerTheme }>
|
||||
<RootStack.Navigator
|
||||
|
@ -86,4 +99,3 @@ function mapStateToProps(state: Object) {
|
|||
}
|
||||
|
||||
export default connect(mapStateToProps)(RootNavigationContainer);
|
||||
|
||||
|
|
Loading…
Reference in New Issue