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

View File

@ -81,12 +81,18 @@ export class App extends AbstractApp {
*
* @returns {void}
*/
componentDidMount() {
super.componentDidMount();
async componentDidMount() {
await super.componentDidMount();
SplashScreen.hide();
}
this._init.then(() => {
/**
* Initializes feature flags and updates settings.
*
* @returns {void}
*/
_extraInit() {
const { dispatch, getState } = this.state.store;
// 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') {
dispatch(updateSettings({ disableCallIntegration: !callIntegrationEnabled }));
}
});
}
/**

View File

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

View File

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

View File

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