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.

LobbyScreen.js 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // @flow
  2. import React from 'react';
  3. import { Text, View, TouchableOpacity, TextInput } from 'react-native';
  4. import { Avatar } from '../../../base/avatar';
  5. import { CustomDialog } from '../../../base/dialog';
  6. import { translate } from '../../../base/i18n';
  7. import { Icon, IconEdit } from '../../../base/icons';
  8. import { LoadingIndicator } from '../../../base/react';
  9. import { connect } from '../../../base/redux';
  10. import AbstractLobbyScreen, { _mapStateToProps } from '../AbstractLobbyScreen';
  11. import styles from './styles';
  12. /**
  13. * Implements a waiting screen that represents the participant being in the lobby.
  14. */
  15. class LobbyScreen extends AbstractLobbyScreen {
  16. /**
  17. * Implements {@code PureComponent#render}.
  18. *
  19. * @inheritdoc
  20. */
  21. render() {
  22. const { _meetingName, t } = this.props;
  23. return (
  24. <CustomDialog
  25. onCancel = { this._onCancel }
  26. style = { styles.contentWrapper }>
  27. <Text style = { styles.dialogTitle }>
  28. { t(this._getScreenTitleKey()) }
  29. </Text>
  30. <Text style = { styles.secondaryText }>
  31. { _meetingName }
  32. </Text>
  33. { this._renderContent() }
  34. </CustomDialog>
  35. );
  36. }
  37. _getScreenTitleKey: () => string;
  38. _onAskToJoin: () => void;
  39. _onCancel: () => boolean;
  40. _onChangeDisplayName: Object => void;
  41. _onChangeEmail: Object => void;
  42. _onChangePassword: Object => void;
  43. _onEnableEdit: () => void;
  44. _onJoinWithPassword: () => void;
  45. _onSwitchToKnockMode: () => void;
  46. _onSwitchToPasswordMode: () => void;
  47. _renderContent: () => React$Element<*>;
  48. /**
  49. * Renders the joining (waiting) fragment of the screen.
  50. *
  51. * @inheritdoc
  52. */
  53. _renderJoining() {
  54. return (
  55. <>
  56. <LoadingIndicator
  57. color = 'black'
  58. style = { styles.loadingIndicator } />
  59. <Text style = { styles.joiningMessage }>
  60. { this.props.t('lobby.joiningMessage') }
  61. </Text>
  62. { this._renderStandardButtons() }
  63. </>
  64. );
  65. }
  66. /**
  67. * Renders the participant form to let the knocking participant enter its details.
  68. *
  69. * @inheritdoc
  70. */
  71. _renderParticipantForm() {
  72. const { t } = this.props;
  73. const { displayName, email } = this.state;
  74. return (
  75. <View style = { styles.formWrapper }>
  76. <Text style = { styles.fieldLabel }>
  77. { t('lobby.nameField') }
  78. </Text>
  79. <TextInput
  80. onChangeText = { this._onChangeDisplayName }
  81. style = { styles.field }
  82. value = { displayName } />
  83. <Text style = { styles.fieldLabel }>
  84. { t('lobby.emailField') }
  85. </Text>
  86. <TextInput
  87. onChangeText = { this._onChangeEmail }
  88. style = { styles.field }
  89. value = { email } />
  90. </View>
  91. );
  92. }
  93. /**
  94. * Renders the participant info fragment when we have all the required details of the user.
  95. *
  96. * @inheritdoc
  97. */
  98. _renderParticipantInfo() {
  99. const { displayName, email } = this.state;
  100. return (
  101. <View style = { styles.participantBox }>
  102. <TouchableOpacity
  103. onPress = { this._onEnableEdit }
  104. style = { styles.editButton }>
  105. <Icon
  106. src = { IconEdit }
  107. style = { styles.editIcon } />
  108. </TouchableOpacity>
  109. <Avatar
  110. participantId = { this.props._participantId }
  111. size = { 64 } />
  112. <Text style = { styles.displayNameText }>
  113. { displayName }
  114. </Text>
  115. { Boolean(email) && <Text style = { styles.secondaryText }>
  116. { email }
  117. </Text> }
  118. </View>
  119. );
  120. }
  121. /**
  122. * Renders the password form to let the participant join by using a password instead of knocking.
  123. *
  124. * @inheritdoc
  125. */
  126. _renderPasswordForm() {
  127. const { _passwordJoinFailed, t } = this.props;
  128. return (
  129. <View style = { styles.formWrapper }>
  130. <Text style = { styles.fieldLabel }>
  131. { this.props.t('lobby.passwordField') }
  132. </Text>
  133. <TextInput
  134. autoCapitalize = 'none'
  135. autoCompleteType = 'off'
  136. onChangeText = { this._onChangePassword }
  137. secureTextEntry = { true }
  138. style = { styles.field }
  139. value = { this.state.password } />
  140. { _passwordJoinFailed && <Text style = { styles.fieldError }>
  141. { t('lobby.invalidPassword') }
  142. </Text> }
  143. </View>
  144. );
  145. }
  146. /**
  147. * Renders the password join button (set).
  148. *
  149. * @inheritdoc
  150. */
  151. _renderPasswordJoinButtons() {
  152. const { t } = this.props;
  153. return (
  154. <>
  155. <TouchableOpacity
  156. disabled = { !this.state.password }
  157. onPress = { this._onJoinWithPassword }
  158. style = { [
  159. styles.button,
  160. styles.primaryButton
  161. ] }>
  162. <Text style = { styles.primaryButtonText }>
  163. { t('lobby.passwordJoinButton') }
  164. </Text>
  165. </TouchableOpacity>
  166. <TouchableOpacity
  167. onPress = { this._onSwitchToKnockMode }
  168. style = { [
  169. styles.button,
  170. styles.secondaryButton
  171. ] }>
  172. <Text>
  173. { t('lobby.backToKnockModeButton') }
  174. </Text>
  175. </TouchableOpacity>
  176. </>
  177. );
  178. }
  179. /**
  180. * Renders the standard button set.
  181. *
  182. * @inheritdoc
  183. */
  184. _renderStandardButtons() {
  185. const { _knocking, t } = this.props;
  186. return (
  187. <>
  188. { _knocking || <TouchableOpacity
  189. disabled = { !this.state.displayName }
  190. onPress = { this._onAskToJoin }
  191. style = { [
  192. styles.button,
  193. styles.primaryButton
  194. ] }>
  195. <Text style = { styles.primaryButtonText }>
  196. { t('lobby.knockButton') }
  197. </Text>
  198. </TouchableOpacity> }
  199. <TouchableOpacity
  200. onPress = { this._onSwitchToPasswordMode }
  201. style = { [
  202. styles.button,
  203. styles.secondaryButton
  204. ] }>
  205. <Text>
  206. { t('lobby.enterPasswordButton') }
  207. </Text>
  208. </TouchableOpacity>
  209. </>
  210. );
  211. }
  212. }
  213. export default translate(connect(_mapStateToProps)(LobbyScreen));