Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

AbstractLobbyScreen.js 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. // @flow
  2. // eslint-disable-next-line no-unused-vars
  3. import React, { PureComponent } from 'react';
  4. import { getConferenceName } from '../../base/conference';
  5. import { getLocalParticipant } from '../../base/participants';
  6. import { getFieldValue } from '../../base/react';
  7. import { updateSettings } from '../../base/settings';
  8. import { cancelKnocking, startKnocking } from '../actions';
  9. export const SCREEN_STATES = {
  10. EDIT: 1,
  11. PASSWORD: 2,
  12. VIEW: 3
  13. };
  14. export type Props = {
  15. /**
  16. * True if knocking is already happening, so we're waiting for a response.
  17. */
  18. _knocking: boolean,
  19. /**
  20. * The name of the meeting we're about to join.
  21. */
  22. _meetingName: string,
  23. /**
  24. * The email of the participant about to knock/join.
  25. */
  26. _participantEmail: string,
  27. /**
  28. * The id of the participant about to knock/join. This is the participant ID in the lobby room, at this point.
  29. */
  30. _participantId: string,
  31. /**
  32. * The name of the participant about to knock/join.
  33. */
  34. _participantName: string;
  35. /**
  36. * The Redux dispatch function.
  37. */
  38. dispatch: Function,
  39. /**
  40. * Function to be used to translate i18n labels.
  41. */
  42. t: Function
  43. };
  44. type State = {
  45. /**
  46. * The display name value entered into the field.
  47. */
  48. displayName: string,
  49. /**
  50. * The email value entered into the field.
  51. */
  52. email: string,
  53. /**
  54. * The password value entered into the field.
  55. */
  56. password: string,
  57. /**
  58. * The state of the screen. One of {@code SCREEN_STATES[*]}
  59. */
  60. screenState: number
  61. }
  62. /**
  63. * Abstract class to encapsulate the platform common code of the {@code LobbyScreen}.
  64. */
  65. export default class AbstractLobbyScreen extends PureComponent<Props, State> {
  66. /**
  67. * Instantiates a new component.
  68. *
  69. * @inheritdoc
  70. */
  71. constructor(props: Props) {
  72. super(props);
  73. this.state = {
  74. displayName: props._participantName || '',
  75. email: props._participantEmail || '',
  76. password: '',
  77. screenState: props._participantName ? SCREEN_STATES.VIEW : SCREEN_STATES.EDIT
  78. };
  79. this._onAskToJoin = this._onAskToJoin.bind(this);
  80. this._onCancel = this._onCancel.bind(this);
  81. this._onChangeDisplayName = this._onChangeDisplayName.bind(this);
  82. this._onChangeEmail = this._onChangeEmail.bind(this);
  83. this._onChangePassword = this._onChangePassword.bind(this);
  84. this._onEnableEdit = this._onEnableEdit.bind(this);
  85. this._onSwitchToKnockMode = this._onSwitchToKnockMode.bind(this);
  86. this._onSwitchToPasswordMode = this._onSwitchToPasswordMode.bind(this);
  87. }
  88. /**
  89. * Returns the screen title.
  90. *
  91. * @returns {string}
  92. */
  93. _getScreenTitleKey() {
  94. const withPassword = Boolean(this.state.password);
  95. return this.props._knocking
  96. ? withPassword ? 'lobby.joiningWithPasswordTitle' : 'lobby.joiningTitle'
  97. : 'lobby.joinTitle';
  98. }
  99. _onAskToJoin: () => void;
  100. /**
  101. * Callback to be invoked when the user submits the joining request.
  102. *
  103. * @returns {void}
  104. */
  105. _onAskToJoin() {
  106. this.props.dispatch(startKnocking(this.state.password));
  107. return false;
  108. }
  109. _onCancel: () => boolean;
  110. /**
  111. * Callback to be invoked when the user cancels the dialog.
  112. *
  113. * @private
  114. * @returns {boolean}
  115. */
  116. _onCancel() {
  117. this.props.dispatch(cancelKnocking());
  118. return true;
  119. }
  120. _onChangeDisplayName: Object => void;
  121. /**
  122. * Callback to be invoked when the user changes its display name.
  123. *
  124. * @param {SyntheticEvent} event - The SyntheticEvent instance of the change.
  125. * @returns {void}
  126. */
  127. _onChangeDisplayName(event) {
  128. const displayName = getFieldValue(event);
  129. this.setState({
  130. displayName
  131. }, () => {
  132. this.props.dispatch(updateSettings({
  133. displayName
  134. }));
  135. });
  136. }
  137. _onChangeEmail: Object => void;
  138. /**
  139. * Callback to be invoked when the user changes its email.
  140. *
  141. * @param {SyntheticEvent} event - The SyntheticEvent instance of the change.
  142. * @returns {void}
  143. */
  144. _onChangeEmail(event) {
  145. const email = getFieldValue(event);
  146. this.setState({
  147. email
  148. }, () => {
  149. this.props.dispatch(updateSettings({
  150. email
  151. }));
  152. });
  153. }
  154. _onChangePassword: Object => void;
  155. /**
  156. * Callback to be invoked when the user changes the password.
  157. *
  158. * @param {SyntheticEvent} event - The SyntheticEvent instance of the change.
  159. * @returns {void}
  160. */
  161. _onChangePassword(event) {
  162. this.setState({
  163. password: getFieldValue(event)
  164. });
  165. }
  166. _onEnableEdit: () => void;
  167. /**
  168. * Callback to be invoked for the edit button.
  169. *
  170. * @returns {void}
  171. */
  172. _onEnableEdit() {
  173. this.setState({
  174. screenState: SCREEN_STATES.EDIT
  175. });
  176. }
  177. _onSwitchToKnockMode: () => void;
  178. /**
  179. * Callback to be invoked for the enter (go back to) knocking mode button.
  180. *
  181. * @returns {void}
  182. */
  183. _onSwitchToKnockMode() {
  184. this.setState({
  185. screenState: this.state.displayName ? SCREEN_STATES.VIEW : SCREEN_STATES.EDIT
  186. });
  187. }
  188. _onSwitchToPasswordMode: () => void;
  189. /**
  190. * Callback to be invoked for the enter password button.
  191. *
  192. * @returns {void}
  193. */
  194. _onSwitchToPasswordMode() {
  195. this.setState({
  196. screenState: SCREEN_STATES.PASSWORD
  197. });
  198. }
  199. /**
  200. * Renders the content of the dialog.
  201. *
  202. * @returns {React$Element}
  203. */
  204. _renderContent() {
  205. const { _knocking } = this.props;
  206. const { password, screenState } = this.state;
  207. const withPassword = Boolean(password);
  208. if (_knocking) {
  209. return this._renderJoining(withPassword);
  210. }
  211. return (
  212. <>
  213. { screenState === SCREEN_STATES.VIEW && this._renderParticipantInfo() }
  214. { screenState === SCREEN_STATES.EDIT && this._renderParticipantForm() }
  215. { screenState === SCREEN_STATES.PASSWORD && this._renderPasswordForm() }
  216. { (screenState === SCREEN_STATES.VIEW || screenState === SCREEN_STATES.EDIT)
  217. && this._renderStandardButtons() }
  218. { screenState === SCREEN_STATES.PASSWORD && this._renderPasswordJoinButtons() }
  219. </>
  220. );
  221. }
  222. /**
  223. * Renders the joining (waiting) fragment of the screen.
  224. *
  225. * @param {boolean} withPassword - True if we're joining with a password. False otherwise.
  226. * @returns {React$Element}
  227. */
  228. _renderJoining: boolean => React$Element<*>;
  229. /**
  230. * Renders the participant form to let the knocking participant enter its details.
  231. *
  232. * @returns {React$Element}
  233. */
  234. _renderParticipantForm: () => React$Element<*>;
  235. /**
  236. * Renders the participant info fragment when we have all the required details of the user.
  237. *
  238. * @returns {React$Element}
  239. */
  240. _renderParticipantInfo: () => React$Element<*>;
  241. /**
  242. * Renders the password form to let the participant join by using a password instead of knocking.
  243. *
  244. * @returns {React$Element}
  245. */
  246. _renderPasswordForm: () => React$Element<*>;
  247. /**
  248. * Renders the password join button (set).
  249. *
  250. * @returns {React$Element}
  251. */
  252. _renderPasswordJoinButtons: () => React$Element<*>;
  253. /**
  254. * Renders the standard button set.
  255. *
  256. * @returns {React$Element}
  257. */
  258. _renderStandardButtons: () => React$Element<*>;
  259. }
  260. /**
  261. * Maps part of the Redux state to the props of this component.
  262. *
  263. * @param {Object} state - The Redux state.
  264. * @returns {Props}
  265. */
  266. export function _mapStateToProps(state: Object): $Shape<Props> {
  267. const localParticipant = getLocalParticipant(state);
  268. const participantId = localParticipant?.id;
  269. return {
  270. _knocking: state['features/lobby'].knocking,
  271. _meetingName: getConferenceName(state),
  272. _participantEmail: localParticipant.email,
  273. _participantId: participantId,
  274. _participantName: localParticipant.name
  275. };
  276. }