From 8dd71a921b03a5f43a31e8dd1663d0506d1f4e1b Mon Sep 17 00:00:00 2001 From: Robert Pintilii Date: Wed, 24 Aug 2022 12:46:22 +0300 Subject: [PATCH] ref(ui-components) Improve native and web Switch (#12061) Bring Switch component more in line Convert some files to TS --- .../base/ui/components/native/Switch.tsx | 35 +++++++++++ react/features/base/ui/components/types.ts | 18 ++++++ .../base/ui/components/web/Switch.tsx | 20 +----- ...LobbyModeSwitch.js => LobbyModeSwitch.tsx} | 25 ++++---- ...ctPollAnswer.js => AbstractPollAnswer.tsx} | 27 ++++---- .../native/{PollAnswer.js => PollAnswer.tsx} | 21 ++++--- .../polls/{constants.js => constants.ts} | 2 - react/features/polls/{types.js => types.ts} | 62 +++++++++---------- .../AbstractStartRecordingDialogContent.tsx | 2 +- .../native/StartRecordingDialogContent.tsx | 23 ++++--- .../components/native/SettingsView.js | 32 +++++----- 11 files changed, 153 insertions(+), 114 deletions(-) create mode 100644 react/features/base/ui/components/native/Switch.tsx rename react/features/lobby/components/native/{LobbyModeSwitch.js => LobbyModeSwitch.tsx} (68%) rename react/features/polls/components/{AbstractPollAnswer.js => AbstractPollAnswer.tsx} (82%) rename react/features/polls/components/native/{PollAnswer.js => PollAnswer.tsx} (81%) rename react/features/polls/{constants.js => constants.ts} (95%) rename react/features/polls/{types.js => types.ts} (93%) diff --git a/react/features/base/ui/components/native/Switch.tsx b/react/features/base/ui/components/native/Switch.tsx new file mode 100644 index 000000000..a29d79471 --- /dev/null +++ b/react/features/base/ui/components/native/Switch.tsx @@ -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) => ( + +); + +export default Switch; diff --git a/react/features/base/ui/components/types.ts b/react/features/base/ui/components/types.ts index e2a10075b..23e0684af 100644 --- a/react/features/base/ui/components/types.ts +++ b/react/features/base/ui/components/types.ts @@ -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; +} diff --git a/react/features/base/ui/components/web/Switch.tsx b/react/features/base/ui/components/web/Switch.tsx index b86ba162f..826295543 100644 --- a/react/features/base/ui/components/web/Switch.tsx +++ b/react/features/base/ui/components/web/Switch.tsx @@ -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(); diff --git a/react/features/lobby/components/native/LobbyModeSwitch.js b/react/features/lobby/components/native/LobbyModeSwitch.tsx similarity index 68% rename from react/features/lobby/components/native/LobbyModeSwitch.js rename to react/features/lobby/components/native/LobbyModeSwitch.tsx index a5d4f7065..caf4de051 100644 --- a/react/features/lobby/components/native/LobbyModeSwitch.js +++ b/react/features/lobby/components/native/LobbyModeSwitch.tsx @@ -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 ( + }} /> ); } diff --git a/react/features/polls/components/AbstractPollAnswer.js b/react/features/polls/components/AbstractPollAnswer.tsx similarity index 82% rename from react/features/polls/components/AbstractPollAnswer.js rename to react/features/polls/components/AbstractPollAnswer.tsx index 1c5d257c1..a5e18d915 100644 --- a/react/features/polls/components/AbstractPollAnswer.js +++ b/react/features/polls/components/AbstractPollAnswer.tsx @@ -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) => (props: InputProps) => { +const AbstractPollAnswer = (Component: ComponentType) => (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); diff --git a/react/features/polls/components/native/PollAnswer.js b/react/features/polls/components/native/PollAnswer.tsx similarity index 81% rename from react/features/polls/components/native/PollAnswer.js rename to react/features/polls/components/native/PollAnswer.tsx index a5b0456ff..34f625691 100644 --- a/react/features/polls/components/native/PollAnswer.js +++ b/react/features/polls/components/native/PollAnswer.tsx @@ -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 } > 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 }} /> {answer.name} ))} diff --git a/react/features/polls/constants.js b/react/features/polls/constants.ts similarity index 95% rename from react/features/polls/constants.js rename to react/features/polls/constants.ts index effbfc727..f4cc3fc0d 100644 --- a/react/features/polls/constants.js +++ b/react/features/polls/constants.ts @@ -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'; diff --git a/react/features/polls/types.js b/react/features/polls/types.ts similarity index 93% rename from react/features/polls/types.js rename to react/features/polls/types.ts index 65f36e1cb..55d0f63c4 100644 --- a/react/features/polls/types.js +++ b/react/features/polls/types.ts @@ -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, + + /** + * 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 + 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 }>, + /** * 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 }>, + 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 }; diff --git a/react/features/recording/components/Recording/AbstractStartRecordingDialogContent.tsx b/react/features/recording/components/Recording/AbstractStartRecordingDialogContent.tsx index e28449757..270028119 100644 --- a/react/features/recording/components/Recording/AbstractStartRecordingDialogContent.tsx +++ b/react/features/recording/components/Recording/AbstractStartRecordingDialogContent.tsx @@ -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. diff --git a/react/features/recording/components/Recording/native/StartRecordingDialogContent.tsx b/react/features/recording/components/Recording/native/StartRecordingDialogContent.tsx index 8d01c6a29..47e6c70aa 100644 --- a/react/features/recording/components/Recording/native/StartRecordingDialogContent.tsx +++ b/react/features/recording/components/Recording/native/StartRecordingDialogContent.tsx @@ -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 + trackColor = {{ false: TRACK_COLOR }} /> ) : null; return ( @@ -133,12 +134,11 @@ class StartRecordingDialogContent extends AbstractStartRecordingDialogContent + trackColor = {{ false: TRACK_COLOR }} /> ); } @@ -278,12 +278,11 @@ class StartRecordingDialogContent extends AbstractStartRecordingDialogContent + trackColor = {{ false: TRACK_COLOR }} /> ); } diff --git a/react/features/settings/components/native/SettingsView.js b/react/features/settings/components/native/SettingsView.js index 7c640cb93..54d7c8ff4 100644 --- a/react/features/settings/components/native/SettingsView.js +++ b/react/features/settings/components/native/SettingsView.js @@ -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 { + }} /> + }} /> { + }} /> @@ -339,13 +339,13 @@ class SettingsView extends AbstractSettingsView { + }} /> {AppInfo.GOOGLE_SERVICES_ENABLED && ( @@ -353,13 +353,13 @@ class SettingsView extends AbstractSettingsView { fieldSeparator = { true } label = 'settingsView.disableCrashReporting'> + }} /> )}