diff --git a/src/libs/LocaleUtils.ts b/src/libs/LocaleUtils.ts new file mode 100644 index 000000000000..1a63cbf579d5 --- /dev/null +++ b/src/libs/LocaleUtils.ts @@ -0,0 +1,17 @@ +import type {ValueOf} from 'type-fest'; +import CONST from '@src/CONST'; + +function getLanguageFromLocale(locale: ValueOf): (typeof CONST.LANGUAGES)[number] { + switch (locale) { + case CONST.LOCALES.ES_ES: + case CONST.LOCALES.ES_ES_ONFIDO: + case CONST.LOCALES.ES: + return CONST.LOCALES.ES; + case CONST.LOCALES.EN: + return CONST.LOCALES.EN; + default: + return CONST.LOCALES.DEFAULT; + } +} + +export default {getLanguageFromLocale}; diff --git a/src/pages/settings/Preferences/LanguagePage.js b/src/pages/settings/Preferences/LanguagePage.tsx similarity index 56% rename from src/pages/settings/Preferences/LanguagePage.js rename to src/pages/settings/Preferences/LanguagePage.tsx index 1df1565214c9..b577e006acfb 100644 --- a/src/pages/settings/Preferences/LanguagePage.js +++ b/src/pages/settings/Preferences/LanguagePage.tsx @@ -1,28 +1,21 @@ -import PropTypes from 'prop-types'; import React from 'react'; -import _ from 'underscore'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import useLocalize from '@hooks/useLocalize'; import Navigation from '@libs/Navigation/Navigation'; import * as App from '@userActions/App'; import CONST from '@src/CONST'; -const propTypes = { - ...withLocalizePropTypes, +function LanguagePage() { + const {translate, preferredLocale} = useLocalize(); - /** The preferred language of the App */ - preferredLocale: PropTypes.string.isRequired, -}; - -function LanguagePage(props) { - const localesToLanguages = _.map(CONST.LANGUAGES, (language) => ({ + const localesToLanguages = CONST.LANGUAGES.map((language) => ({ value: language, - text: props.translate(`languagePage.languages.${language}.label`), + text: translate(`languagePage.languages.${language}.label`), keyForList: language, - isSelected: props.preferredLocale === language, + isSelected: preferredLocale === language, })); return ( @@ -31,20 +24,19 @@ function LanguagePage(props) { testID={LanguagePage.displayName} > Navigation.goBack()} /> App.setLocaleAndNavigate(language.value)} - initiallyFocusedOptionKey={_.find(localesToLanguages, (locale) => locale.isSelected).keyForList} + initiallyFocusedOptionKey={localesToLanguages.find((locale) => locale.isSelected)?.keyForList} /> ); } LanguagePage.displayName = 'LanguagePage'; -LanguagePage.propTypes = propTypes; -export default withLocalize(LanguagePage); +export default LanguagePage; diff --git a/src/pages/settings/Preferences/PreferencesPage.js b/src/pages/settings/Preferences/PreferencesPage.tsx similarity index 86% rename from src/pages/settings/Preferences/PreferencesPage.js rename to src/pages/settings/Preferences/PreferencesPage.tsx index 36a26ccffaa2..5849f323dc36 100755 --- a/src/pages/settings/Preferences/PreferencesPage.js +++ b/src/pages/settings/Preferences/PreferencesPage.tsx @@ -1,7 +1,6 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Illustrations from '@components/Icon/Illustrations'; @@ -15,33 +14,28 @@ import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import LocaleUtils from '@libs/LocaleUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type {PreferredTheme, PriorityMode, User as UserType} from '@src/types/onyx'; -const propTypes = { +type PreferencesPageOnyxProps = { /** The chat priority mode */ - priorityMode: PropTypes.string, + priorityMode: PriorityMode; /** The app's color theme */ - preferredTheme: PropTypes.string, + preferredTheme: PreferredTheme; /** The details about the user that is signed in */ - user: PropTypes.shape({ - /** Whether or not the user is subscribed to news updates */ - isSubscribedToNewsletter: PropTypes.bool, - }), + user: OnyxEntry; }; -const defaultProps = { - priorityMode: CONST.PRIORITY_MODE.DEFAULT, - preferredTheme: CONST.DEFAULT_THEME, - user: {}, -}; +type PreferencesPageProps = PreferencesPageOnyxProps; -function PreferencesPage(props) { +function PreferencesPage({priorityMode, preferredTheme, user}: PreferencesPageProps) { const styles = useThemeStyles(); const {translate, preferredLocale} = useLocalize(); const {isSmallScreenWidth} = useWindowDimensions(); @@ -83,7 +77,7 @@ function PreferencesPage(props) { @@ -95,28 +89,28 @@ function PreferencesPage(props) { Navigation.navigate(ROUTES.SETTINGS_PRIORITY_MODE)} wrapperStyle={styles.sectionMenuItemTopDescription} /> Navigation.navigate(ROUTES.SETTINGS_LANGUAGE)} wrapperStyle={styles.sectionMenuItemTopDescription} /> Navigation.navigate(ROUTES.SETTINGS_THEME)} wrapperStyle={styles.sectionMenuItemTopDescription} @@ -129,11 +123,9 @@ function PreferencesPage(props) { ); } -PreferencesPage.propTypes = propTypes; -PreferencesPage.defaultProps = defaultProps; PreferencesPage.displayName = 'PreferencesPage'; -export default withOnyx({ +export default withOnyx({ priorityMode: { key: ONYXKEYS.NVP_PRIORITY_MODE, }, diff --git a/src/pages/settings/Preferences/PriorityModePage.js b/src/pages/settings/Preferences/PriorityModePage.tsx similarity index 50% rename from src/pages/settings/Preferences/PriorityModePage.js rename to src/pages/settings/Preferences/PriorityModePage.tsx index 05c0546c2e41..677d3813acd7 100644 --- a/src/pages/settings/Preferences/PriorityModePage.js +++ b/src/pages/settings/Preferences/PriorityModePage.tsx @@ -1,49 +1,54 @@ -import PropTypes from 'prop-types'; import React, {useCallback} from 'react'; import {withOnyx} from 'react-native-onyx'; -import _, {compose} from 'underscore'; +import type {ValueOf} from 'type-fest'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; import Text from '@components/Text'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {PriorityMode} from '@src/types/onyx'; -const propTypes = { - /** The chat priority mode */ - priorityMode: PropTypes.string, - - ...withLocalizePropTypes, +type PriorityModeItem = { + value: ValueOf; + text: string; + alternateText: string; + keyForList: ValueOf; + isSelected: boolean; }; -const defaultProps = { - priorityMode: CONST.PRIORITY_MODE.DEFAULT, +type PriorityModePageOnyxProps = { + /** The chat priority mode */ + priorityMode: PriorityMode; }; -function PriorityModePage(props) { +type PriorityModePageProps = PriorityModePageOnyxProps; + +function PriorityModePage({priorityMode}: PriorityModePageProps) { + const {translate} = useLocalize(); const styles = useThemeStyles(); - const priorityModes = _.map(_.values(CONST.PRIORITY_MODE), (mode) => ({ + const priorityModes = Object.values(CONST.PRIORITY_MODE).map((mode) => ({ value: mode, - text: props.translate(`priorityModePage.priorityModes.${mode}.label`), - alternateText: props.translate(`priorityModePage.priorityModes.${mode}.description`), + text: translate(`priorityModePage.priorityModes.${mode}.label`), + alternateText: translate(`priorityModePage.priorityModes.${mode}.description`), keyForList: mode, - isSelected: props.priorityMode === mode, + isSelected: priorityMode === mode, })); const updateMode = useCallback( - (mode) => { - if (mode.value === props.priorityMode) { + (mode: PriorityModeItem) => { + if (mode.value === priorityMode) { Navigation.goBack(); return; } User.updateChatPriorityMode(mode.value); }, - [props.priorityMode], + [priorityMode], ); return ( @@ -52,29 +57,24 @@ function PriorityModePage(props) { testID={PriorityModePage.displayName} > Navigation.goBack()} /> - {props.translate('priorityModePage.explainerText')} + {translate('priorityModePage.explainerText')} mode.isSelected).keyForList} + initiallyFocusedOptionKey={priorityModes.find((mode) => mode.isSelected)?.keyForList} /> ); } PriorityModePage.displayName = 'PriorityModePage'; -PriorityModePage.propTypes = propTypes; -PriorityModePage.defaultProps = defaultProps; -export default compose( - withLocalize, - withOnyx({ - priorityMode: { - key: ONYXKEYS.NVP_PRIORITY_MODE, - }, - }), -)(PriorityModePage); +export default withOnyx({ + priorityMode: { + key: ONYXKEYS.NVP_PRIORITY_MODE, + }, +})(PriorityModePage); diff --git a/src/pages/settings/Preferences/ThemePage.js b/src/pages/settings/Preferences/ThemePage.tsx similarity index 74% rename from src/pages/settings/Preferences/ThemePage.js rename to src/pages/settings/Preferences/ThemePage.tsx index 0724eb286620..f879a7a259ea 100644 --- a/src/pages/settings/Preferences/ThemePage.js +++ b/src/pages/settings/Preferences/ThemePage.tsx @@ -1,7 +1,5 @@ -import PropTypes from 'prop-types'; import React from 'react'; import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; @@ -13,24 +11,24 @@ import Navigation from '@libs/Navigation/Navigation'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {PreferredTheme} from '@src/types/onyx'; -const propTypes = { +type ThemePageOnyxProps = { /** The theme of the app */ - preferredTheme: PropTypes.string, + preferredTheme: PreferredTheme; }; -const defaultProps = { - preferredTheme: CONST.THEME.DEFAULT, -}; +type ThemePageProps = ThemePageOnyxProps; -function ThemePage(props) { +function ThemePage({preferredTheme}: ThemePageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const localesToThemes = _.map(_.values(_.omit(CONST.THEME, 'DEFAULT', 'FALLBACK')), (theme) => ({ + const {DEFAULT, FALLBACK, ...themes} = CONST.THEME; + const localesToThemes = Object.values(themes).map((theme) => ({ value: theme, text: translate(`themePage.themes.${theme}.label`), keyForList: theme, - isSelected: (props.preferredTheme || CONST.THEME.DEFAULT) === theme, + isSelected: (preferredTheme ?? CONST.THEME.DEFAULT) === theme, })); return ( @@ -51,17 +49,15 @@ function ThemePage(props) { sections={[{data: localesToThemes}]} ListItem={RadioListItem} onSelectRow={(theme) => User.updateTheme(theme.value)} - initiallyFocusedOptionKey={_.find(localesToThemes, (theme) => theme.isSelected).keyForList} + initiallyFocusedOptionKey={localesToThemes.find((theme) => theme.isSelected)?.keyForList} /> ); } ThemePage.displayName = 'ThemePage'; -ThemePage.propTypes = propTypes; -ThemePage.defaultProps = defaultProps; -export default withOnyx({ +export default withOnyx({ preferredTheme: { key: ONYXKEYS.PREFERRED_THEME, }, diff --git a/src/types/onyx/PreferredTheme.ts b/src/types/onyx/PreferredTheme.ts new file mode 100644 index 000000000000..408748ad06ea --- /dev/null +++ b/src/types/onyx/PreferredTheme.ts @@ -0,0 +1,7 @@ +import type {OnyxEntry} from 'react-native-onyx'; +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type PreferredTheme = OnyxEntry>; + +export default PreferredTheme; diff --git a/src/types/onyx/PriorityMode.ts b/src/types/onyx/PriorityMode.ts new file mode 100644 index 000000000000..224c86867f35 --- /dev/null +++ b/src/types/onyx/PriorityMode.ts @@ -0,0 +1,7 @@ +import type {OnyxEntry} from 'react-native-onyx'; +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type PriorityMode = OnyxEntry>; + +export default PriorityMode; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index d12b0a22bba2..e3118538258e 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -40,6 +40,8 @@ import type {PolicyMembers} from './PolicyMember'; import type PolicyMember from './PolicyMember'; import type {PolicyReportField, PolicyReportFields} from './PolicyReportField'; import type {PolicyTag, PolicyTagList, PolicyTags} from './PolicyTag'; +import type PreferredTheme from './PreferredTheme'; +import type PriorityMode from './PriorityMode'; import type PrivatePersonalDetails from './PrivatePersonalDetails'; import type RecentlyUsedCategories from './RecentlyUsedCategories'; import type RecentlyUsedReportFields from './RecentlyUsedReportFields'; @@ -114,6 +116,8 @@ export type { PolicyTag, PolicyTags, PolicyTagList, + PreferredTheme, + PriorityMode, PrivatePersonalDetails, RecentWaypoint, RecentlyUsedCategories,