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 4.6KB

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