feat(App): refactor App and split it into BaseApp and App (continued)
There doesn't seem to be a strong need for the initialized React Component state in BaseApp so remove/delete it.
This commit is contained in:
parent
dc246960df
commit
bfdfb5321c
|
@ -10,7 +10,7 @@ import { appNavigate } from '../actions';
|
||||||
import { getDefaultURL } from '../functions';
|
import { getDefaultURL } from '../functions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code AbstractApp} component's property types.
|
* The type of React {@code Component} props of {@link AbstractApp}.
|
||||||
*/
|
*/
|
||||||
export type Props = {
|
export type Props = {
|
||||||
|
|
||||||
|
@ -49,8 +49,8 @@ export class AbstractApp extends BaseApp<Props, *> {
|
||||||
super.componentWillMount();
|
super.componentWillMount();
|
||||||
|
|
||||||
this._init.then(() => {
|
this._init.then(() => {
|
||||||
// If a URL was explicitly specified to this React Component,
|
// If a URL was explicitly specified to this React Component, then
|
||||||
// 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());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -102,9 +102,9 @@ export class AbstractApp extends BaseApp<Props, *> {
|
||||||
* Creates an extra {@link ReactElement}s to be added (unconditionaly)
|
* Creates an extra {@link ReactElement}s to be added (unconditionaly)
|
||||||
* alongside the main element.
|
* alongside the main element.
|
||||||
*
|
*
|
||||||
* @returns {ReactElement}
|
|
||||||
* @abstract
|
* @abstract
|
||||||
* @protected
|
* @protected
|
||||||
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
_createExtraElement() {
|
_createExtraElement() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -27,46 +27,46 @@ import type { Props as AbstractAppProps } from './AbstractApp';
|
||||||
declare var __DEV__;
|
declare var __DEV__;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App component's property types.
|
* The type of React {@code Component} props of {@link App}.
|
||||||
*/
|
*/
|
||||||
type Props = AbstractAppProps & {
|
type Props = AbstractAppProps & {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the add people feature is enabled or not.
|
* Whether the add people feature is enabled.
|
||||||
*/
|
*/
|
||||||
addPeopleEnabled: boolean,
|
addPeopleEnabled: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the dial-out feature is enabled or not.
|
* Whether the dial-out feature is enabled.
|
||||||
*/
|
*/
|
||||||
dialOutEnabled: boolean,
|
dialOutEnabled: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether Picture-in-Picture is enabled. If {@code true}, a toolbar
|
* Whether Picture-in-Picture is enabled. If {@code true}, a toolbar button
|
||||||
* button is rendered in the {@link Conference} view to afford entering
|
* is rendered in the {@link Conference} view to afford entering
|
||||||
* Picture-in-Picture.
|
* Picture-in-Picture.
|
||||||
*/
|
*/
|
||||||
pictureInPictureEnabled: boolean,
|
pictureInPictureEnabled: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the Welcome page is enabled. If {@code true}, the Welcome
|
* Whether the Welcome page is enabled. If {@code true}, the Welcome page is
|
||||||
* page is rendered when the {@link App} is not at a location (URL)
|
* rendered when the {@link App} is not at a location (URL) identifying
|
||||||
* identifying a Jitsi Meet conference/room.
|
* a Jitsi Meet conference/room.
|
||||||
*/
|
*/
|
||||||
welcomePageEnabled: boolean
|
welcomePageEnabled: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Root application component.
|
* Root app {@code Component} on mobile/React Native.
|
||||||
*
|
*
|
||||||
* @extends AbstractApp
|
* @extends AbstractApp
|
||||||
*/
|
*/
|
||||||
export class App extends AbstractApp {
|
export class App extends AbstractApp {
|
||||||
/**
|
/**
|
||||||
* Initializes a new App instance.
|
* Initializes a new {@code App} instance.
|
||||||
*
|
*
|
||||||
* @param {Object} props - The read-only React Component props with which
|
* @param {Props} props - The read-only React {@code Component} props with
|
||||||
* the new instance is to be initialized.
|
* which the new instance is to be initialized.
|
||||||
*/
|
*/
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -76,8 +76,8 @@ export class App extends AbstractApp {
|
||||||
|
|
||||||
// In the Release configuration, React Native will (intentionally) throw
|
// In the Release configuration, React Native will (intentionally) throw
|
||||||
// an unhandled JavascriptException for an unhandled JavaScript error.
|
// an unhandled JavascriptException for an unhandled JavaScript error.
|
||||||
// This will effectively kill the application. In accord with the Web,
|
// This will effectively kill the app. In accord with the Web, do not
|
||||||
// do not kill the application.
|
// kill the app.
|
||||||
this._maybeDisableExceptionsManager();
|
this._maybeDisableExceptionsManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,10 +130,9 @@ export class App extends AbstractApp {
|
||||||
* {@link ExceptionsManager#handleException} on platforms and in
|
* {@link ExceptionsManager#handleException} on platforms and in
|
||||||
* configurations on/in which the use of the method in questions has been
|
* configurations on/in which the use of the method in questions has been
|
||||||
* determined to be undesirable. For example, React Native will
|
* determined to be undesirable. For example, React Native will
|
||||||
* (intentionally) throw an unhandled JavascriptException for an
|
* (intentionally) throw an unhandled {@code JavascriptException} for an
|
||||||
* unhandled JavaScript error in the Release configuration. This will
|
* unhandled JavaScript error in the Release configuration. This will
|
||||||
* effectively kill the application. In accord with the Web, do not kill the
|
* effectively kill the app. In accord with the Web, do not kill the app.
|
||||||
* application.
|
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
@ -148,9 +147,9 @@ export class App extends AbstractApp {
|
||||||
// A solution based on RTCSetFatalHandler was implemented on iOS and
|
// A solution based on RTCSetFatalHandler was implemented on iOS and
|
||||||
// it is preferred because it is at a later step of the
|
// it is preferred because it is at a later step of the
|
||||||
// error/exception handling and it is specific to fatal
|
// error/exception handling and it is specific to fatal
|
||||||
// errors/exceptions which were observed to kill the application.
|
// errors/exceptions which were observed to kill the app. The
|
||||||
// The solution implemented bellow was tested on Android only so it
|
// solution implemented bellow was tested on Android only so it is
|
||||||
// is considered safest to use it there only.
|
// considered safest to use it there only.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,10 +166,10 @@ export class App extends AbstractApp {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notified by React's Linking API that a specific URL registered to be
|
* Notified by React's Linking API that a specific URL registered to be
|
||||||
* handled by this App was activated.
|
* handled by this app was activated.
|
||||||
*
|
*
|
||||||
* @param {Object} event - The details of the notification/event.
|
* @param {Object} event - The details of the notification/event.
|
||||||
* @param {string} event.url - The URL registered to be handled by this App
|
* @param {string} event.url - The URL registered to be handled by this app
|
||||||
* which was activated.
|
* which was activated.
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
@ -183,11 +182,11 @@ export class App extends AbstractApp {
|
||||||
/**
|
/**
|
||||||
* Handles a (possibly unhandled) JavaScript error by preventing React Native
|
* Handles a (possibly unhandled) JavaScript error by preventing React Native
|
||||||
* from converting a fatal error into an unhandled native exception which will
|
* from converting a fatal error into an unhandled native exception which will
|
||||||
* kill the application.
|
* kill the app.
|
||||||
*
|
*
|
||||||
* @param {Error} error - The (possibly unhandled) JavaScript error to handle.
|
* @param {Error} error - The (possibly unhandled) JavaScript error to handle.
|
||||||
* @param {boolean} fatal - True if the specified error is fatal; otherwise,
|
* @param {boolean} fatal - If the specified error is fatal, {@code true};
|
||||||
* false.
|
* otherwise, {@code false}.
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
|
@ -195,12 +194,12 @@ function _handleException(error, fatal) {
|
||||||
if (fatal) {
|
if (fatal) {
|
||||||
// In the Release configuration, React Native will (intentionally) throw
|
// In the Release configuration, React Native will (intentionally) throw
|
||||||
// an unhandled JavascriptException for an unhandled JavaScript error.
|
// an unhandled JavascriptException for an unhandled JavaScript error.
|
||||||
// This will effectively kill the application. In accord with the Web,
|
// This will effectively kill the app. In accord with the Web, do not
|
||||||
// do not kill the application.
|
// kill the app.
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} else {
|
} else {
|
||||||
// Forward to the next globalHandler of ErrorUtils.
|
// Forward to the next globalHandler of ErrorUtils.
|
||||||
const next = _handleException.next;
|
const { next } = _handleException;
|
||||||
|
|
||||||
typeof next === 'function' && next(error, fatal);
|
typeof next === 'function' && next(error, fatal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,21 @@ import '../../video-layout';
|
||||||
import { AbstractApp } from './AbstractApp';
|
import { AbstractApp } from './AbstractApp';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Root application component.
|
* Root app {@code Component} on Web/React.
|
||||||
*
|
*
|
||||||
* @extends AbstractApp
|
* @extends AbstractApp
|
||||||
*/
|
*/
|
||||||
export class App extends AbstractApp {
|
export class App extends AbstractApp {
|
||||||
|
/**
|
||||||
|
* Gets a Location object from the window with information about the current
|
||||||
|
* location of the document.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
getWindowLocation() {
|
||||||
|
return window.location;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the parent method to inject {@link AtlasKitThemeProvider} as
|
* Overrides the parent method to inject {@link AtlasKitThemeProvider} as
|
||||||
* the top most component.
|
* the top most component.
|
||||||
|
@ -29,14 +39,4 @@ export class App extends AbstractApp {
|
||||||
</AtlasKitThemeProvider>
|
</AtlasKitThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a Location object from the window with information about the current
|
|
||||||
* location of the document.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
getWindowLocation() {
|
|
||||||
return window.location;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,21 +20,18 @@ import { appWillMount, appWillUnmount } from '../actions';
|
||||||
|
|
||||||
declare var APP: Object;
|
declare var APP: Object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the React {@code Component} state of {@link BaseApp}.
|
||||||
|
*/
|
||||||
type State = {
|
type State = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The state of the »possible« async initialization of
|
* The {@code Route} rendered by the {@code BaseApp}.
|
||||||
* the {@code BaseApp}.
|
|
||||||
*/
|
|
||||||
initialized: boolean,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Route rendered by this {@code BaseApp}.
|
|
||||||
*/
|
*/
|
||||||
route: Object,
|
route: Object,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The redux store used by this {@code BaseApp}.
|
* The redux store used by the {@code BaseApp}.
|
||||||
*/
|
*/
|
||||||
store: Object
|
store: Object
|
||||||
};
|
};
|
||||||
|
@ -57,7 +54,6 @@ export default class BaseApp extends Component<*, State> {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
initialized: false,
|
|
||||||
route: {},
|
route: {},
|
||||||
|
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
|
@ -65,9 +61,8 @@ export default class BaseApp extends Component<*, State> {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the mobile {@code BaseApp} wait until the
|
* Make the mobile {@code BaseApp} wait until the {@code AsyncStorage}
|
||||||
* {@code AsyncStorage} implementation of {@code Storage} initializes
|
* implementation of {@code Storage} initializes fully.
|
||||||
* fully.
|
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @see {@link #_initStorage}
|
* @see {@link #_initStorage}
|
||||||
|
@ -83,32 +78,21 @@ export default class BaseApp extends Component<*, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the application.
|
* Initializes the app.
|
||||||
*
|
*
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
this._init.then(() => {
|
this._init.then(() => this.state.store.dispatch(appWillMount(this)));
|
||||||
const { dispatch } = this.state.store;
|
|
||||||
|
|
||||||
dispatch(appWillMount(this));
|
|
||||||
|
|
||||||
// We set the initialized state here and not in the constructor to
|
|
||||||
// make sure that {@code componentWillMount} gets invoked before
|
|
||||||
// the app tries to render the actual app content.
|
|
||||||
this.setState({ initialized: true });
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* De-initialize the application.
|
* De-initializes the app.
|
||||||
*
|
*
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
const { dispatch } = this.state.store;
|
this.state.store.dispatch(appWillUnmount(this));
|
||||||
|
|
||||||
dispatch(appWillUnmount(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,10 +117,9 @@ export default class BaseApp extends Component<*, State> {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const { initialized, route, store } = this.state;
|
const { route: { component }, store } = this.state;
|
||||||
const { component } = route;
|
|
||||||
|
|
||||||
if (initialized && component) {
|
if (store && component) {
|
||||||
return (
|
return (
|
||||||
<I18nextProvider i18n = { i18next }>
|
<I18nextProvider i18n = { i18next }>
|
||||||
<Provider store = { store }>
|
<Provider store = { store }>
|
||||||
|
|
Loading…
Reference in New Issue