2018-01-30 20:57:36 +00:00
|
|
|
// FIXME The bundler-related (and the browser-related) polyfills were born at
|
|
|
|
// the very early days of prototyping the execution of lib-jitsi-meet on
|
|
|
|
// react-native. Today, the feature base/lib-jitsi-meet should not be
|
|
|
|
// responsible for such polyfills because it is not the only feature relying on
|
|
|
|
// them. Additionally, the polyfills are usually necessary earlier than the
|
|
|
|
// execution of base/lib-jitsi-meet (which is understandable given that the
|
|
|
|
// polyfills are globals). The remaining problem to be solved here is where to
|
|
|
|
// collect the polyfills' files.
|
|
|
|
import './features/base/lib-jitsi-meet/native/polyfills-bundler';
|
|
|
|
|
|
|
|
// FIXME: Remove once react-native-webrtc and react-native-prompt import
|
|
|
|
// PropTypes from 'prop-types' instead of 'react'.
|
|
|
|
import './features/base/react/prop-types-polyfill';
|
2017-10-24 22:26:56 +00:00
|
|
|
|
2017-09-27 21:23:31 +00:00
|
|
|
import PropTypes from 'prop-types';
|
2016-10-05 14:36:59 +00:00
|
|
|
import React, { Component } from 'react';
|
2018-01-17 12:24:00 +00:00
|
|
|
import { AppRegistry, Linking, NativeModules } from 'react-native';
|
2016-10-05 14:36:59 +00:00
|
|
|
|
|
|
|
import { App } from './features/app';
|
2017-07-31 13:30:31 +00:00
|
|
|
import { equals } from './features/base/redux';
|
2016-10-05 14:36:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* React Native doesn't support specifying props to the main/root component (in
|
|
|
|
* the JS/JSX source code). So create a wrapper React Component (class) around
|
|
|
|
* features/app's App instead.
|
|
|
|
*
|
|
|
|
* @extends Component
|
|
|
|
*/
|
|
|
|
class Root extends Component {
|
2017-06-09 10:30:59 +00:00
|
|
|
/**
|
2017-06-09 19:09:23 +00:00
|
|
|
* {@code Root} component's property types.
|
2017-06-09 10:30:59 +00:00
|
|
|
*
|
|
|
|
* @static
|
|
|
|
*/
|
|
|
|
static propTypes = {
|
|
|
|
/**
|
2017-06-09 19:09:23 +00:00
|
|
|
* The URL, if any, with which the app was launched.
|
2017-06-09 10:30:59 +00:00
|
|
|
*/
|
2017-09-27 21:23:31 +00:00
|
|
|
url: PropTypes.oneOfType([
|
|
|
|
PropTypes.object,
|
|
|
|
PropTypes.string
|
2017-07-31 13:30:31 +00:00
|
|
|
]),
|
2017-06-09 10:30:59 +00:00
|
|
|
|
|
|
|
/**
|
2017-06-09 19:09:23 +00:00
|
|
|
* Whether the Welcome page is enabled. If {@code true}, the Welcome
|
|
|
|
* page is rendered when the {@link App} is not at a location (URL)
|
|
|
|
* identifying a Jitsi Meet conference/room.
|
2017-06-09 10:30:59 +00:00
|
|
|
*/
|
2017-09-27 21:23:31 +00:00
|
|
|
welcomePageEnabled: PropTypes.bool
|
2017-06-09 10:30:59 +00:00
|
|
|
};
|
|
|
|
|
2016-10-05 14:36:59 +00:00
|
|
|
/**
|
2017-06-09 19:09:23 +00:00
|
|
|
* Initializes a new {@code Root} instance.
|
2016-10-05 14:36:59 +00:00
|
|
|
*
|
|
|
|
* @param {Object} props - The read-only properties with which the new
|
|
|
|
* instance is to be initialized.
|
|
|
|
*/
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The initial state of this Component.
|
|
|
|
*
|
2017-06-09 19:09:23 +00:00
|
|
|
* @type {{
|
2017-07-31 13:30:31 +00:00
|
|
|
* url: object|string
|
2017-06-09 19:09:23 +00:00
|
|
|
* }}
|
2016-10-05 14:36:59 +00:00
|
|
|
*/
|
|
|
|
this.state = {
|
|
|
|
/**
|
|
|
|
* The URL, if any, with which the app was launched.
|
|
|
|
*
|
2017-07-31 13:30:31 +00:00
|
|
|
* @type {object|string}
|
2016-10-05 14:36:59 +00:00
|
|
|
*/
|
2017-06-09 10:30:59 +00:00
|
|
|
url: this.props.url
|
2016-10-05 14:36:59 +00:00
|
|
|
};
|
|
|
|
|
2017-07-06 18:27:00 +00:00
|
|
|
// Handle the URL, if any, with which the app was launched. But props
|
|
|
|
// have precedence.
|
2017-07-06 08:01:35 +00:00
|
|
|
if (typeof this.props.url === 'undefined') {
|
2018-01-17 12:24:00 +00:00
|
|
|
this._getInitialURL()
|
2017-07-06 08:01:35 +00:00
|
|
|
.then(url => {
|
|
|
|
if (typeof this.state.url === 'undefined') {
|
|
|
|
this.setState({ url });
|
|
|
|
}
|
|
|
|
})
|
2017-07-06 08:01:35 +00:00
|
|
|
.catch(err => {
|
|
|
|
console.error('Failed to get initial URL', err);
|
2016-10-05 14:36:59 +00:00
|
|
|
|
2017-07-06 08:01:35 +00:00
|
|
|
if (typeof this.state.url === 'undefined') {
|
|
|
|
// Start with an empty URL if getting the initial URL
|
|
|
|
// fails; otherwise, nothing will be rendered.
|
|
|
|
this.setState({ url: null });
|
|
|
|
}
|
2017-07-06 08:01:35 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-17 12:24:00 +00:00
|
|
|
/**
|
|
|
|
* Gets the initial URL the app was launched with. This can be a universal
|
|
|
|
* (or deep) link, or a CallKit intent in iOS. Since the native
|
|
|
|
* {@code Linking} module doesn't provide a way to access intents in iOS,
|
|
|
|
* those are handled with the {@code LaunchOptions} module, which
|
|
|
|
* essentially provides a replacement which takes that into consideration.
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
* @returns {Promise} - A promise which will be fulfilled with the URL that
|
|
|
|
* the app was launched with.
|
|
|
|
*/
|
|
|
|
_getInitialURL() {
|
|
|
|
if (NativeModules.LaunchOptions) {
|
|
|
|
return NativeModules.LaunchOptions.getInitialURL();
|
|
|
|
}
|
|
|
|
|
|
|
|
return Linking.getInitialURL();
|
|
|
|
}
|
|
|
|
|
2017-07-06 08:01:35 +00:00
|
|
|
/**
|
|
|
|
* Implements React's {@link Component#componentWillReceiveProps()}.
|
|
|
|
*
|
|
|
|
* New props can be set from the native side by setting the appProperties
|
|
|
|
* property (on iOS) or calling setAppProperties (on Android).
|
|
|
|
*
|
|
|
|
* @inheritdoc
|
|
|
|
*/
|
2017-07-06 18:27:00 +00:00
|
|
|
componentWillReceiveProps({ url }) {
|
2017-09-01 21:25:48 +00:00
|
|
|
equals(this.props.url, url) || this.setState({ url: url || null });
|
2016-10-05 14:36:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implements React's {@link Component#render()}.
|
|
|
|
*
|
|
|
|
* @inheritdoc
|
|
|
|
* @returns {ReactElement}
|
|
|
|
*/
|
|
|
|
render() {
|
2017-06-09 19:09:23 +00:00
|
|
|
const { url } = this.state;
|
|
|
|
|
|
|
|
// XXX We don't render the App component until we get the initial URL.
|
|
|
|
// Either it's null or some other non-null defined value.
|
|
|
|
if (typeof url === 'undefined') {
|
2016-10-05 14:36:59 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2017-06-09 19:09:23 +00:00
|
|
|
const {
|
|
|
|
// The following props are forked in state:
|
|
|
|
url: _, // eslint-disable-line no-unused-vars
|
|
|
|
|
|
|
|
// The remaining props are passed through to App.
|
|
|
|
...props
|
|
|
|
} = this.props;
|
|
|
|
|
2016-10-05 14:36:59 +00:00
|
|
|
return (
|
|
|
|
<App
|
2017-06-09 19:09:23 +00:00
|
|
|
{ ...props }
|
|
|
|
url = { url } />
|
2016-10-05 14:36:59 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-09 19:09:23 +00:00
|
|
|
// Register the main/root Component.
|
2016-10-05 14:36:59 +00:00
|
|
|
AppRegistry.registerComponent('App', () => Root);
|