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

Bring Switch component more in line
Convert some files to TS
This commit is contained in:
Robert Pintilii 2022-08-24 12:46:22 +03:00 committed by GitHub
parent 6d39d13af7
commit 8dd71a921b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 153 additions and 114 deletions

View File

@ -0,0 +1,35 @@
import React from 'react';
import { ColorValue } from 'react-native';
import { Switch as NativeSwitch } from 'react-native-paper';
import { SwitchProps } from '../types';
interface Props extends SwitchProps {
/**
* Custom styles for the switch.
*/
style?: Object;
/**
* Color of the switch button.
*/
thumbColor?: ColorValue;
/**
* Color of the switch background.
*/
trackColor?: Object;
}
const Switch = ({ checked, disabled, onChange, thumbColor, trackColor, style }: Props) => (
<NativeSwitch
disabled = { disabled }
onValueChange = { onChange }
style = { style }
thumbColor = { thumbColor }
trackColor = { trackColor }
value = { checked } />
);
export default Switch;

View File

@ -77,3 +77,21 @@ export interface InputProps {
*/
value: string | number;
}
export interface SwitchProps {
/**
* Whether or not the toggle is on.
*/
checked: boolean;
/**
* Whether or not the toggle is disabled.
*/
disabled?: boolean;
/**
* Toggle change callback.
*/
onChange: (on?: boolean) => void;
}

View File

