You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.native.js 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // FIXME The bundler-related (and the browser-related) polyfills were born at
  2. // the very early days of prototyping the execution of lib-jitsi-meet on
  3. // react-native. Today, the feature base/lib-jitsi-meet should not be
  4. // responsible for such polyfills because it is not the only feature relying on
  5. // them. Additionally, the polyfills are usually necessary earlier than the
  6. // execution of base/lib-jitsi-meet (which is understandable given that the
  7. // polyfills are globals). The remaining problem to be solved here is where to
  8. // collect the polyfills' files.
  9. import './features/base/lib-jitsi-meet/native/polyfills-bundler';
  10. // FIXME: Remove once react-native-webrtc and react-native-prompt import
  11. // PropTypes from 'prop-types' instead of 'react'.
  12. import './features/base/react/prop-types-polyfill';
  13. import PropTypes from 'prop-types';
  14. import React, { Component } from 'react';
  15. import { AppRegistry, Linking, NativeModules } from 'react-native';
  16. import { App } from './features/app';
  17. import { equals } from './features/base/redux';
  18. /**
  19. * React Native doesn't support specifying props to the main/root component (in
  20. * the JS/JSX source code). So create a wrapper React Component (class) around
  21. * features/app's App instead.
  22. *
  23. * @extends Component
  24. */
  25. class Root extends Component {
  26. /**
  27. * {@code Root} component's property types.
  28. *
  29. * @static
  30. */
  31. static propTypes = {
  32. /**
  33. * The URL, if any, with which the app was launched.
  34. */
  35. url: PropTypes.oneOfType([
  36. PropTypes.object,
  37. PropTypes.string
  38. ]),
  39. /**
  40. * Whether the Welcome page is enabled. If {@code true}, the Welcome
  41. * page is rendered when the {@link App} is not at a location (URL)
  42. * identifying a Jitsi Meet conference/room.
  43. */
  44. welcomePageEnabled: PropTypes.bool
  45. };
  46. /**
  47. * Initializes a new {@code Root} instance.
  48. *
  49. * @param {Object} props - The read-only properties with which the new
  50. * instance is to be initialized.
  51. */
  52. constructor(props) {
  53. super(props);
  54. /**
  55. * The initial state of this Component.
  56. *
  57. * @type {{
  58. * url: object|string
  59. * }}
  60. */
  61. this.state = {
  62. /**
  63. * The URL, if any, with which the app was launched.
  64. *
  65. * @type {object|string}
  66. */
  67. url: this.props.url
  68. };
  69. // Handle the URL, if any, with which the app was launched. But props
  70. // have precedence.
  71. if (typeof this.props.url === 'undefined') {
  72. this._getInitialURL()
  73. .then(url => {
  74. if (typeof this.state.url === 'undefined') {
  75. this.setState({ url });
  76. }
  77. })
  78. .catch(err => {
  79. console.error('Failed to get initial URL', err);
  80. if (typeof this.state.url === 'undefined') {
  81. // Start with an empty URL if getting the initial URL
  82. // fails; otherwise, nothing will be rendered.
  83. this.setState({ url: null });
  84. }
  85. });
  86. }
  87. }
  88. /**
  89. * Gets the initial URL the app was launched with. This can be a universal
  90. * (or deep) link, or a CallKit intent in iOS. Since the native
  91. * {@code Linking} module doesn't provide a way to access intents in iOS,
  92. * those are handled with the {@code LaunchOptions} module, which
  93. * essentially provides a replacement which takes that into consideration.
  94. *
  95. * @private
  96. * @returns {Promise} - A promise which will be fulfilled with the URL that
  97. * the app was launched with.
  98. */
  99. _getInitialURL() {
  100. if (NativeModules.LaunchOptions) {
  101. return NativeModules.LaunchOptions.getInitialURL();
  102. }
  103. return Linking.getInitialURL();
  104. }
  105. /**
  106. * Implements React's {@link Component#componentWillReceiveProps()}.
  107. *
  108. * New props can be set from the native side by setting the appProperties
  109. * property (on iOS) or calling setAppProperties (on Android).
  110. *
  111. * @inheritdoc
  112. */
  113. componentWillReceiveProps({ url }) {
  114. equals(this.props.url, url) || this.setState({ url: url || null });
  115. }
  116. /**
  117. * Implements React's {@link Component#render()}.
  118. *
  119. * @inheritdoc
  120. * @returns {ReactElement}
  121. */
  122. render() {
  123. const { url } = this.state;
  124. // XXX We don't render the App component until we get the initial URL.
  125. // Either it's null or some other non-null defined value.
  126. if (typeof url === 'undefined') {
  127. return null;
  128. }
  129. const {
  130. // The following props are forked in state:
  131. url: _, // eslint-disable-line no-unused-vars
  132. // The remaining props are passed through to App.
  133. ...props
  134. } = this.props;
  135. return (
  136. <App
  137. { ...props }
  138. url = { url } />
  139. );
  140. }
  141. }
  142. // Register the main/root Component.
  143. AppRegistry.registerComponent('App', () => Root);