您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

UnsupportedMobileBrowser.js 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* @flow */
  2. import PropTypes from 'prop-types';
  3. import React, { Component } from 'react';
  4. import { connect } from 'react-redux';
  5. import { translate, translateToHTML } from '../../base/i18n';
  6. import { Platform } from '../../base/react';
  7. import { URI_PROTOCOL_PATTERN } from '../../base/util';
  8. import { DialInSummary } from '../../invite';
  9. import HideNotificationBarStyle from './HideNotificationBarStyle';
  10. declare var interfaceConfig: Object;
  11. /**
  12. * The namespace of the CSS styles of UnsupportedMobileBrowser.
  13. *
  14. * @private
  15. * @type {string}
  16. */
  17. const _SNS = 'unsupported-mobile-browser';
  18. /**
  19. * The namespace of the i18n/translation keys of UnsupportedMobileBrowser.
  20. *
  21. * @private
  22. * @type {string}
  23. */
  24. const _TNS = 'unsupportedBrowser';
  25. /**
  26. * The map of platforms to URLs at which the mobile app for the associated
  27. * platform is available for download.
  28. *
  29. * @private
  30. * @type {Array<string>}
  31. */
  32. const _URLS = {
  33. android: interfaceConfig.MOBILE_DOWNLOAD_LINK_ANDROID
  34. || 'https://play.google.com/store/apps/details?id=org.jitsi.meet',
  35. ios: interfaceConfig.MOBILE_DOWNLOAD_LINK_IOS
  36. || 'https://itunes.apple.com/us/app/jitsi-meet/id1165103905'
  37. };
  38. /**
  39. * React component representing mobile browser page.
  40. *
  41. * @class UnsupportedMobileBrowser
  42. */
  43. class UnsupportedMobileBrowser extends Component<*, *> {
  44. state: Object;
  45. /**
  46. * UnsupportedMobileBrowser component's property types.
  47. *
  48. * @static
  49. */
  50. static propTypes = {
  51. /**
  52. * The name of the conference attempting to being joined.
  53. */
  54. _room: PropTypes.string,
  55. /**
  56. * The function to translate human-readable text.
  57. *
  58. * @public
  59. * @type {Function}
  60. */
  61. t: PropTypes.func
  62. };
  63. /**
  64. * Initializes the text and URL of the `Start a conference` / `Join the
  65. * conversation` button which takes the user to the mobile app.
  66. *
  67. * @inheritdoc
  68. */
  69. componentWillMount() {
  70. // If the user installed the app while this Component was displayed
  71. // (e.g. the user clicked the Download the App button), then we would
  72. // like to open the current URL in the mobile app. The only way to do it
  73. // appears to be a link with an app-specific scheme, not a Universal
  74. // Link.
  75. const appScheme = interfaceConfig.MOBILE_APP_SCHEME || 'org.jitsi.meet';
  76. // Replace the protocol part with the app scheme.
  77. const joinURL
  78. = window.location.href.replace(
  79. new RegExp(`^${URI_PROTOCOL_PATTERN}`), `${appScheme}:`);
  80. this.setState({
  81. joinURL
  82. });
  83. }
  84. /**
  85. * Implements React's {@link Component#render()}.
  86. *
  87. * @inheritdoc
  88. * @returns {ReactElement}
  89. */
  90. render() {
  91. const { _room, t } = this.props;
  92. const openAppButtonClassName
  93. = `${_SNS}__button ${_SNS}__button_primary`;
  94. const appName
  95. = interfaceConfig.ADD_PEOPLE_APP_NAME || interfaceConfig.APP_NAME;
  96. return (
  97. <div className = { _SNS }>
  98. <div className = { `${_SNS}__body` }>
  99. <img
  100. className = { `${_SNS}__logo` }
  101. src = 'images/logo-blue.svg' />
  102. <p className = { `${_SNS}__text` }>
  103. {
  104. translateToHTML(
  105. t,
  106. `${_TNS}.appNotInstalled`,
  107. { app: appName })
  108. }
  109. </p>
  110. <a href = { this.state.joinURL }>
  111. <button className = { openAppButtonClassName }>
  112. { t(`${_TNS}.openApp`,
  113. { app: appName }) }
  114. </button>
  115. </a>
  116. <a href = { _URLS[Platform.OS] }>
  117. <button className = { `${_SNS}__button` }>
  118. { t(`${_TNS}.downloadApp`) }
  119. </button>
  120. </a>
  121. { _room
  122. ? <DialInSummary
  123. className = 'unsupported-dial-in'
  124. clickableNumbers = { true }
  125. room = { _room } />
  126. : null }
  127. </div>
  128. <HideNotificationBarStyle />
  129. </div>
  130. );
  131. }
  132. }
  133. /**
  134. * Maps (parts of) the Redux state to the associated props for the
  135. * {@code UnsupportedMobileBrowser} component.
  136. *
  137. * @param {Object} state - The Redux state.
  138. * @private
  139. * @returns {{
  140. * _room: string
  141. * }}
  142. */
  143. function _mapStateToProps(state) {
  144. return {
  145. _room: state['features/base/conference'].room
  146. };
  147. }
  148. export default translate(connect(_mapStateToProps)(UnsupportedMobileBrowser));