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.5KB

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