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.

E2EESection.tsx 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import React, { Component } from 'react';
  2. import { WithTranslation } from 'react-i18next';
  3. import { createE2EEEvent } from '../../analytics/AnalyticsEvents';
  4. import { sendAnalytics } from '../../analytics/functions';
  5. import { IReduxState, IStore } from '../../app/types';
  6. import { translate } from '../../base/i18n/functions';
  7. import { connect } from '../../base/redux/functions';
  8. import Switch from '../../base/ui/components/web/Switch';
  9. import { toggleE2EE } from '../actions';
  10. import { MAX_MODE } from '../constants';
  11. import { doesEveryoneSupportE2EE } from '../functions';
  12. interface IProps extends WithTranslation {
  13. /**
  14. * The resource for the description, computed based on the maxMode and whether the switch is toggled or not.
  15. */
  16. _descriptionResource: string;
  17. /**
  18. * Custom e2ee labels.
  19. */
  20. _e2eeLabels: any;
  21. /**
  22. * Whether the switch is currently enabled or not.
  23. */
  24. _enabled: boolean;
  25. /**
  26. * Indicates whether all participants in the conference currently support E2EE.
  27. */
  28. _everyoneSupportE2EE: boolean;
  29. /**
  30. * Whether E2EE is currently enabled or not.
  31. */
  32. _toggled: boolean;
  33. /**
  34. * The redux {@code dispatch} function.
  35. */
  36. dispatch: IStore['dispatch'];
  37. }
  38. interface IState {
  39. /**
  40. * True if the switch is toggled on.
  41. */
  42. toggled: boolean;
  43. }
  44. /**
  45. * Implements a React {@code Component} for displaying a security dialog section with a field
  46. * for setting the E2EE key.
  47. *
  48. * @augments Component
  49. */
  50. class E2EESection extends Component<IProps, IState> {
  51. /**
  52. * Implements React's {@link Component#getDerivedStateFromProps()}.
  53. *
  54. * @inheritdoc
  55. */
  56. static getDerivedStateFromProps(props: IProps, state: IState) {
  57. if (props._toggled !== state.toggled) {
  58. return {
  59. toggled: props._toggled
  60. };
  61. }
  62. return null;
  63. }
  64. /**
  65. * Instantiates a new component.
  66. *
  67. * @inheritdoc
  68. */
  69. constructor(props: IProps) {
  70. super(props);
  71. this.state = {
  72. toggled: false
  73. };
  74. // Bind event handlers so they are only bound once for every instance.
  75. this._onToggle = this._onToggle.bind(this);
  76. }
  77. /**
  78. * Implements React's {@link Component#render()}.
  79. *
  80. * @inheritdoc
  81. * @returns {ReactElement}
  82. */
  83. render() {
  84. const { _descriptionResource, _enabled, _e2eeLabels, _everyoneSupportE2EE, t } = this.props;
  85. const { toggled } = this.state;
  86. const description = _e2eeLabels?.description || t(_descriptionResource);
  87. const label = _e2eeLabels?.label || t('dialog.e2eeLabel');
  88. const warning = _e2eeLabels?.warning || t('dialog.e2eeWarning');
  89. return (
  90. <div id = 'e2ee-section'>
  91. <p
  92. aria-live = 'polite'
  93. className = 'description'
  94. id = 'e2ee-section-description'>
  95. { description }
  96. { !_everyoneSupportE2EE && <br /> }
  97. { !_everyoneSupportE2EE && warning }
  98. </p>
  99. <div className = 'control-row'>
  100. <label htmlFor = 'e2ee-section-switch'>
  101. { label }
  102. </label>
  103. <Switch
  104. checked = { toggled }
  105. disabled = { !_enabled }
  106. id = 'e2ee-section-switch'
  107. onChange = { this._onToggle } />
  108. </div>
  109. </div>
  110. );
  111. }
  112. /**
  113. * Callback to be invoked when the user toggles E2EE on or off.
  114. *
  115. * @private
  116. * @returns {void}
  117. */
  118. _onToggle() {
  119. const newValue = !this.state.toggled;
  120. this.setState({
  121. toggled: newValue
  122. });
  123. sendAnalytics(createE2EEEvent(`enabled.${String(newValue)}`));
  124. this.props.dispatch(toggleE2EE(newValue));
  125. }
  126. }
  127. /**
  128. * Maps (parts of) the Redux state to the associated props for this component.
  129. *
  130. * @param {Object} state - The Redux state.
  131. * @private
  132. * @returns {IProps}
  133. */
  134. function mapStateToProps(state: IReduxState) {
  135. const { enabled: e2eeEnabled, maxMode } = state['features/e2ee'];
  136. const { e2eeLabels } = state['features/base/config'];
  137. let descriptionResource: string | undefined = '';
  138. if (e2eeLabels) {
  139. // When e2eeLabels are present, the descriptionResouse is ignored.
  140. descriptionResource = undefined;
  141. } else if (maxMode === MAX_MODE.THRESHOLD_EXCEEDED) {
  142. descriptionResource = 'dialog.e2eeDisabledDueToMaxModeDescription';
  143. } else if (maxMode === MAX_MODE.ENABLED) {
  144. descriptionResource = e2eeEnabled
  145. ? 'dialog.e2eeWillDisableDueToMaxModeDescription' : 'dialog.e2eeDisabledDueToMaxModeDescription';
  146. } else {
  147. descriptionResource = 'dialog.e2eeDescription';
  148. }
  149. return {
  150. _descriptionResource: descriptionResource,
  151. _e2eeLabels: e2eeLabels,
  152. _enabled: maxMode === MAX_MODE.DISABLED || e2eeEnabled,
  153. _toggled: e2eeEnabled,
  154. _everyoneSupportE2EE: doesEveryoneSupportE2EE(state)
  155. };
  156. }
  157. export default translate(connect(mapStateToProps)(E2EESection));