fix(rn, web) await initialisation before dispatching appWillMount

This commit is contained in:
tmoldovan8x8 2022-01-07 15:18:24 +02:00 committed by GitHub
parent 8de024a699
commit 307e253276
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 114 additions and 95 deletions

View File

@ -38,14 +38,12 @@ export class AbstractApp extends BaseApp<Props, *> {
* *
* @inheritdoc * @inheritdoc
*/ */
componentDidMount() { async componentDidMount() {
super.componentDidMount(); await super.componentDidMount();
this._init.then(() => {
// If a URL was explicitly specified to this React Component, then // If a URL was explicitly specified to this React Component, then
// open it; otherwise, use a default. // open it; otherwise, use a default.
this._openURL(toURLString(this.props.url) || this._getDefaultURL()); this._openURL(toURLString(this.props.url) || this._getDefaultURL());
});
} }
/** /**
@ -53,13 +51,14 @@ export class AbstractApp extends BaseApp<Props, *> {
* *
* @inheritdoc * @inheritdoc
*/ */
componentDidUpdate(prevProps: Props) { async componentDidUpdate(prevProps: Props) {
const previousUrl = toURLString(prevProps.url); const previousUrl = toURLString(prevProps.url);
const currentUrl = toURLString(this.props.url); const currentUrl = toURLString(this.props.url);
const previousTimestamp = prevProps.timestamp; const previousTimestamp = prevProps.timestamp;
const currentTimestamp = this.props.timestamp; const currentTimestamp = this.props.timestamp;
this._init.then(() => { await this._init;
// Deal with URL changes. // Deal with URL changes.
if (previousUrl !== currentUrl if (previousUrl !== currentUrl
@ -69,7 +68,6 @@ export class AbstractApp extends BaseApp<Props, *> {
|| previousTimestamp !== currentTimestamp) { || previousTimestamp !== currentTimestamp) {
this._openURL(currentUrl || this._getDefaultURL()); this._openURL(currentUrl || this._getDefaultURL());
} }
});
} }
/** /**

View File

@ -81,12 +81,18 @@ export class App extends AbstractApp {
* *
* @returns {void} * @returns {void}
*/ */
componentDidMount() { async componentDidMount() {
super.componentDidMount(); await super.componentDidMount();
SplashScreen.hide(); SplashScreen.hide();
}
this._init.then(() => { /**
* Initializes feature flags and updates settings.
*
* @returns {void}
*/
_extraInit() {
const { dispatch, getState } = this.state.store; const { dispatch, getState } = this.state.store;
// We set these early enough so then we avoid any unnecessary re-renders. // We set these early enough so then we avoid any unnecessary re-renders.
@ -114,7 +120,6 @@ export class App extends AbstractApp {
if (typeof callIntegrationEnabled !== 'undefined') { if (typeof callIntegrationEnabled !== 'undefined') {
dispatch(updateSettings({ disableCallIntegration: !callIntegrationEnabled })); dispatch(updateSettings({ disableCallIntegration: !callIntegrationEnabled }));
} }
});
} }
/** /**

View File

@ -16,6 +16,7 @@ import {
StateListenerRegistry StateListenerRegistry
} from '../../redux'; } from '../../redux';
import { SoundCollection } from '../../sounds'; import { SoundCollection } from '../../sounds';
import { createDeferred } from '../../util';
import { appWillMount, appWillUnmount } from '../actions'; import { appWillMount, appWillUnmount } from '../actions';
import logger from '../logger'; import logger from '../logger';
@ -43,7 +44,10 @@ type State = {
* @abstract * @abstract
*/ */
export default class BaseApp extends Component<*, State> { export default class BaseApp extends Component<*, State> {
_init: Promise<*>; /**
* The deferred for the initialisation {{promise, resolve, reject}}.
*/
_init: Object;
/** /**
* Initializes a new {@code BaseApp} instance. * Initializes a new {@code BaseApp} instance.
@ -65,7 +69,7 @@ export default class BaseApp extends Component<*, State> {
* *
* @inheritdoc * @inheritdoc
*/ */
componentDidMount() { async componentDidMount() {
/** /**
* Make the mobile {@code BaseApp} wait until the {@code AsyncStorage} * Make the mobile {@code BaseApp} wait until the {@code AsyncStorage}
* implementation of {@code Storage} initializes fully. * implementation of {@code Storage} initializes fully.
@ -74,21 +78,28 @@ export default class BaseApp extends Component<*, State> {
* @see {@link #_initStorage} * @see {@link #_initStorage}
* @type {Promise} * @type {Promise}
*/ */
this._init = this._initStorage() this._init = createDeferred();
.catch(err => {
/* BaseApp should always initialize! */ try {
logger.error(err); await this._initStorage();
})
.then(() => new Promise(resolve => { const setStatePromise = new Promise(resolve => {
this.setState({ this.setState({
store: this._createStore() store: this._createStore()
}, resolve); }, resolve);
})) });
.then(() => this.state.store.dispatch(appWillMount(this)))
.catch(err => { await setStatePromise;
await this._extraInit();
} catch (err) {
/* BaseApp should always initialize! */ /* BaseApp should always initialize! */
logger.error(err); logger.error(err);
}); }
this.state.store.dispatch(appWillMount(this));
this._init.resolve();
} }
/** /**
@ -127,6 +138,15 @@ export default class BaseApp extends Component<*, State> {
return _initializing || Promise.resolve(); return _initializing || Promise.resolve();
} }
/**
* Extra initialisation that subclasses might require.
*
* @returns {void}
*/
_extraInit() {
// To be implemented by subclass.
}
/** /**
* Implements React's {@link Component#render()}. * Implements React's {@link Component#render()}.
* *

View File

@ -43,10 +43,9 @@ export default class IncomingCallApp extends BaseApp<Props> {
* *
* @returns {void} * @returns {void}
*/ */
componentDidMount() { async componentDidMount() {
super.componentDidMount(); await super.componentDidMount();
this._init.then(() => {
const { dispatch } = this.state.store; const { dispatch } = this.state.store;
const { const {
callerAvatarURL: avatarUrl, callerAvatarURL: avatarUrl,
@ -61,6 +60,5 @@ export default class IncomingCallApp extends BaseApp<Props> {
})); }));
super._navigate({ component: IncomingCallPage }); super._navigate({ component: IncomingCallPage });
});
} }
} }

View File

@ -36,10 +36,9 @@ export default class PrejoinApp extends BaseApp<Props> {
* *
* @returns {void} * @returns {void}
*/ */
componentDidMount() { async componentDidMount() {
super.componentDidMount(); await super.componentDidMount();
this._init.then(async () => {
const { store } = this.state; const { store } = this.state;
const { dispatch } = store; const { dispatch } = store;
const { styleType } = this.props; const { styleType } = this.props;
@ -69,7 +68,6 @@ export default class PrejoinApp extends BaseApp<Props> {
dispatch(initPrejoin(tracks, errors)); dispatch(initPrejoin(tracks, errors));
dispatch(makePrecallTest(getConferenceOptions(store.getState()))); dispatch(makePrecallTest(getConferenceOptions(store.getState())));
}); });
});
} }
/** /**