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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. _onSwitchToKnockMode: () => void;
  45. _onSwitchToPasswordMode: () => void;
  46. _renderContent: () => React$Element<*>;
  47. /**
  48. * Renders the joining (waiting) fragment of the screen.
  49. *
  50. * @inheritdoc
  51. */
  52. _renderJoining() {
  53. return (
  54. <>
  55. <LoadingIndicator
  56. color = 'black'
  57. style = { styles.loadingIndicator } />
  58. <Text style = { styles.joiningMessage }>
  59. { this.props.t('lobby.joiningMessage') }
  60. </Text>
  61. </>
  62. );
  63. }
  64. /**
  65. * Renders the participant form to let the knocking participant enter its details.
  66. *
  67. * @inheritdoc
  68. */
  69. _renderParticipantForm() {
  70. const { t } = this.props;
  71. const { displayName, email } = this.state;
  72. return (
  73. <View style = { styles.formWrapper }>
  74. <Text style = { styles.fieldLabel }>
  75. { t('lobby.nameField') }
  76. </Text>
  77. <TextInput
  78. onChangeText = { this._onChangeDisplayName }
  79. style = { styles.field }
  80. value = { displayName } />
  81. <Text style = { styles.fieldLabel }>
  82. { t('lobby.emailField') }
  83. </Text>
  84. <TextInput
  85. onChangeText = { this._onChangeEmail }
  86. style = { styles.field }
  87. value = { email } />
  88. </View>
  89. );
  90. }
  91. /**
  92. * Renders the participant info fragment when we have all the required details of the user.
  93. *
  94. * @inheritdoc
  95. */
  96. _renderParticipantInfo() {
  97. const { displayName, email } = this.state;
  98. return (
  99. <View style = { styles.participantBox }>
  100. <TouchableOpacity
  101. onPress = { this._onEnableEdit }
  102. style = { styles.editButton }>
  103. <Icon
  104. src = { IconEdit }
  105. style = { styles.editIcon } />
  106. </TouchableOpacity>
  107. <Avatar
  108. participantId = { this.props._participantId }
  109. size = { 64 }
  110. style = { styles.avatar } />
  111. <Text style = { styles.displayNameText }>
  112. { displayName }
  113. </Text>
  114. { Boolean(email) && <Text style = { styles.secondaryText }>
  115. { email }
  116. </Text> }
  117. </View>
  118. );
  119. }
  120. /**
  121. * Renders the password form to let the participant join by using a password instead of knocking.
  122. *
  123. * @inheritdoc
  124. */
  125. _renderPasswordForm() {
  126. return (
  127. <View style = { styles.formWrapper }>
  128. <Text style = { styles.fieldLabel }>
  129. { this.props.t('lobby.passwordField') }
  130. </Text>
  131. <TextInput
  132. autoCapitalize = 'none'
  133. autoCompleteType = 'off'
  134. onChangeText = { this._onChangePassword }
  135. secureTextEntry = { true }
  136. style = { styles.field }
  137. value = { this.state.password } />
  138. </View>
  139. );
  140. }
  141. /**
  142. * Renders the password join button (set).
  143. *
  144. * @inheritdoc
  145. */
  146. _renderPasswordJoinButtons() {
  147. const { t } = this.props;
  148. return (
  149. <>
  150. <TouchableOpacity
  151. disabled = { !this.state.password }
  152. onPress = { this._onAskToJoin }
  153. style = { [
  154. styles.button,
  155. styles.primaryButton
  156. ] }>
  157. <Text style = { styles.primaryButtonText }>
  158. { t('lobby.passwordJoinButton') }
  159. </Text>
  160. </TouchableOpacity>
  161. <TouchableOpacity
  162. onPress = { this._onSwitchToKnockMode }
  163. style = { [
  164. styles.button,
  165. styles.secondaryButton
  166. ] }>
  167. <Text>
  168. { t('lobby.backToKnockModeButton') }
  169. </Text>
  170. </TouchableOpacity>
  171. </>
  172. );
  173. }
  174. /**
  175. * Renders the standard button set.
  176. *
  177. * @inheritdoc
  178. */
  179. _renderStandardButtons() {
  180. const { t } = this.props;
  181. return (
  182. <>
  183. <TouchableOpacity
  184. disabled = { !this.state.displayName }
  185. onPress = { this._onAskToJoin }
  186. style = { [
  187. styles.button,
  188. styles.primaryButton
  189. ] }>
  190. <Text style = { styles.primaryButtonText }>
  191. { t('lobby.knockButton') }
  192. </Text>
  193. </TouchableOpacity>
  194. <TouchableOpacity
  195. onPress = { this._onSwitchToPasswordMode }
  196. style = { [
  197. styles.button,
  198. styles.secondaryButton
  199. ] }>
  200. <Text>
  201. { t('lobby.enterPasswordButton') }
  202. </Text>
  203. </TouchableOpacity>
  204. </>
  205. );
  206. }
  207. }
  208. export default translate(connect(_mapStateToProps)(LobbyScreen));