|
@@ -1,17 +1,17 @@
|
1
|
|
-import React, { Component } from 'react';
|
2
|
|
-import { WithTranslation } from 'react-i18next';
|
|
1
|
+import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
+import { useTranslation } from 'react-i18next';
|
3
|
3
|
import { connect } from 'react-redux';
|
|
4
|
+import { makeStyles } from 'tss-react/mui';
|
4
|
5
|
|
5
|
6
|
import { createE2EEEvent } from '../../analytics/AnalyticsEvents';
|
6
|
7
|
import { sendAnalytics } from '../../analytics/functions';
|
7
|
8
|
import { IReduxState, IStore } from '../../app/types';
|
8
|
|
-import { translate } from '../../base/i18n/functions';
|
9
|
9
|
import Switch from '../../base/ui/components/web/Switch';
|
10
|
10
|
import { toggleE2EE } from '../actions';
|
11
|
11
|
import { MAX_MODE } from '../constants';
|
12
|
12
|
import { doesEveryoneSupportE2EE } from '../functions';
|
13
|
13
|
|
14
|
|
-interface IProps extends WithTranslation {
|
|
14
|
+interface IProps {
|
15
|
15
|
|
16
|
16
|
/**
|
17
|
17
|
* The resource for the description, computed based on the maxMode and whether the switch is toggled or not.
|
|
@@ -44,89 +44,53 @@ interface IProps extends WithTranslation {
|
44
|
44
|
dispatch: IStore['dispatch'];
|
45
|
45
|
}
|
46
|
46
|
|
47
|
|
-interface IState {
|
48
|
|
-
|
49
|
|
- /**
|
50
|
|
- * True if the switch is toggled on.
|
51
|
|
- */
|
52
|
|
- toggled: boolean;
|
53
|
|
-}
|
|
47
|
+const useStyles = makeStyles()(() => {
|
|
48
|
+ return {
|
|
49
|
+ e2eeSection: {
|
|
50
|
+ display: 'flex',
|
|
51
|
+ flexDirection: 'column'
|
|
52
|
+ },
|
|
53
|
+
|
|
54
|
+ description: {
|
|
55
|
+ fontSize: '13px',
|
|
56
|
+ margin: '15px 0'
|
|
57
|
+ },
|
|
58
|
+
|
|
59
|
+ controlRow: {
|
|
60
|
+ display: 'flex',
|
|
61
|
+ justifyContent: 'space-between',
|
|
62
|
+ marginTop: '15px',
|
|
63
|
+
|
|
64
|
+ '& label': {
|
|
65
|
+ fontSize: '14px',
|
|
66
|
+ fontWeight: 'bold'
|
|
67
|
+ }
|
|
68
|
+ }
|
|
69
|
+ };
|
|
70
|
+});
|
54
|
71
|
|
55
|
72
|
/**
|
56
|
73
|
* Implements a React {@code Component} for displaying a security dialog section with a field
|
57
|
74
|
* for setting the E2EE key.
|
58
|
75
|
*
|
59
|
|
- * @augments Component
|
|
76
|
+ * @param {IProps} props - Component's props.
|
|
77
|
+ * @returns {JSX}
|
60
|
78
|
*/
|
61
|
|
-class E2EESection extends Component<IProps, IState> {
|
62
|
|
- /**
|
63
|
|
- * Implements React's {@link Component#getDerivedStateFromProps()}.
|
64
|
|
- *
|
65
|
|
- * @inheritdoc
|
66
|
|
- */
|
67
|
|
- static getDerivedStateFromProps(props: IProps, state: IState) {
|
68
|
|
- if (props._toggled !== state.toggled) {
|
69
|
|
-
|
70
|
|
- return {
|
71
|
|
- toggled: props._toggled
|
72
|
|
- };
|
73
|
|
- }
|
74
|
|
-
|
75
|
|
- return null;
|
76
|
|
- }
|
77
|
|
-
|
78
|
|
- /**
|
79
|
|
- * Instantiates a new component.
|
80
|
|
- *
|
81
|
|
- * @inheritdoc
|
82
|
|
- */
|
83
|
|
- constructor(props: IProps) {
|
84
|
|
- super(props);
|
85
|
|
-
|
86
|
|
- this.state = {
|
87
|
|
- toggled: false
|
88
|
|
- };
|
89
|
|
-
|
90
|
|
- // Bind event handlers so they are only bound once for every instance.
|
91
|
|
- this._onToggle = this._onToggle.bind(this);
|
92
|
|
- }
|
93
|
|
-
|
94
|
|
- /**
|
95
|
|
- * Implements React's {@link Component#render()}.
|
96
|
|
- *
|
97
|
|
- * @inheritdoc
|
98
|
|
- * @returns {ReactElement}
|
99
|
|
- */
|
100
|
|
- render() {
|
101
|
|
- const { _descriptionResource, _enabled, _e2eeLabels, _everyoneSupportE2EE, t } = this.props;
|
102
|
|
- const { toggled } = this.state;
|
103
|
|
- const description = _e2eeLabels?.description || t(_descriptionResource ?? '');
|
104
|
|
- const label = _e2eeLabels?.label || t('dialog.e2eeLabel');
|
105
|
|
- const warning = _e2eeLabels?.warning || t('dialog.e2eeWarning');
|
106
|
|
-
|
107
|
|
- return (
|
108
|
|
- <div id = 'e2ee-section'>
|
109
|
|
- <p
|
110
|
|
- aria-live = 'polite'
|
111
|
|
- className = 'description'
|
112
|
|
- id = 'e2ee-section-description'>
|
113
|
|
- { description }
|
114
|
|
- { !_everyoneSupportE2EE && <br /> }
|
115
|
|
- { !_everyoneSupportE2EE && warning }
|
116
|
|
- </p>
|
117
|
|
- <div className = 'control-row'>
|
118
|
|
- <label htmlFor = 'e2ee-section-switch'>
|
119
|
|
- { label }
|
120
|
|
- </label>
|
121
|
|
- <Switch
|
122
|
|
- checked = { toggled }
|
123
|
|
- disabled = { !_enabled }
|
124
|
|
- id = 'e2ee-section-switch'
|
125
|
|
- onChange = { this._onToggle } />
|
126
|
|
- </div>
|
127
|
|
- </div>
|
128
|
|
- );
|
129
|
|
- }
|
|
79
|
+const E2EESection = ({
|
|
80
|
+ _descriptionResource,
|
|
81
|
+ _enabled,
|
|
82
|
+ _e2eeLabels,
|
|
83
|
+ _everyoneSupportE2EE,
|
|
84
|
+ _toggled,
|
|
85
|
+ dispatch
|
|
86
|
+}: IProps) => {
|
|
87
|
+ const { classes } = useStyles();
|
|
88
|
+ const { t } = useTranslation();
|
|
89
|
+ const [ toggled, setToggled ] = useState(_toggled ?? false);
|
|
90
|
+
|
|
91
|
+ useEffect(() => {
|
|
92
|
+ setToggled(_toggled);
|
|
93
|
+ }, [ _toggled ]);
|
130
|
94
|
|
131
|
95
|
/**
|
132
|
96
|
* Callback to be invoked when the user toggles E2EE on or off.
|
|
@@ -134,17 +98,44 @@ class E2EESection extends Component<IProps, IState> {
|
134
|
98
|
* @private
|
135
|
99
|
* @returns {void}
|
136
|
100
|
*/
|
137
|
|
- _onToggle() {
|
138
|
|
- const newValue = !this.state.toggled;
|
|
101
|
+ const _onToggle = useCallback(() => {
|
|
102
|
+ const newValue = !toggled;
|
139
|
103
|
|
140
|
|
- this.setState({
|
141
|
|
- toggled: newValue
|
142
|
|
- });
|
|
104
|
+ setToggled(newValue);
|
143
|
105
|
|
144
|
106
|
sendAnalytics(createE2EEEvent(`enabled.${String(newValue)}`));
|
145
|
|
- this.props.dispatch(toggleE2EE(newValue));
|
146
|
|
- }
|
147
|
|
-}
|
|
107
|
+ dispatch(toggleE2EE(newValue));
|
|
108
|
+ }, [ toggled ]);
|
|
109
|
+
|
|
110
|
+ const description = _e2eeLabels?.description || t(_descriptionResource ?? '');
|
|
111
|
+ const label = _e2eeLabels?.label || t('dialog.e2eeLabel');
|
|
112
|
+ const warning = _e2eeLabels?.warning || t('dialog.e2eeWarning');
|
|
113
|
+
|
|
114
|
+ return (
|
|
115
|
+ <div
|
|
116
|
+ className = { classes.e2eeSection }
|
|
117
|
+ id = 'e2ee-section'>
|
|
118
|
+ <p
|
|
119
|
+ aria-live = 'polite'
|
|
120
|
+ className = { classes.description }
|
|
121
|
+ id = 'e2ee-section-description'>
|
|
122
|
+ {description}
|
|
123
|
+ {!_everyoneSupportE2EE && <br />}
|
|
124
|
+ {!_everyoneSupportE2EE && warning}
|
|
125
|
+ </p>
|
|
126
|
+ <div className = { classes.controlRow }>
|
|
127
|
+ <label htmlFor = 'e2ee-section-switch'>
|
|
128
|
+ {label}
|
|
129
|
+ </label>
|
|
130
|
+ <Switch
|
|
131
|
+ checked = { toggled }
|
|
132
|
+ disabled = { !_enabled }
|
|
133
|
+ id = 'e2ee-section-switch'
|
|
134
|
+ onChange = { _onToggle } />
|
|
135
|
+ </div>
|
|
136
|
+ </div>
|
|
137
|
+ );
|
|
138
|
+};
|
148
|
139
|
|
149
|
140
|
/**
|
150
|
141
|
* Maps (parts of) the Redux state to the associated props for this component.
|
|
@@ -180,4 +171,4 @@ function mapStateToProps(state: IReduxState) {
|
180
|
171
|
};
|
181
|
172
|
}
|
182
|
173
|
|
183
|
|
-export default translate(connect(mapStateToProps)(E2EESection));
|
|
174
|
+export default connect(mapStateToProps)(E2EESection);
|