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.

DialInSummary.js 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // @flow
  2. import React, { Component } from 'react';
  3. import { Linking, View } from 'react-native';
  4. import { WebView } from 'react-native-webview';
  5. import { type Dispatch } from 'redux';
  6. import { openDialog } from '../../../../base/dialog';
  7. import { translate } from '../../../../base/i18n';
  8. import {
  9. HeaderWithNavigation,
  10. LoadingIndicator,
  11. SlidingView
  12. } from '../../../../base/react';
  13. import { connect } from '../../../../base/redux';
  14. import { hideDialInSummary } from '../../../actions';
  15. import { getDialInfoPageURLForURIString } from '../../../functions';
  16. import DialInSummaryErrorDialog from './DialInSummaryErrorDialog';
  17. import styles, { INDICATOR_COLOR } from './styles';
  18. type Props = {
  19. /**
  20. * The URL to display the summary for.
  21. */
  22. _summaryUrl: ?string,
  23. dispatch: Dispatch<any>
  24. };
  25. /**
  26. * Implements a React native component that displays the dial in info page for a specific room.
  27. */
  28. class DialInSummary extends Component<Props> {
  29. /**
  30. * Initializes a new instance.
  31. *
  32. * @inheritdoc
  33. */
  34. constructor(props: Props) {
  35. super(props);
  36. this._onCloseView = this._onCloseView.bind(this);
  37. this._onError = this._onError.bind(this);
  38. this._onNavigate = this._onNavigate.bind(this);
  39. this._renderLoading = this._renderLoading.bind(this);
  40. }
  41. /**
  42. * Implements React's {@link Component#render()}.
  43. *
  44. * @inheritdoc
  45. */
  46. render() {
  47. const { _summaryUrl } = this.props;
  48. return (
  49. <SlidingView
  50. onHide = { this._onCloseView }
  51. position = 'bottom'
  52. show = { Boolean(_summaryUrl) } >
  53. <View style = { styles.webViewWrapper }>
  54. <HeaderWithNavigation
  55. headerLabelKey = 'info.label'
  56. onPressBack = { this._onCloseView } />
  57. <WebView
  58. onError = { this._onError }
  59. onShouldStartLoadWithRequest = { this._onNavigate }
  60. renderLoading = { this._renderLoading }
  61. source = {{ uri: getDialInfoPageURLForURIString(_summaryUrl) }}
  62. startInLoadingState = { true }
  63. style = { styles.webView } />
  64. </View>
  65. </SlidingView>
  66. );
  67. }
  68. _onCloseView: () => boolean;
  69. /**
  70. * Closes the view.
  71. *
  72. * @returns {boolean}
  73. */
  74. _onCloseView() {
  75. if (this.props._summaryUrl) {
  76. this.props.dispatch(hideDialInSummary());
  77. return true;
  78. }
  79. return false;
  80. }
  81. _onError: () => void;
  82. /**
  83. * Callback to handle the error if the page fails to load.
  84. *
  85. * @returns {void}
  86. */
  87. _onError() {
  88. this.props.dispatch(hideDialInSummary());
  89. this.props.dispatch(openDialog(DialInSummaryErrorDialog));
  90. }
  91. _onNavigate: Object => Boolean;
  92. /**
  93. * Callback to intercept navigation inside the webview and make the native app handle the dial requests.
  94. *
  95. * NOTE: We don't navigate to anywhere else form that view.
  96. *
  97. * @param {any} request - The request object.
  98. * @returns {boolean}
  99. */
  100. _onNavigate(request) {
  101. const { url } = request;
  102. if (url.startsWith('tel:')) {
  103. Linking.openURL(url);
  104. this.props.dispatch(hideDialInSummary());
  105. }
  106. return url === getDialInfoPageURLForURIString(this.props._summaryUrl);
  107. }
  108. _renderLoading: () => React$Component<any>;
  109. /**
  110. * Renders the loading indicator.
  111. *
  112. * @returns {React$Component<any>}
  113. */
  114. _renderLoading() {
  115. return (
  116. <View style = { styles.indicatorWrapper }>
  117. <LoadingIndicator
  118. color = { INDICATOR_COLOR }
  119. size = 'large' />
  120. </View>
  121. );
  122. }
  123. }
  124. /**
  125. * Maps part of the Redux state to the props of this component.
  126. *
  127. * @param {Object} state - The Redux state.
  128. * @returns {{
  129. * _summaryUrl: ?string
  130. * }}
  131. */
  132. function _mapStateToProps(state) {
  133. return {
  134. _summaryUrl: state['features/invite'].summaryUrl
  135. };
  136. }
  137. export default translate(connect(_mapStateToProps)(DialInSummary));