Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

LobbyScreen.tsx 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. import React from 'react';
  2. import { Text, TextStyle, View, ViewStyle } from 'react-native';
  3. import { connect } from 'react-redux';
  4. import { IReduxState } from '../../../app/types';
  5. import { getConferenceName } from '../../../base/conference/functions';
  6. import { translate } from '../../../base/i18n/functions';
  7. import JitsiScreen from '../../../base/modal/components/JitsiScreen';
  8. import LoadingIndicator from '../../../base/react/components/native/LoadingIndicator';
  9. import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui/constants';
  10. import BaseTheme from '../../../base/ui/components/BaseTheme.native';
  11. import Button from '../../../base/ui/components/native/Button';
  12. import Input from '../../../base/ui/components/native/Input';
  13. import { BUTTON_TYPES } from '../../../base/ui/constants.native';
  14. import BrandingImageBackground from '../../../dynamic-branding/components/native/BrandingImageBackground';
  15. import LargeVideo from '../../../large-video/components/LargeVideo.native';
  16. import { navigate }
  17. from '../../../mobile/navigation/components/lobby/LobbyNavigationContainerRef';
  18. import { screen } from '../../../mobile/navigation/routes';
  19. import { preJoinStyles } from '../../../prejoin/components/native/styles';
  20. import AudioMuteButton from '../../../toolbox/components/AudioMuteButton';
  21. import VideoMuteButton from '../../../toolbox/components/VideoMuteButton';
  22. import AbstractLobbyScreen, {
  23. IProps as AbstractProps,
  24. _mapStateToProps as abstractMapStateToProps } from '../AbstractLobbyScreen';
  25. import styles from './styles';
  26. interface IProps extends AbstractProps {
  27. /**
  28. * The current aspect ratio of the screen.
  29. */
  30. _aspectRatio: Symbol;
  31. /**
  32. * The room name.
  33. */
  34. _roomName: string;
  35. }
  36. /**
  37. * Implements a waiting screen that represents the participant being in the lobby.
  38. */
  39. class LobbyScreen extends AbstractLobbyScreen<IProps> {
  40. /**
  41. * Implements {@code PureComponent#render}.
  42. *
  43. * @inheritdoc
  44. */
  45. render() {
  46. const { _aspectRatio, _roomName } = this.props;
  47. let contentWrapperStyles;
  48. let contentContainerStyles;
  49. let largeVideoContainerStyles;
  50. if (_aspectRatio === ASPECT_RATIO_NARROW) {
  51. contentWrapperStyles = preJoinStyles.contentWrapper;
  52. largeVideoContainerStyles = preJoinStyles.largeVideoContainer;
  53. contentContainerStyles = styles.contentContainer;
  54. } else {
  55. contentWrapperStyles = preJoinStyles.contentWrapperWide;
  56. largeVideoContainerStyles = preJoinStyles.largeVideoContainerWide;
  57. contentContainerStyles = preJoinStyles.contentContainerWide;
  58. }
  59. return (
  60. <JitsiScreen
  61. safeAreaInsets = { [ 'right' ] }
  62. style = { contentWrapperStyles }>
  63. <BrandingImageBackground />
  64. <View style = { largeVideoContainerStyles }>
  65. <View style = { preJoinStyles.displayRoomNameBackdrop as ViewStyle }>
  66. <Text
  67. numberOfLines = { 1 }
  68. style = { preJoinStyles.preJoinRoomName }>
  69. { _roomName }
  70. </Text>
  71. </View>
  72. <LargeVideo />
  73. </View>
  74. <View style = { contentContainerStyles as ViewStyle }>
  75. { this._renderToolbarButtons() }
  76. { this._renderContent() }
  77. </View>
  78. </JitsiScreen>
  79. );
  80. }
  81. /**
  82. * Navigates to the lobby chat screen.
  83. *
  84. * @private
  85. * @returns {void}
  86. */
  87. _onNavigateToLobbyChat() {
  88. navigate(screen.lobby.chat);
  89. }
  90. /**
  91. * Renders the joining (waiting) fragment of the screen.
  92. *
  93. * @inheritdoc
  94. */
  95. _renderJoining() {
  96. return (
  97. <View style = { styles.lobbyWaitingFragmentContainer }>
  98. <Text style = { styles.lobbyTitle }>
  99. { this.props.t('lobby.joiningTitle') }
  100. </Text>
  101. <LoadingIndicator
  102. color = { BaseTheme.palette.icon01 }
  103. style = { styles.loadingIndicator } />
  104. <Text style = { styles.joiningMessage as TextStyle }>
  105. { this.props.t('lobby.joiningMessage') }
  106. </Text>
  107. { this._renderStandardButtons() }
  108. </View>
  109. );
  110. }
  111. /**
  112. * Renders the participant form to let the knocking participant enter its details.
  113. *
  114. * @inheritdoc
  115. */
  116. _renderParticipantForm() {
  117. const { t } = this.props;
  118. const { displayName } = this.state;
  119. return (
  120. <Input
  121. customStyles = {{ input: preJoinStyles.customInput }}
  122. onChange = { this._onChangeDisplayName }
  123. placeholder = { t('lobby.nameField') }
  124. value = { displayName } />
  125. );
  126. }
  127. /**
  128. * Renders the participant info fragment when we have all the required details of the user.
  129. *
  130. * @inheritdoc
  131. */
  132. _renderParticipantInfo() {
  133. return this._renderParticipantForm();
  134. }
  135. /**
  136. * Renders the password form to let the participant join by using a password instead of knocking.
  137. *
  138. * @inheritdoc
  139. */
  140. _renderPasswordForm() {
  141. const { _passwordJoinFailed, t } = this.props;
  142. return (
  143. <Input
  144. autoCapitalize = 'none'
  145. customStyles = {{ input: styles.customInput }}
  146. error = { _passwordJoinFailed }
  147. onChange = { this._onChangePassword }
  148. placeholder = { t('lobby.passwordField') }
  149. secureTextEntry = { true }
  150. value = { this.state.password } />
  151. );
  152. }
  153. /**
  154. * Renders the password join button (set).
  155. *
  156. * @inheritdoc
  157. */
  158. _renderPasswordJoinButtons() {
  159. return (
  160. <View style = { styles.passwordJoinButtons }>
  161. <Button
  162. accessibilityLabel = 'lobby.passwordJoinButton'
  163. disabled = { !this.state.password }
  164. labelKey = { 'lobby.passwordJoinButton' }
  165. onClick = { this._onJoinWithPassword }
  166. style = { preJoinStyles.joinButton }
  167. type = { BUTTON_TYPES.PRIMARY } />
  168. <Button
  169. accessibilityLabel = 'lobby.backToKnockModeButton'
  170. labelKey = 'lobby.backToKnockModeButton'
  171. onClick = { this._onSwitchToKnockMode }
  172. style = { preJoinStyles.joinButton }
  173. type = { BUTTON_TYPES.TERTIARY } />
  174. </View>
  175. );
  176. }
  177. /**
  178. * Renders the toolbar buttons menu.
  179. *
  180. * @inheritdoc
  181. */
  182. _renderToolbarButtons() {
  183. return (
  184. <View style = { preJoinStyles.toolboxContainer as ViewStyle }>
  185. <AudioMuteButton
  186. styles = { preJoinStyles.buttonStylesBorderless } />
  187. <VideoMuteButton
  188. styles = { preJoinStyles.buttonStylesBorderless } />
  189. </View>
  190. );
  191. }
  192. /**
  193. * Renders the standard button set.
  194. *
  195. * @inheritdoc
  196. */
  197. _renderStandardButtons() {
  198. const { _knocking, _renderPassword, _isLobbyChatActive } = this.props;
  199. const { displayName } = this.state;
  200. return (
  201. <View style = { styles.formWrapper as ViewStyle }>
  202. {
  203. _knocking && _isLobbyChatActive
  204. && <Button
  205. accessibilityLabel = 'toolbar.openChat'
  206. labelKey = 'toolbar.openChat'
  207. onClick = { this._onNavigateToLobbyChat }
  208. style = { preJoinStyles.joinButton }
  209. type = { BUTTON_TYPES.PRIMARY } />
  210. }
  211. {
  212. _knocking
  213. || <Button
  214. accessibilityLabel = 'lobby.knockButton'
  215. disabled = { !displayName }
  216. labelKey = 'lobby.knockButton'
  217. onClick = { this._onAskToJoin }
  218. style = { preJoinStyles.joinButton }
  219. type = { BUTTON_TYPES.PRIMARY } />
  220. }
  221. {
  222. _renderPassword
  223. && <Button
  224. accessibilityLabel = 'lobby.enterPasswordButton'
  225. labelKey = 'lobby.enterPasswordButton'
  226. onClick = { this._onSwitchToPasswordMode }
  227. style = { preJoinStyles.joinButton }
  228. type = { BUTTON_TYPES.PRIMARY } />
  229. }
  230. </View>
  231. );
  232. }
  233. }
  234. /**
  235. * Maps part of the Redux state to the props of this component.
  236. *
  237. * @param {Object} state - The Redux state.
  238. * @param {IProps} ownProps - The own props of the component.
  239. * @returns {{
  240. * _aspectRatio: Symbol
  241. * }}
  242. */
  243. function _mapStateToProps(state: IReduxState) {
  244. return {
  245. ...abstractMapStateToProps(state),
  246. _aspectRatio: state['features/base/responsive-ui'].aspectRatio,
  247. _roomName: getConferenceName(state)
  248. };
  249. }
  250. export default translate(connect(_mapStateToProps)(LobbyScreen));