Browse Source

ref(ui-components) Improve native and web Switch (#12061)

Bring Switch component more in line
Convert some files to TS
factor2
Robert Pintilii 3 years ago
parent
commit
8dd71a921b
No account linked to committer's email address

+ 35
- 0
react/features/base/ui/components/native/Switch.tsx View File

@@ -0,0 +1,35 @@
1
+import React from 'react';
2
+import { ColorValue } from 'react-native';
3
+import { Switch as NativeSwitch } from 'react-native-paper';
4
+
5
+import { SwitchProps } from '../types';
6
+
7
+interface Props extends SwitchProps {
8
+
9
+    /**
10
+     * Custom styles for the switch.
11
+     */
12
+    style?: Object;
13
+
14
+    /**
15
+     * Color of the switch button.
16
+     */
17
+    thumbColor?: ColorValue;
18
+
19
+    /**
20
+     * Color of the switch background.
21
+     */
22
+    trackColor?: Object;
23
+}
24
+
25
+const Switch = ({ checked, disabled, onChange, thumbColor, trackColor, style }: Props) => (
26
+    <NativeSwitch
27
+        disabled = { disabled }
28
+        onValueChange = { onChange }
29
+        style = { style }
30
+        thumbColor = { thumbColor }
31
+        trackColor = { trackColor }
32
+        value = { checked } />
33
+);
34
+
35
+export default Switch;

+ 18
- 0
react/features/base/ui/components/types.ts View File

@@ -77,3 +77,21 @@ export interface InputProps {
77 77
      */
78 78
     value: string | number;
79 79
 }
80
+
81
+export interface SwitchProps {
82
+
83
+    /**
84
+     * Whether or not the toggle is on.
85
+     */
86
+    checked: boolean;
87
+
88
+    /**
89
+     * Whether or not the toggle is disabled.
90
+     */
91
+    disabled?: boolean;
92
+
93
+    /**
94
+     * Toggle change callback.
95
+     */
96
+    onChange: (on?: boolean) => void;
97
+}

+ 3
- 17
react/features/base/ui/components/web/Switch.tsx View File

@@ -3,28 +3,14 @@ import clsx from 'clsx';
3 3
 import React, { useCallback } from 'react';
4 4
 
5 5
 import { isMobileBrowser } from '../../../environment/utils';
6
+import { SwitchProps } from '../types';
6 7
 
7
-interface SwitchProps {
8
-
9
-    /**
10
-     * Whether or not the toggle is on.
11
-     */
12
-    checked: boolean;
13
-
14
-    /**
15
-     * Whether or not the toggle is disabled.
16
-     */
17
-    disabled?: boolean;
8
+interface Props extends SwitchProps {
18 9
 
19 10
     /**
20 11
      * Id of the toggle.
21 12
      */
22 13
     id?: string;
23
-
24
-    /**
25
-     * Toggle change callback.
26
-     */
27
-    onChange: (on?: boolean) => void;
28 14
 }
29 15
 
30 16
 const useStyles = makeStyles((theme: any) => {
@@ -92,7 +78,7 @@ const useStyles = makeStyles((theme: any) => {
92 78
     };
93 79
 });
94 80
 
95
-const Switch = ({ id, checked, disabled, onChange }: SwitchProps) => {
81
+const Switch = ({ id, checked, disabled, onChange }: Props) => {
96 82
     const styles = useStyles();
97 83
     const isMobile = isMobileBrowser();
98 84
 

react/features/lobby/components/native/LobbyModeSwitch.js → react/features/lobby/components/native/LobbyModeSwitch.tsx View File

@@ -1,22 +1,25 @@
1
-// @flow
2
-
3 1
 import React from 'react';
4
-import { Switch, View } from 'react-native';
2
+import { WithTranslation } from 'react-i18next';
3
+import { View } from 'react-native';
5 4
 
6
-import { translate } from '../../../base/i18n';
7
-import { connect } from '../../../base/redux';
5
+import { translate } from '../../../base/i18n/functions';
6
+import { connect } from '../../../base/redux/functions';
7
+import Switch from '../../../base/ui/components/native/Switch';
8 8
 import {
9 9
     DISABLED_TRACK_COLOR,
10 10
     ENABLED_TRACK_COLOR,
11 11
     THUMB_COLOR
12
+
13
+    // @ts-ignore
12 14
 } from '../../../settings/components/native/styles';
13 15
 
16
+// @ts-ignore
14 17
 import styles from './styles';
15 18
 
16 19
 /**
17 20
  * The type of the React {@code Component} props of {@link LobbyModeSwitch}.
18 21
  */
19
-type Props = {
22
+interface Props extends WithTranslation {
20 23
 
21 24
     /**
22 25
      * True if the lobby mode is currently enabled for this conference.
@@ -26,8 +29,8 @@ type Props = {
26 29
     /**
27 30
      * Callback to be invoked when handling enable-disable lobby mode switch.
28 31
      */
29
-    onToggleLobbyMode: Function
30
-};
32
+    onToggleLobbyMode: (on?: boolean) => void;
33
+}
31 34
 
32 35
 /**
33 36
  * Component meant to Enable/Disable lobby mode.
@@ -43,14 +46,14 @@ function LobbyModeSwitch(
43 46
     return (
44 47
         <View style = { styles.lobbySwitchContainer }>
45 48
             <Switch
46
-                onValueChange = { onToggleLobbyMode }
49
+                checked = { lobbyEnabled }
50
+                onChange = { onToggleLobbyMode }
47 51
                 style = { styles.lobbySwitchIcon }
48 52
                 thumbColor = { THUMB_COLOR }
49 53
                 trackColor = {{
50 54
                     true: ENABLED_TRACK_COLOR,
51 55
                     false: DISABLED_TRACK_COLOR
52
-                }}
53
-                value = { lobbyEnabled } />
56
+                }} />
54 57
         </View>
55 58
     );
56 59
 }

react/features/polls/components/AbstractPollAnswer.js → react/features/polls/components/AbstractPollAnswer.tsx View File

@@ -1,16 +1,17 @@
1
-// @flow
2
-
3
-import React, { useCallback, useState } from 'react';
4
-import type { AbstractComponent } from 'react';
1
+/* eslint-disable lines-around-comment */
2
+import React, { ComponentType, useCallback, useState } from 'react';
5 3
 import { useTranslation } from 'react-i18next';
6 4
 import { useDispatch, useSelector } from 'react-redux';
7 5
 
6
+// @ts-ignore
8 7
 import { sendAnalytics, createPollEvent } from '../../analytics';
9
-import { getLocalParticipant, getParticipantById } from '../../base/participants';
8
+import { IState } from '../../app/types';
9
+import { getLocalParticipant, getParticipantById } from '../../base/participants/functions';
10 10
 import { useBoundSelector } from '../../base/util/hooks';
11
+// @ts-ignore
11 12
 import { registerVote, setVoteChanging } from '../actions';
12 13
 import { COMMAND_ANSWER_POLL } from '../constants';
13
-import type { Poll } from '../types';
14
+import { Poll } from '../types';
14 15
 
15 16
 /**
16 17
  * The type of the React {@code Component} props of inheriting component.
@@ -24,13 +25,13 @@ type InputProps = {
24 25
  * concrete implementations (web/native).
25 26
  **/
26 27
 export type AbstractProps = {
27
-    checkBoxStates: Function,
28
+    checkBoxStates: boolean[],
28 29
     creatorName: string,
29 30
     poll: Poll,
30 31
     setCheckbox: Function,
31
-    skipAnswer: Function,
32
-    skipChangeVote: Function,
33
-    submitAnswer: Function,
32
+    skipAnswer: () => void,
33
+    skipChangeVote: () => void,
34
+    submitAnswer: () => void,
34 35
     t: Function,
35 36
 };
36 37
 
@@ -41,13 +42,13 @@ export type AbstractProps = {
41 42
  * @param {React.AbstractComponent} Component - The concrete component.
42 43
  * @returns {React.AbstractComponent}
43 44
  */
44
-const AbstractPollAnswer = (Component: AbstractComponent<AbstractProps>) => (props: InputProps) => {
45
+const AbstractPollAnswer = (Component: ComponentType<AbstractProps>) => (props: InputProps) => {
45 46
 
46 47
     const { pollId } = props;
47 48
 
48
-    const conference: Object = useSelector(state => state['features/base/conference'].conference);
49
+    const conference: any = useSelector((state: IState) => state['features/base/conference'].conference);
49 50
 
50
-    const poll: Poll = useSelector(state => state['features/polls'].polls[pollId]);
51
+    const poll: Poll = useSelector((state: any) => state['features/polls'].polls[pollId]);
51 52
 
52 53
     const { id: localId } = useSelector(getLocalParticipant);
53 54
 

react/features/polls/components/native/PollAnswer.js → react/features/polls/components/native/PollAnswer.tsx View File

@@ -1,17 +1,18 @@
1
-// @flow
2
-
1
+/* eslint-disable lines-around-comment */
3 2
 import React from 'react';
4
-import { Switch, Text, View } from 'react-native';
3
+import { Text, View } from 'react-native';
5 4
 import { useSelector } from 'react-redux';
6 5
 
7
-import { getLocalParticipant } from '../../../base/participants';
6
+import { getLocalParticipant } from '../../../base/participants/functions';
8 7
 import BaseTheme from '../../../base/ui/components/BaseTheme.native';
9 8
 import Button from '../../../base/ui/components/native/Button';
9
+import Switch from '../../../base/ui/components/native/Switch';
10 10
 import { BUTTON_TYPES } from '../../../base/ui/constants';
11
+// @ts-ignore
11 12
 import { isSubmitAnswerDisabled } from '../../functions';
12
-import AbstractPollAnswer from '../AbstractPollAnswer';
13
-import type { AbstractProps } from '../AbstractPollAnswer';
13
+import AbstractPollAnswer, { AbstractProps } from '../AbstractPollAnswer';
14 14
 
15
+// @ts-ignore
15 16
 import { chatStyles, dialogStyles } from './styles';
16 17
 
17 18
 
@@ -42,10 +43,10 @@ const PollAnswer = (props: AbstractProps) => {
42 43
                         key = { index }
43 44
                         style = { chatStyles.switchRow } >
44 45
                         <Switch
45
-                            /* eslint-disable react/jsx-no-bind */
46
-                            onValueChange = { state => setCheckbox(index, state) }
47
-                            trackColor = {{ true: BaseTheme.palette.action01 }}
48
-                            value = { checkBoxStates[index] } />
46
+                            checked = { checkBoxStates[index] }
47
+                            /* eslint-disable-next-line react/jsx-no-bind */
48
+                            onChange = { state => setCheckbox(index, state) }
49
+                            trackColor = {{ true: BaseTheme.palette.action01 }} />
49 50
                         <Text style = { chatStyles.switchLabel }>{answer.name}</Text>
50 51
                     </View>
51 52
                 ))}

react/features/polls/constants.js → react/features/polls/constants.ts View File

@@ -1,5 +1,3 @@
1
-// @flow
2
-
3 1
 export const COMMAND_NEW_POLL = 'new-poll';
4 2
 export const COMMAND_ANSWER_POLL = 'answer-poll';
5 3
 export const COMMAND_OLD_POLLS = 'old-polls';

react/features/polls/types.js → react/features/polls/types.ts View File

@@ -1,66 +1,64 @@
1
-// @flow
2
-
3 1
 export type Answer = {
4 2
 
5 3
     /**
6
-     * ID of the voter for this answer.
4
+     * An array of boolean: true if the answer was chosen by the responder, else false.
7 5
      */
8
-    voterId: string,
6
+    answers: Array<boolean>,
9 7
 
10 8
     /**
11
-     * Name of the voter.
9
+     * ID of the parent Poll of this answer.
12 10
      */
13
-    voterName: string,
11
+    pollId: string,
14 12
 
15 13
     /**
16
-     * ID of the parent Poll of this answer.
14
+     * ID of the voter for this answer.
17 15
      */
18
-    pollId: string,
16
+    voterId: string,
19 17
 
20 18
     /**
21
-     * An array of boolean: true if the answer was chosen by the responder, else false.
19
+     * Name of the voter.
22 20
      */
23
-    answers: Array<boolean>
21
+    voterName: string
24 22
 };
25 23
 
26 24
 export type Poll = {
27 25
 
28 26
     /**
29
-     * Whether the poll vote is being edited/changed.
27
+     * An array of answers:
28
+     * the name of the answer name and a map of ids and names of voters voting for this option.
30 29
      */
31
-    changingVote: boolean,
30
+    answers: Array<{ name: string, voters: Map<string, string> }>,
32 31
 
33 32
     /**
34
-     * ID of the sender of this poll.
33
+     * Whether the poll vote is being edited/changed.
35 34
      */
36
-    senderId: string,
35
+    changingVote: boolean,
37 36
 
38 37
 
39 38
     /**
40
-     * Name of the sender of this poll
41
-     * Store poll sender name in case they exit the call.
39
+     * The last sent votes for this poll, or null if voting was skipped
40
+     * Note: This is reset when voting/skipping, not when clicking "Change vote".
42 41
      */
43
-    senderName: string,
42
+    lastVote: Array<boolean> | null,
44 43
 
45 44
     /**
46
-     * Whether the results should be shown instead of the answer form.
45
+     * The question asked by this poll.
47 46
      */
48
-    showResults: boolean,
47
+    question: string,
49 48
 
50 49
     /**
51
-     * The last sent votes for this poll, or null if voting was skipped
52
-     * Note: This is reset when voting/skipping, not when clicking "Change vote".
50
+     * ID of the sender of this poll.
53 51
      */
54
-    lastVote: Array<boolean> | null,
52
+    senderId: string,
55 53
 
56 54
     /**
57
-     * The question asked by this poll.
55
+     * Name of the sender of this poll
56
+     * Store poll sender name in case they exit the call.
58 57
      */
59
-    question: string,
58
+    senderName: string,
60 59
 
61 60
     /**
62
-     * An array of answers:
63
-     * the name of the answer name and a map of ids and names of voters voting for this option.
61
+     * Whether the results should be shown instead of the answer form.
64 62
      */
65
-    answers: Array<{ name: string, voters: Map<string, string> }>,
63
+    showResults: boolean
66 64
 };

+ 1
- 1
react/features/recording/components/Recording/AbstractStartRecordingDialogContent.tsx View File

@@ -123,7 +123,7 @@ export interface Props extends WithTranslation {
123 123
     /**
124 124
      * Callback to be invoked on sharing setting change.
125 125
      */
126
-    onSharingSettingChanged: Function,
126
+    onSharingSettingChanged: () => void,
127 127
 
128 128
     /**
129 129
      * The currently selected recording service of type: RECORDING_TYPES.

+ 11
- 12
react/features/recording/components/Recording/native/StartRecordingDialogContent.tsx View File

@@ -1,13 +1,14 @@
1 1
 /* eslint-disable lines-around-comment  */
2 2
 import React from 'react';
3 3
 import { Image, View } from 'react-native';
4
-import { Switch, Text } from 'react-native-paper';
4
+import { Text } from 'react-native-paper';
5 5
 
6 6
 import { translate } from '../../../../base/i18n/functions';
7 7
 // @ts-ignore
8 8
 import { LoadingIndicator } from '../../../../base/react';
9 9
 import { connect } from '../../../../base/redux/functions';
10 10
 import Button from '../../../../base/ui/components/native/Button';
11
+import Switch from '../../../../base/ui/components/native/Switch';
11 12
 import { BUTTON_TYPES } from '../../../../base/ui/constants';
12 13
 // @ts-ignore
13 14
 import { RECORDING_TYPES } from '../../../constants';
@@ -73,11 +74,11 @@ class StartRecordingDialogContent extends AbstractStartRecordingDialogContent<Pr
73 74
             = integrationsEnabled
74 75
                 ? (
75 76
                     <Switch
77
+                        checked = { selectedRecordingService === RECORDING_TYPES.JITSI_REC_SERVICE }
76 78
                         disabled = { isValidating }
77
-                        onValueChange = { this._onRecordingServiceSwitchChange }
79
+                        onChange = { this._onRecordingServiceSwitchChange }
78 80
                         style = { styles.switch }
79
-                        trackColor = {{ false: TRACK_COLOR }}
80
-                        value = { selectedRecordingService === RECORDING_TYPES.JITSI_REC_SERVICE } />
81
+                        trackColor = {{ false: TRACK_COLOR }} />
81 82
                 ) : null;
82 83
 
83 84
         return (
@@ -133,12 +134,11 @@ class StartRecordingDialogContent extends AbstractStartRecordingDialogContent<Pr
133 134
                     { t('recording.fileSharingdescription') }
134 135
                 </Text>
135 136
                 <Switch
137
+                    checked = { sharingSetting }
136 138
                     disabled = { isValidating }
137
-                    // @ts-ignore
138
-                    onValueChange = { onSharingSettingChanged }
139
+                    onChange = { onSharingSettingChanged }
139 140
                     style = { styles.switch }
140
-                    trackColor = {{ false: TRACK_COLOR }}
141
-                    value = { sharingSetting } />
141
+                    trackColor = {{ false: TRACK_COLOR }} />
142 142
             </View>
143 143
         );
144 144
     }
@@ -278,12 +278,11 @@ class StartRecordingDialogContent extends AbstractStartRecordingDialogContent<Pr
278 278
         if (fileRecordingsServiceEnabled) {
279 279
             switchContent = (
280 280
                 <Switch
281
+                    checked = { selectedRecordingService === RECORDING_TYPES.DROPBOX }
281 282
                     disabled = { isValidating }
282
-                    onValueChange = { this._onDropboxSwitchChange }
283
+                    onChange = { this._onDropboxSwitchChange }
283 284
                     style = { styles.switch }
284
-                    trackColor = {{ false: TRACK_COLOR }}
285
-                    value = { selectedRecordingService
286
-                        === RECORDING_TYPES.DROPBOX } />
285
+                    trackColor = {{ false: TRACK_COLOR }} />
287 286
             );
288 287
         }
289 288
 

+ 16
- 16
react/features/settings/components/native/SettingsView.js View File

@@ -11,7 +11,6 @@ import {
11 11
 } from 'react-native';
12 12
 import {
13 13
     Divider,
14
-    Switch,
15 14
     TextInput,
16 15
     withTheme
17 16
 } from 'react-native-paper';
@@ -24,6 +23,7 @@ import {
24 23
     getParticipantDisplayName
25 24
 } from '../../../base/participants';
26 25
 import { connect } from '../../../base/redux';
26
+import Switch from '../../../base/ui/components/native/Switch';
27 27
 import { screen } from '../../../mobile/navigation/routes';
28 28
 import { AVATAR_SIZE } from '../../../welcome/components/styles';
29 29
 import { normalizeUserInputURL, isServerURLChangeEnabled } from '../../functions';
@@ -269,24 +269,24 @@ class SettingsView extends AbstractSettingsView<Props, State> {
269 269
                         <FormRow
270 270
                             label = 'settingsView.startWithAudioMuted'>
271 271
                             <Switch
272
-                                onValueChange = { this._onStartAudioMutedChange }
272
+                                checked = { startWithAudioMuted }
273
+                                onChange = { this._onStartAudioMutedChange }
273 274
                                 thumbColor = { THUMB_COLOR }
274 275
                                 trackColor = {{
275 276
                                     true: ENABLED_TRACK_COLOR,
276 277
                                     false: DISABLED_TRACK_COLOR
277
-                                }}
278
-                                value = { startWithAudioMuted } />
278
+                                }} />
279 279
                         </FormRow>
280 280
                         <Divider style = { styles.fieldSeparator } />
281 281
                         <FormRow label = 'settingsView.startWithVideoMuted'>
282 282
                             <Switch
283
-                                onValueChange = { this._onStartVideoMutedChange }
283
+                                checked = { startWithVideoMuted }
284
+                                onChange = { this._onStartVideoMutedChange }
284 285
                                 thumbColor = { THUMB_COLOR }
285 286
                                 trackColor = {{
286 287
                                     true: ENABLED_TRACK_COLOR,
287 288
                                     false: DISABLED_TRACK_COLOR
288
-                                }}
289
-                                value = { startWithVideoMuted } />
289
+                                }} />
290 290
                         </FormRow>
291 291
                     </FormSectionAccordion>
292 292
                     <FormSectionAccordion
@@ -325,13 +325,13 @@ class SettingsView extends AbstractSettingsView<Props, State> {
325 325
                                 <FormRow
326 326
                                     label = 'settingsView.disableCallIntegration'>
327 327
                                     <Switch
328
-                                        onValueChange = { this._onDisableCallIntegration }
328
+                                        checked = { disableCallIntegration }
329
+                                        onChange = { this._onDisableCallIntegration }
329 330
                                         thumbColor = { THUMB_COLOR }
330 331
                                         trackColor = {{
331 332
                                             true: ENABLED_TRACK_COLOR,
332 333
                                             false: DISABLED_TRACK_COLOR
333
-                                        }}
334
-                                        value = { disableCallIntegration } />
334
+                                        }} />
335 335
                                 </FormRow>
336 336
                                 <Divider style = { styles.fieldSeparator } />
337 337
                             </>
@@ -339,13 +339,13 @@ class SettingsView extends AbstractSettingsView<Props, State> {
339 339
                         <FormRow
340 340
                             label = 'settingsView.disableP2P'>
341 341
                             <Switch
342
-                                onValueChange = { this._onDisableP2P }
342
+                                checked = { disableP2P }
343
+                                onChange = { this._onDisableP2P }
343 344
                                 thumbColor = { THUMB_COLOR }
344 345
                                 trackColor = {{
345 346
                                     true: ENABLED_TRACK_COLOR,
346 347
                                     false: DISABLED_TRACK_COLOR
347
-                                }}
348
-                                value = { disableP2P } />
348
+                                }} />
349 349
                         </FormRow>
350 350
                         <Divider style = { styles.fieldSeparator } />
351 351
                         {AppInfo.GOOGLE_SERVICES_ENABLED && (
@@ -353,13 +353,13 @@ class SettingsView extends AbstractSettingsView<Props, State> {
353 353
                                 fieldSeparator = { true }
354 354
                                 label = 'settingsView.disableCrashReporting'>
355 355
                                 <Switch
356
-                                    onValueChange = { this._onDisableCrashReporting }
356
+                                    checked = { disableCrashReporting }
357
+                                    onChange = { this._onDisableCrashReporting }
357 358
                                     thumbColor = { THUMB_COLOR }
358 359
                                     trackColor = {{
359 360
                                         true: ENABLED_TRACK_COLOR,
360 361
                                         false: DISABLED_TRACK_COLOR
361
-                                    }}
362
-                                    value = { disableCrashReporting } />
362
+                                    }} />
363 363
                             </FormRow>
364 364
                         )}
365 365
                     </FormSectionAccordion>

Loading…
Cancel
Save