@ -3,28 +3,14 @@ import clsx from 'clsx';
import React, { useCallback } from 'react';
import { isMobileBrowser } from '../../../environment/utils';
import { SwitchProps } from '../types';
interface SwitchProps {
/**
* Whether or not the toggle is on.
*/
checked: boolean;
/**
* Whether or not the toggle is disabled.
*/
disabled?: boolean;
interface Props extends SwitchProps {
/**
* Id of the toggle.
*/
id?: string;
/**
* Toggle change callback.
*/
onChange: (on?: boolean) => void;
}
const useStyles = makeStyles((theme: any) => {
@ -92,7 +78,7 @@ const useStyles = makeStyles((theme: any) => {
};
});
const Switch = ({ id, checked, disabled, onChange }: SwitchProps) => {
const Switch = ({ id, checked, disabled, onChange }: Props) => {
const styles = useStyles();
const isMobile = isMobileBrowser();

View File

@ -1,22 +1,25 @@
// @flow
import React from 'react';
import { Switch, View } from 'react-native';
import { WithTranslation } from 'react-i18next';
import { View } from 'react-native';
import { translate } from '../../../base/i18n';
import { connect } from '../../../base/redux';
import { translate } from '../../../base/i18n/functions';
import { connect } from '../../../base/redux/functions';
import Switch from '../../../base/ui/components/native/Switch';
import {
DISABLED_TRACK_COLOR,
ENABLED_TRACK_COLOR,
THUMB_COLOR
// @ts-ignore
} from '../../../settings/components/native/styles';
// @ts-ignore
import styles from './styles';
/**
* The type of the React {@code Component} props of {@link LobbyModeSwitch}.
*/
type Props = {
interface Props extends WithTranslation {
/**
* True if the lobby mode is currently enabled for this conference.
@ -26,8 +29,8 @@ type Props = {
/**
* Callback to be invoked when handling enable-disable lobby mode switch.
*/
onToggleLobbyMode: Function
};
onToggleLobbyMode: (on?: boolean) => void;
}
/**
* Component meant to Enable/Disable lobby mode.
@ -43,14 +46,14 @@ function LobbyModeSwitch(
return (
<View style = { styles.lobbySwitchContainer }>
<Switch
onValueChange = { onToggleLobbyMode }
checked = { lobbyEnabled }
onChange = { onToggleLobbyMode }
style = { styles.lobbySwitchIcon }
thumbColor = { THUMB_COLOR }
trackColor = {{
true: ENABLED_TRACK_COLOR,
false: DISABLED_TRACK_COLOR
}}
value = { lobbyEnabled } />
}} />
</View>
);
}

View File

@ -1,16 +1,17 @@
// @flow
import React, { useCallback, useState } from 'react';
import type { AbstractComponent } from 'react';
/* eslint-disable lines-around-comment */
import React, { ComponentType, useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
// @ts-ignore
import { sendAnalytics, createPollEvent } from '../../analytics';
import { getLocalParticipant, getParticipantById } from '../../base/participants';
import { IState } from '../../app/types';
import { getLocalParticipant, getParticipantById } from '../../base/participants/functions';
import { useBoundSelector } from '../../base/util/hooks';
// @ts-ignore
import { registerVote, setVoteChanging } from '../actions';
import { COMMAND_ANSWER_POLL } from '../constants';
import type { Poll } from '../types';
import { Poll } from '../types';
/**
* The type of the React {@code Component} props of inheriting component.
@ -24,13 +25,13 @@ type InputProps = {
* concrete implementations (web/native).
**/
export type AbstractProps = {
checkBoxStates: Function,
checkBoxStates: boolean[],
creatorName: string,
poll: Poll,
setCheckbox: Function,
skipAnswer: Function,
skipChangeVote: Function,
submitAnswer: Function,
skipAnswer: () => void,
skipChangeVote: () => void,
submitAnswer: () => void,
t: Function,
};
@ -41,13 +42,13 @@ export type AbstractProps = {
* @param {React.AbstractComponent} Component - The concrete component.
* @returns {React.AbstractComponent}
*/
const AbstractPollAnswer = (Component: AbstractComponent<AbstractProps>) => (props: InputProps) => {
const AbstractPollAnswer = (Component: ComponentType<AbstractProps>) => (props: InputProps) => {
const { pollId } = props;
const conference: Object = useSelector(state => state['features/base/conference'].conference);
const conference: any = useSelector((state: IState) => state['features/base/conference'].conference);
const poll: Poll = useSelector(state => state['features/polls'].polls[pollId]);
const poll: Poll = useSelector((state: any) => state['features/polls'].polls[pollId]);
const { id: localId } = useSelector(getLocalParticipant);

View File

@ -1,17 +1,18 @@
// @flow
/* eslint-disable lines-around-comment */
import React from 'react';
import { Switch, Text, View } from 'react-native';
import { Text, View } from 'react-native';
import { useSelector } from 'react-redux';
import { getLocalParticipant } from '../../../base/participants';
import { getLocalParticipant } from '../../../base/participants/functions';
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
import Button from '../../../base/ui/components/native/Button';
import Switch from '../../../base/ui/components/native/Switch';
import { BUTTON_TYPES } from '../../../base/ui/constants';
// @ts-ignore
import { isSubmitAnswerDisabled } from '../../functions';
import AbstractPollAnswer from '../AbstractPollAnswer';
import type { AbstractProps } from '../AbstractPollAnswer';
import AbstractPollAnswer, { AbstractProps } from '../AbstractPollAnswer';
// @ts-ignore
import { chatStyles, dialogStyles } from './styles';
@ -42,10 +43,10 @@ const PollAnswer = (props: AbstractProps) => {
key = { index }
style = { chatStyles.switchRow } >
<Switch
/* eslint-disable react/jsx-no-bind */
onValueChange = { state => setCheckbox(index, state) }
trackColor = {{ true: BaseTheme.palette.action01 }}
value = { checkBoxStates[index] } />
checked = { checkBoxStates[index] }
/* eslint-disable-next-line react/jsx-no-bind */
onChange = { state => setCheckbox(index, state) }
trackColor = {{ true: BaseTheme.palette.action01 }} />
<Text style = { chatStyles.switchLabel }>{answer.name}</Text>
</View>
))}

View File

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

View File

@ -1,7 +1,15 @@
// @flow
export type Answer = {
/**
* An array of boolean: true if the answer was chosen by the responder, else false.
*/
answers: Array<boolean>,
/**
* ID of the parent Poll of this answer.
*/
pollId: string,
/**
* ID of the voter for this answer.
*/
@ -10,42 +18,22 @@ export type Answer = {
/**
* Name of the voter.
*/
voterName: string,
/**
* ID of the parent Poll of this answer.
*/
pollId: string,
/**
* An array of boolean: true if the answer was chosen by the responder, else false.
*/
answers: Array<boolean>
voterName: string
};
export type Poll = {
/**
* An array of answers:
* the name of the answer name and a map of ids and names of voters voting for this option.
*/
answers: Array<{ name: string, voters: Map<string, string> }>,
/**
* Whether the poll vote is being edited/changed.
*/
changingVote: boolean,
/**
* ID of the sender of this poll.
*/
senderId: string,
/**
* Name of the sender of this poll
* Store poll sender name in case they exit the call.
*/
senderName: string,
/**
* Whether the results should be shown instead of the answer form.
*/
showResults: boolean,
/**
* The last sent votes for this poll, or null if voting was skipped
@ -59,8 +47,18 @@ export type Poll = {
question: string,
/**
* An array of answers:
* the name of the answer name and a map of ids and names of voters voting for this option.
* ID of the sender of this poll.
*/
answers: Array<{ name: string, voters: Map<string, string> }>,
senderId: string,
/**
* Name of the sender of this poll
* Store poll sender name in case they exit the call.
*/
senderName: string,
/**
* Whether the results should be shown instead of the answer form.
*/
showResults: boolean
};

View File

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

View File

@ -1,13 +1,14 @@
/* eslint-disable lines-around-comment */
import React from 'react';
import { Image, View } from 'react-native';
import { Switch, Text } from 'react-native-paper';
import { Text } from 'react-native-paper';
import { translate } from '../../../../base/i18n/functions';
// @ts-ignore
import { LoadingIndicator } from '../../../../base/react';
import { connect } from '../../../../base/redux/functions';
import Button from '../../../../base/ui/components/native/Button';
import Switch from '../../../../base/ui/components/native/Switch';
import { BUTTON_TYPES } from '../../../../base/ui/constants';
// @ts-ignore
import { RECORDING_TYPES } from '../../../constants';
@ -73,11 +74,11 @@ class StartRecordingDialogContent extends AbstractStartRecordingDialogContent<Pr
= integrationsEnabled
? (
<Switch
checked = { selectedRecordingService === RECORDING_TYPES.JITSI_REC_SERVICE }
disabled = { isValidating }
onValueChange = { this._onRecordingServiceSwitchChange }
onChange = { this._onRecordingServiceSwitchChange }
style = { styles.switch }
trackColor = {{ false: TRACK_COLOR }}
value = { selectedRecordingService === RECORDING_TYPES.JITSI_REC_SERVICE } />
trackColor = {{ false: TRACK_COLOR }} />
) : null;
return (
@ -133,12 +134,11 @@ class StartRecordingDialogContent extends AbstractStartRecordingDialogContent<Pr
{ t('recording.fileSharingdescription') }
</Text>
<Switch
checked = { sharingSetting }
disabled = { isValidating }
// @ts-ignore
onValueChange = { onSharingSettingChanged }
onChange = { onSharingSettingChanged }
style = { styles.switch }
trackColor = {{ false: TRACK_COLOR }}
value = { sharingSetting } />
trackColor = {{ false: TRACK_COLOR }} />
</View>
);
}
@ -278,12 +278,11 @@ class StartRecordingDialogContent extends AbstractStartRecordingDialogContent<Pr
if (fileRecordingsServiceEnabled) {
switchContent = (
<Switch
checked = { selectedRecordingService === RECORDING_TYPES.DROPBOX }
disabled = { isValidating }
onValueChange = { this._onDropboxSwitchChange }
onChange = { this._onDropboxSwitchChange }
style = { styles.switch }
trackColor = {{ false: TRACK_COLOR }}
value = { selectedRecordingService
=== RECORDING_TYPES.DROPBOX } />
trackColor = {{ false: TRACK_COLOR }} />
);
}

View File

@ -11,7 +11,6 @@ import {
} from 'react-native';
import {
Divider,
Switch,
TextInput,
withTheme
} from 'react-native-paper';
@ -24,6 +23,7 @@ import {
getParticipantDisplayName
} from '../../../base/participants';
import { connect } from '../../../base/redux';
import Switch from '../../../base/ui/components/native/Switch';
import { screen } from '../../../mobile/navigation/routes';
import { AVATAR_SIZE } from '../../../welcome/components/styles';
import { normalizeUserInputURL, isServerURLChangeEnabled } from '../../functions';
@ -269,24 +269,24 @@ class SettingsView extends AbstractSettingsView<Props, State> {
<FormRow
label = 'settingsView.startWithAudioMuted'>
<Switch
onValueChange = { this._onStartAudioMutedChange }
checked = { startWithAudioMuted }
onChange = { this._onStartAudioMutedChange }
thumbColor = { THUMB_COLOR }
trackColor = {{
true: ENABLED_TRACK_COLOR,
false: DISABLED_TRACK_COLOR
}}
value = { startWithAudioMuted } />
}} />
</FormRow>
<Divider style = { styles.fieldSeparator } />
<FormRow label = 'settingsView.startWithVideoMuted'>
<Switch
onValueChange = { this._onStartVideoMutedChange }
checked = { startWithVideoMuted }
onChange = { this._onStartVideoMutedChange }
thumbColor = { THUMB_COLOR }
trackColor = {{
true: ENABLED_TRACK_COLOR,
false: DISABLED_TRACK_COLOR
}}
value = { startWithVideoMuted } />
}} />
</FormRow>
</FormSectionAccordion>
<FormSectionAccordion
@ -325,13 +325,13 @@ class SettingsView extends AbstractSettingsView<Props, State> {
<FormRow
label = 'settingsView.disableCallIntegration'>
<Switch
onValueChange = { this._onDisableCallIntegration }
checked = { disableCallIntegration }
onChange = { this._onDisableCallIntegration }
thumbColor = { THUMB_COLOR }
trackColor = {{
true: ENABLED_TRACK_COLOR,
false: DISABLED_TRACK_COLOR
}}
value = { disableCallIntegration } />
}} />
</FormRow>
<Divider style = { styles.fieldSeparator } />
</>
@ -339,13 +339,13 @@ class SettingsView extends AbstractSettingsView<Props, State> {
<FormRow
label = 'settingsView.disableP2P'>
<Switch
onValueChange = { this._onDisableP2P }
checked = { disableP2P }
onChange = { this._onDisableP2P }
thumbColor = { THUMB_COLOR }
trackColor = {{
true: ENABLED_TRACK_COLOR,
false: DISABLED_TRACK_COLOR
}}
value = { disableP2P } />
}} />
</FormRow>
<Divider style = { styles.fieldSeparator } />
{AppInfo.GOOGLE_SERVICES_ENABLED && (
@ -353,13 +353,13 @@ class SettingsView extends AbstractSettingsView<Props, State> {
fieldSeparator = { true }
label = 'settingsView.disableCrashReporting'>
<Switch
onValueChange = { this._onDisableCrashReporting }
checked = { disableCrashReporting }
onChange = { this._onDisableCrashReporting }
thumbColor = { THUMB_COLOR }
trackColor = {{
true: ENABLED_TRACK_COLOR,
false: DISABLED_TRACK_COLOR
}}
value = { disableCrashReporting } />
}} />
</FormRow>
)}
</FormSectionAccordion>