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.

PasswordForm.tsx 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import React, { Component } from 'react';
  2. import { WithTranslation } from 'react-i18next';
  3. import { translate } from '../../../../base/i18n/functions';
  4. import Input from '../../../../base/ui/components/web/Input';
  5. import { LOCKED_LOCALLY } from '../../../../room-lock/constants';
  6. /**
  7. * The type of the React {@code Component} props of {@link PasswordForm}.
  8. */
  9. interface IProps extends WithTranslation {
  10. /**
  11. * Whether or not to show the password editing field.
  12. */
  13. editEnabled: boolean;
  14. /**
  15. * The value for how the conference is locked (or undefined if not locked)
  16. * as defined by room-lock constants.
  17. */
  18. locked: string;
  19. /**
  20. * Callback to invoke when the local participant is submitting a password
  21. * set request.
  22. */
  23. onSubmit: Function;
  24. /**
  25. * The current known password for the JitsiConference.
  26. */
  27. password: string;
  28. /**
  29. * The number of digits to be used in the password.
  30. */
  31. passwordNumberOfDigits?: number;
  32. /**
  33. * Whether or not the password should be visible.
  34. */
  35. visible: boolean;
  36. }
  37. /**
  38. * The type of the React {@code Component} state of {@link PasswordForm}.
  39. */
  40. interface IState {
  41. /**
  42. * The value of the password being entered by the local participant.
  43. */
  44. enteredPassword: string;
  45. }
  46. /**
  47. * React {@code Component} for displaying and editing the conference password.
  48. *
  49. * @augments Component
  50. */
  51. class PasswordForm extends Component<IProps, IState> {
  52. /**
  53. * Implements React's {@link Component#getDerivedStateFromProps()}.
  54. *
  55. * @inheritdoc
  56. */
  57. static getDerivedStateFromProps(props: IProps, state: IState) {
  58. return {
  59. enteredPassword: props.editEnabled ? state.enteredPassword : ''
  60. };
  61. }
  62. state = {
  63. enteredPassword: ''
  64. };
  65. /**
  66. * Initializes a new {@code PasswordForm} instance.
  67. *
  68. * @param {IProps} props - The React {@code Component} props to initialize
  69. * the new {@code PasswordForm} instance with.
  70. */
  71. constructor(props: IProps) {
  72. super(props);
  73. // Bind event handlers so they are only bound once per instance.
  74. this._onEnteredPasswordChange = this._onEnteredPasswordChange.bind(this);
  75. this._onKeyPress = this._onKeyPress.bind(this);
  76. }
  77. /**
  78. * Implements React's {@link Component#render()}.
  79. *
  80. * @inheritdoc
  81. * @returns {ReactElement}
  82. */
  83. render() {
  84. return (
  85. <div className = 'info-password'>
  86. {this._renderPassword()}
  87. {this._renderPasswordField()}
  88. </div>
  89. );
  90. }
  91. /** .........
  92. * Renders the password if there is any.
  93. *
  94. * @returns {ReactElement}
  95. */
  96. _renderPassword() {
  97. const { locked, t } = this.props;
  98. return locked && <>
  99. <span className = 'info-label'>
  100. {t('info.password')}
  101. </span>
  102. <span className = 'spacer'>&nbsp;</span>
  103. <span className = 'info-password-field info-value'>
  104. {locked === LOCKED_LOCALLY ? (
  105. <div className = 'info-password-local'>
  106. {this.props.visible ? this.props.password : '******' }
  107. </div>
  108. ) : (
  109. <div className = 'info-password-remote'>
  110. {this.props.t('passwordSetRemotely')}
  111. </div>
  112. ) }
  113. {this._renderPasswordField()}
  114. </span>
  115. </>;
  116. }
  117. /**
  118. * Returns a ReactElement for showing the current state of the password or
  119. * for editing the current password.
  120. *
  121. * @private
  122. * @returns {ReactElement}
  123. */
  124. _renderPasswordField() {
  125. if (this.props.editEnabled) {
  126. let placeHolderText = this.props.t('dialog.password');
  127. if (this.props.passwordNumberOfDigits) {
  128. placeHolderText = this.props.t('passwordDigitsOnly', {
  129. number: this.props.passwordNumberOfDigits });
  130. }
  131. return (
  132. <div
  133. className = 'info-password-form'>
  134. <Input
  135. accessibilityLabel = { this.props.t('info.addPassword') }
  136. autoFocus = { true }
  137. id = 'info-password-input'
  138. maxLength = { this.props.passwordNumberOfDigits }
  139. onChange = { this._onEnteredPasswordChange }
  140. onKeyPress = { this._onKeyPress }
  141. placeholder = { placeHolderText }
  142. type = 'password'
  143. value = { this.state.enteredPassword } />
  144. </div>
  145. );
  146. }
  147. }
  148. /**
  149. * Updates the internal state of entered password.
  150. *
  151. * @param {string} value - DOM Event for value change.
  152. * @private
  153. * @returns {void}
  154. */
  155. _onEnteredPasswordChange(value: string) {
  156. this.setState({ enteredPassword: value });
  157. }
  158. /**
  159. * Stops the the EnterKey for propagation in order to prevent the dialog
  160. * to close.
  161. *
  162. * @param {Object} event - The key event.
  163. * @private
  164. * @returns {void}
  165. */
  166. _onKeyPress(event: React.KeyboardEvent) {
  167. if (event.key === 'Enter') {
  168. event.preventDefault();
  169. event.stopPropagation();
  170. this.props.onSubmit(this.state.enteredPassword);
  171. }
  172. }
  173. }
  174. export default translate(PasswordForm);