From d8f75f765c097e2de3374705f03224d49440d3e7 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Mon, 31 Oct 2022 18:31:45 +0200 Subject: [PATCH 01/17] Set up new pronouns page route --- src/ROUTES.js | 1 + src/libs/Navigation/AppNavigator/ModalStackNavigators.js | 7 +++++++ src/libs/Navigation/linkingConfig.js | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/ROUTES.js b/src/ROUTES.js index 0dd0f61824e2..6bd81a67cfc6 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -22,6 +22,7 @@ export default { HOME: '', SETTINGS: 'settings', SETTINGS_PROFILE: 'settings/profile', + SETTINGS_PRONOUNS: 'settings/profile/pronouns', SETTINGS_PREFERENCES: 'settings/preferences', SETTINGS_WORKSPACES: 'settings/workspaces', SETTINGS_SECURITY: 'settings/security', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 7a22f47572fc..baa93d79bae6 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -217,6 +217,13 @@ const SettingsModalStackNavigator = createModalStackNavigator([ }, name: 'Settings_Profile', }, + { + getComponent: () => { + const SettingsPronounsPage = require('../../../pages/settings/Profile/PronounsPage').default; + return SettingsPronounsPage; + }, + name: 'Settings_Pronouns', + }, { getComponent: () => { const SettingsAddSecondaryLoginPage = require('../../../pages/settings/AddSecondaryLoginPage').default; diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index 6e8951bffbcf..8be6ef996681 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -88,6 +88,10 @@ export default { path: ROUTES.SETTINGS_PROFILE, exact: true, }, + Settings_Pronouns: { + path: ROUTES.SETTINGS_PRONOUNS, + exact: true, + }, Settings_About: { path: ROUTES.SETTINGS_ABOUT, exact: true, From 02e2f0ada5d0c822fe55f0431b8d07619a917182 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Mon, 31 Oct 2022 18:31:53 +0200 Subject: [PATCH 02/17] Add new Pronouns page --- src/ONYXKEYS.js | 1 + src/languages/en.js | 20 +-- src/languages/es.js | 20 +-- src/pages/settings/Profile/PronounsPage.js | 152 +++++++++++++++++++++ 4 files changed, 177 insertions(+), 16 deletions(-) create mode 100644 src/pages/settings/Profile/PronounsPage.js diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index b4d3998db100..5cf67b7c6922 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -173,6 +173,7 @@ export default { REQUEST_CALL_FORM: 'requestCallForm', REIMBURSEMENT_ACCOUNT_FORM: 'reimbursementAccount', WORKSPACE_SETTINGS_FORM: 'workspaceSettingsForm', + PRONOUNS_FORM: 'pronounsForm', }, // Whether we should show the compose input or not diff --git a/src/languages/en.js b/src/languages/en.js index 7e14c6c2faad..10442c0ab587 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -302,6 +302,18 @@ export default { offline: 'Offline', syncing: 'Syncing', }, + pronounsPage: { + pronouns: 'Pronouns', + isShownOnProfile: 'Your pronouns are shown on your profile.', + }, + pronouns: { + heHimHis: 'He/him', + sheHerHers: 'She/her', + theyThemTheirs: 'They/them', + zeHirHirs: 'Ze/hir', + selfSelect: 'Self-select', + callMeByMyName: 'Call me by my name', + }, addSecondaryLoginPage: { addPhoneNumber: 'Add phone number', addEmailAddress: 'Add email address', @@ -607,14 +619,6 @@ export default { formLabel: 'View PDF', }, }, - pronouns: { - heHimHis: 'He/him', - sheHerHers: 'She/her', - theyThemTheirs: 'They/them', - zeHirHirs: 'Ze/hir', - selfSelect: 'Self-select', - callMeByMyName: 'Call me by my name', - }, messages: { errorMessageInvalidPhone: `Please enter a valid phone number without brackets or dashes. If you're outside the US please include your country code (e.g. ${CONST.EXAMPLE_PHONE_NUMBER}).`, }, diff --git a/src/languages/es.js b/src/languages/es.js index 22cc262a6835..821c1ee7903a 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -302,6 +302,18 @@ export default { offline: 'Desconectado', syncing: 'Sincronizando', }, + pronounsPage: { + pronouns: 'Pronombres', + isShownOnProfile: '', + }, + pronouns: { + heHimHis: 'Él', + sheHerHers: 'Ella', + theyThemTheirs: 'Ellos', + zeHirHirs: 'Ze/hir', + selfSelect: 'Personalízalo', + callMeByMyName: 'Llámame por mi nombre', + }, addSecondaryLoginPage: { addPhoneNumber: 'Agregar número de teléfono', addEmailAddress: 'Agregar dirección de email', @@ -607,14 +619,6 @@ export default { formLabel: 'Ver PDF', }, }, - pronouns: { - heHimHis: 'Él', - sheHerHers: 'Ella', - theyThemTheirs: 'Ellos', - zeHirHirs: 'Ze/hir', - selfSelect: 'Personalízalo', - callMeByMyName: 'Llámame por mi nombre', - }, messages: { errorMessageInvalidPhone: `Por favor, introduce un número de teléfono válido sin paréntesis o guiones. Si reside fuera de Estados Unidos, por favor incluye el prefijo internacional (p. ej. ${CONST.EXAMPLE_PHONE_NUMBER}).`, }, diff --git a/src/pages/settings/Profile/PronounsPage.js b/src/pages/settings/Profile/PronounsPage.js new file mode 100644 index 000000000000..a5c5efa49da9 --- /dev/null +++ b/src/pages/settings/Profile/PronounsPage.js @@ -0,0 +1,152 @@ +import lodashGet from 'lodash/get'; +import React, {Component} from 'react'; +import {View} from 'react-native'; +import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../../components/withCurrentUserPersonalDetails'; +import ScreenWrapper from '../../../components/ScreenWrapper'; +import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton'; +import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import * as Localize from '../../../libs/Localize'; +import ROUTES from '../../../ROUTES'; +import Form from '../../../components/Form'; +import ONYXKEYS from '../../../ONYXKEYS'; +import CONST from '../../../CONST'; +import * as ValidationUtils from '../../../libs/ValidationUtils'; +import TextInput from '../../../components/TextInput'; +import Text from '../../../components/Text'; +import styles from '../../../styles/styles'; +import Navigation from '../../../libs/Navigation/Navigation'; +import * as PersonalDetails from '../../../libs/actions/PersonalDetails'; +import compose from '../../../libs/compose'; +import Picker from '../../../components/Picker'; + +const propTypes = { + ...withLocalizePropTypes, + ...withCurrentUserPersonalDetailsPropTypes, +}; + +const defaultProps = { + ...withCurrentUserPersonalDetailsDefaultProps, +}; + +class PronounsPage extends Component { + constructor(props) { + super(props); + + this.validate = this.validate.bind(this); + this.updatePronouns = this.updatePronouns.bind(this); + this.setPronouns = this.setPronouns.bind(this); + + this.pronouns = props.currentUserPersonalDetails.pronouns; + this.state = { + hasSelfSelectedPronouns: !_.isEmpty(props.currentUserPersonalDetails.pronouns) && !props.currentUserPersonalDetails.pronouns.startsWith(CONST.PRONOUNS.PREFIX), + }; + } + + /** + * @param {String} pronouns + */ + setPronouns(pronouns) { + const hasSelfSelectedPronouns = pronouns === CONST.PRONOUNS.SELF_SELECT; + this.pronouns = hasSelfSelectedPronouns ? '' : pronouns; + + if (this.state.hasSelfSelectedPronouns === hasSelfSelectedPronouns) { + return; + } + + this.setState({hasSelfSelectedPronouns}); + } + + /** + * Submit form to update personal details + * @param {Object} values + * @param {String} values.pronouns + * @param {String} values.selfSelectedPronoun + */ + updatePronouns(values) { + PersonalDetails.updatePronouns( + this.state.hasSelfSelectedPronouns ? values.selfSelectedPronoun.trim() : values.pronouns.trim(), + ); + } + + /** + * @param {Object} values - An object containing the value of each inputID + * @param {String} values.pronouns + * @param {String} values.selfSelectedPronoun + * @returns {Object} - An object containing the errors for each inputID + */ + validate(values) { + const errors = {}; + + const [hasPronounError] = ValidationUtils.doesFailCharacterLimitAfterTrim( + CONST.FORM_CHARACTER_LIMIT, + [values.pronouns], + ); + + if (hasPronounError) { + errors.pronouns = Localize.translateLocal('personalDetails.error.characterLimit', {limit: CONST.FORM_CHARACTER_LIMIT}); + } + + return errors; + } + + render() { + const pronounsList = _.map(this.props.translate('pronouns'), (value, key) => ({ + label: value, + value: `${CONST.PRONOUNS.PREFIX}${key}`, + })); + const pronounsPickerValue = this.state.hasSelfSelectedPronouns ? CONST.PRONOUNS.SELF_SELECT : this.pronouns; + + return ( + + Navigation.navigate(ROUTES.SETTINGS_PROFILE)} + onCloseButtonPress={() => Navigation.dismissModal(true)} + /> +
+ + {this.props.translate('displayNamePage.isShownOnProfile')} + + + + {this.state.hasSelfSelectedPronouns && ( + + + + )} + +
+
+ ) + } +} + +PronounsPage.propTypes = propTypes; +PronounsPage.defaultProps = defaultProps; + +export default compose( + withLocalize, + withCurrentUserPersonalDetails, +)(PronounsPage); From 208ff39df192222c3e51c313c287152d67c51c78 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Tue, 1 Nov 2022 12:53:38 +0200 Subject: [PATCH 03/17] Update spanish translation --- src/languages/es.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.js b/src/languages/es.js index 103543a81dc0..e2be7cf98e02 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -304,7 +304,7 @@ export default { }, pronounsPage: { pronouns: 'Pronombres', - isShownOnProfile: '', + isShownOnProfile: 'Tu pronombres son muestra en tu perfil.', }, pronouns: { heHimHis: 'Él', From c993656f50776e540fcc96f828bea0664f39a539 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Tue, 1 Nov 2022 13:17:27 +0200 Subject: [PATCH 04/17] Fix translation location --- src/pages/settings/Profile/PronounsPage.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/settings/Profile/PronounsPage.js b/src/pages/settings/Profile/PronounsPage.js index a5c5efa49da9..28e231795a8b 100644 --- a/src/pages/settings/Profile/PronounsPage.js +++ b/src/pages/settings/Profile/PronounsPage.js @@ -45,7 +45,7 @@ class PronounsPage extends Component { /** * @param {String} pronouns */ - setPronouns(pronouns) { + setPronouns(pronouns) { const hasSelfSelectedPronouns = pronouns === CONST.PRONOUNS.SELF_SELECT; this.pronouns = hasSelfSelectedPronouns ? '' : pronouns; @@ -76,16 +76,16 @@ class PronounsPage extends Component { */ validate(values) { const errors = {}; - + const [hasPronounError] = ValidationUtils.doesFailCharacterLimitAfterTrim( CONST.FORM_CHARACTER_LIMIT, [values.pronouns], ); - + if (hasPronounError) { errors.pronouns = Localize.translateLocal('personalDetails.error.characterLimit', {limit: CONST.FORM_CHARACTER_LIMIT}); } - + return errors; } @@ -113,7 +113,7 @@ class PronounsPage extends Component { enabledWhenOffline > - {this.props.translate('displayNamePage.isShownOnProfile')} + {this.props.translate('pronounsPage.isShownOnProfile')} Date: Tue, 1 Nov 2022 13:17:42 +0200 Subject: [PATCH 05/17] Add updatePronouns action --- src/libs/actions/PersonalDetails.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libs/actions/PersonalDetails.js b/src/libs/actions/PersonalDetails.js index 903ec76b4839..5dde61b552ff 100644 --- a/src/libs/actions/PersonalDetails.js +++ b/src/libs/actions/PersonalDetails.js @@ -285,6 +285,23 @@ function updateProfile(firstName, lastName, pronouns, timezone) { }); } +/** + * @param {String} pronouns + */ +function updatePronouns(pronouns) { + API.write('UpdatePronouns', {pronouns}, { + optimisticData: [{ + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: ONYXKEYS.PERSONAL_DETAILS, + value: { + [currentUserEmail]: { + pronouns, + }, + }, + }], + }); +} + /** * Fetches the local currency based on location and sets currency code/symbol to Onyx */ @@ -398,4 +415,5 @@ export { extractFirstAndLastNameFromAvailableDetails, updateProfile, clearAvatarErrors, + updatePronouns, }; From e77d92c534bb0089f5f99ecadf4f4fae696fc5ff Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Thu, 10 Nov 2022 14:47:30 -0800 Subject: [PATCH 06/17] Navigate back to profile after updating pronouns --- src/libs/actions/PersonalDetails.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/actions/PersonalDetails.js b/src/libs/actions/PersonalDetails.js index a077946d1ebc..f4e339efd85e 100644 --- a/src/libs/actions/PersonalDetails.js +++ b/src/libs/actions/PersonalDetails.js @@ -310,6 +310,7 @@ function updatePronouns(pronouns) { }, }], }); + Navigation.navigate(ROUTES.SETTINGS_PROFILE); } /** From de474c51526b9457ee844c6ae806fd60325b053e Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Thu, 10 Nov 2022 14:47:43 -0800 Subject: [PATCH 07/17] Update public pronouns translation --- src/languages/es.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.js b/src/languages/es.js index c3c762237002..b357fc50d2f8 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -306,7 +306,7 @@ export default { }, pronounsPage: { pronouns: 'Pronombres', - isShownOnProfile: 'Tu pronombres son muestra en tu perfil.', + isShownOnProfile: 'Tus pronombres se muestran en tu perfil.', }, pronouns: { heHimHis: 'Él', From c5ff85a19c3b1893f2faaf1ac9494a6a2e7a7c99 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Thu, 10 Nov 2022 14:48:48 -0800 Subject: [PATCH 08/17] Remove extra whitespace --- src/libs/actions/PersonalDetails.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/PersonalDetails.js b/src/libs/actions/PersonalDetails.js index f4e339efd85e..66ec00ca992b 100644 --- a/src/libs/actions/PersonalDetails.js +++ b/src/libs/actions/PersonalDetails.js @@ -317,7 +317,7 @@ function updatePronouns(pronouns) { * @param {String} firstName * @param {String} lastName */ - function updateDisplayName(firstName, lastName) { +function updateDisplayName(firstName, lastName) { API.write('UpdateDisplayName', {firstName, lastName}, { optimisticData: [{ onyxMethod: CONST.ONYX.METHOD.MERGE, From 5594d9597217234e393fe3fbd593983c269d5901 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Thu, 10 Nov 2022 16:03:38 -0800 Subject: [PATCH 09/17] Show pronoun list directly on page --- src/ONYXKEYS.js | 1 - src/languages/en.js | 1 - src/languages/es.js | 1 - src/pages/settings/Profile/PronounsPage.js | 162 ++++++--------------- 4 files changed, 45 insertions(+), 120 deletions(-) diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index 8a67b18c8bfd..04ca95c21169 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -177,7 +177,6 @@ export default { REIMBURSEMENT_ACCOUNT_FORM: 'reimbursementAccount', WORKSPACE_SETTINGS_FORM: 'workspaceSettingsForm', PROFILE_SETTINGS_FORM: 'profileSettingsForm', - PRONOUNS_FORM: 'pronounsForm', DISPLAY_NAME_FORM: 'displayNameForm', }, diff --git a/src/languages/en.js b/src/languages/en.js index e03e553fdf21..d3a78d390d9d 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -312,7 +312,6 @@ export default { sheHerHers: 'She/her', theyThemTheirs: 'They/them', zeHirHirs: 'Ze/hir', - selfSelect: 'Self-select', callMeByMyName: 'Call me by my name', }, displayNamePage: { diff --git a/src/languages/es.js b/src/languages/es.js index b357fc50d2f8..2b160a644607 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -313,7 +313,6 @@ export default { sheHerHers: 'Ella', theyThemTheirs: 'Ellos', zeHirHirs: 'Ze/hir', - selfSelect: 'Personalízalo', callMeByMyName: 'Llámame por mi nombre', }, displayNamePage: { diff --git a/src/pages/settings/Profile/PronounsPage.js b/src/pages/settings/Profile/PronounsPage.js index 28e231795a8b..a3e6dfa2e7ce 100644 --- a/src/pages/settings/Profile/PronounsPage.js +++ b/src/pages/settings/Profile/PronounsPage.js @@ -1,23 +1,19 @@ import lodashGet from 'lodash/get'; -import React, {Component} from 'react'; +import React from 'react'; import {View} from 'react-native'; import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../../components/withCurrentUserPersonalDetails'; import ScreenWrapper from '../../../components/ScreenWrapper'; import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; -import * as Localize from '../../../libs/Localize'; import ROUTES from '../../../ROUTES'; -import Form from '../../../components/Form'; -import ONYXKEYS from '../../../ONYXKEYS'; -import CONST from '../../../CONST'; -import * as ValidationUtils from '../../../libs/ValidationUtils'; -import TextInput from '../../../components/TextInput'; import Text from '../../../components/Text'; import styles from '../../../styles/styles'; import Navigation from '../../../libs/Navigation/Navigation'; import * as PersonalDetails from '../../../libs/actions/PersonalDetails'; import compose from '../../../libs/compose'; -import Picker from '../../../components/Picker'; +import OptionsList from '../../../components/OptionsList'; +import themeColors from '../../../styles/themes/default'; +import * as Expensicons from '../../../components/Icon/Expensicons'; const propTypes = { ...withLocalizePropTypes, @@ -28,120 +24,52 @@ const defaultProps = { ...withCurrentUserPersonalDetailsDefaultProps, }; -class PronounsPage extends Component { - constructor(props) { - super(props); - - this.validate = this.validate.bind(this); - this.updatePronouns = this.updatePronouns.bind(this); - this.setPronouns = this.setPronouns.bind(this); - - this.pronouns = props.currentUserPersonalDetails.pronouns; - this.state = { - hasSelfSelectedPronouns: !_.isEmpty(props.currentUserPersonalDetails.pronouns) && !props.currentUserPersonalDetails.pronouns.startsWith(CONST.PRONOUNS.PREFIX), - }; - } - - /** - * @param {String} pronouns - */ - setPronouns(pronouns) { - const hasSelfSelectedPronouns = pronouns === CONST.PRONOUNS.SELF_SELECT; - this.pronouns = hasSelfSelectedPronouns ? '' : pronouns; - - if (this.state.hasSelfSelectedPronouns === hasSelfSelectedPronouns) { - return; - } - - this.setState({hasSelfSelectedPronouns}); - } - - /** - * Submit form to update personal details - * @param {Object} values - * @param {String} values.pronouns - * @param {String} values.selfSelectedPronoun - */ - updatePronouns(values) { - PersonalDetails.updatePronouns( - this.state.hasSelfSelectedPronouns ? values.selfSelectedPronoun.trim() : values.pronouns.trim(), - ); - } +const PronounsPage = props => { + const currentPronouns = lodashGet(props.currentUserPersonalDetails, 'pronouns', ''); + const pronounsList = _.map(props.translate('pronouns'), (value, key) => ({ + text: value, + value: key, + keyForList: key, + + // Add green checkmark icon & bold the timezone text + customIcon: key === currentPronouns + ? {src: Expensicons.Checkmark, color: themeColors.textSuccess} + : null, + isUnread: key === currentPronouns, + })); /** - * @param {Object} values - An object containing the value of each inputID - * @param {String} values.pronouns - * @param {String} values.selfSelectedPronoun - * @returns {Object} - An object containing the errors for each inputID + * @param {String} selectedPronouns */ - validate(values) { - const errors = {}; - - const [hasPronounError] = ValidationUtils.doesFailCharacterLimitAfterTrim( - CONST.FORM_CHARACTER_LIMIT, - [values.pronouns], - ); - - if (hasPronounError) { - errors.pronouns = Localize.translateLocal('personalDetails.error.characterLimit', {limit: CONST.FORM_CHARACTER_LIMIT}); - } - - return errors; - } - - render() { - const pronounsList = _.map(this.props.translate('pronouns'), (value, key) => ({ - label: value, - value: `${CONST.PRONOUNS.PREFIX}${key}`, - })); - const pronounsPickerValue = this.state.hasSelfSelectedPronouns ? CONST.PRONOUNS.SELF_SELECT : this.pronouns; + const updatePronouns = selectedPronouns => { + PersonalDetails.updatePronouns(selectedPronouns); + }; - return ( - - Navigation.navigate(ROUTES.SETTINGS_PROFILE)} - onCloseButtonPress={() => Navigation.dismissModal(true)} + return ( + + Navigation.navigate(ROUTES.SETTINGS_PROFILE)} + onCloseButtonPress={() => Navigation.dismissModal(true)} + /> + + + {props.translate('pronounsPage.isShownOnProfile')} + + updatePronouns(option.value)} + hideSectionHeaders + disableFocusOptions + optionMode="default" + optionHoveredStyle={styles.hoveredComponentBG} + shouldHaveOptionSeparator /> -
- - {this.props.translate('pronounsPage.isShownOnProfile')} - - - - {this.state.hasSelfSelectedPronouns && ( - - - - )} - -
-
- ) - } -} +
+ + ); +}; PronounsPage.propTypes = propTypes; PronounsPage.defaultProps = defaultProps; From b916d21ec8e74f0189fe725e13e5a0ff32faa722 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Thu, 10 Nov 2022 16:03:54 -0800 Subject: [PATCH 10/17] Add ability to show option separator --- src/components/OptionRow.js | 15 +++++++++++++++ src/components/OptionsList/BaseOptionsList.js | 1 + .../OptionsList/optionsListPropTypes.js | 4 ++++ src/components/optionPropTypes.js | 9 +++++++++ 4 files changed, 29 insertions(+) diff --git a/src/components/OptionRow.js b/src/components/OptionRow.js index 9e0c56a8cb94..29c27cf57960 100644 --- a/src/components/OptionRow.js +++ b/src/components/OptionRow.js @@ -70,6 +70,9 @@ const propTypes = { /** Whether this option should be disabled */ isDisabled: PropTypes.bool, + /** Whether to show a line separating options in list */ + shouldHaveOptionSeparator: PropTypes.bool, + style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), ...withLocalizePropTypes, @@ -90,6 +93,7 @@ const defaultProps = { isDisabled: false, optionIsFocused: false, style: null, + shouldHaveOptionSeparator: false, }; const OptionRow = (props) => { @@ -164,6 +168,7 @@ const OptionRow = (props) => { props.optionIsFocused ? styles.sidebarLinkActive : null, hovered && !props.optionIsFocused ? props.hoverStyle : null, props.isDisabled && styles.cursorDisabled, + props.shouldHaveOptionSeparator && styles.borderTop, ]} > @@ -266,6 +271,16 @@ const OptionRow = (props) => { )} + {Boolean(props.option.customIcon) && ( + + + + )} )} diff --git a/src/components/OptionsList/BaseOptionsList.js b/src/components/OptionsList/BaseOptionsList.js index a1df92cfc7ef..a9470ab501c4 100644 --- a/src/components/OptionsList/BaseOptionsList.js +++ b/src/components/OptionsList/BaseOptionsList.js @@ -185,6 +185,7 @@ class BaseOptionsList extends Component { hideAdditionalOptionStates={this.props.hideAdditionalOptionStates} forceTextUnreadStyle={this.props.forceTextUnreadStyle} isDisabled={this.props.isDisabled || section.isDisabled} + shouldHaveOptionSeparator={index > 0 && this.props.shouldHaveOptionSeparator} /> ); } diff --git a/src/components/OptionsList/optionsListPropTypes.js b/src/components/OptionsList/optionsListPropTypes.js index b51fc14d64d7..c4ab5a3f301e 100644 --- a/src/components/OptionsList/optionsListPropTypes.js +++ b/src/components/OptionsList/optionsListPropTypes.js @@ -78,6 +78,9 @@ const propTypes = { /** Callback to execute when the SectionList lays out */ onLayout: PropTypes.func, + + /** Whether to show a line separating options in list */ + shouldHaveOptionSeparator: PropTypes.bool, }; const defaultProps = { @@ -100,6 +103,7 @@ const defaultProps = { optionMode: undefined, isDisabled: false, onLayout: undefined, + shouldHaveOptionSeparator: false, }; export {propTypes, defaultProps}; diff --git a/src/components/optionPropTypes.js b/src/components/optionPropTypes.js index 345e5b556023..32a4cc76cc66 100644 --- a/src/components/optionPropTypes.js +++ b/src/components/optionPropTypes.js @@ -39,6 +39,15 @@ export default PropTypes.shape({ // Whether the option has an outstanding IOU hasOutstandingIOU: PropTypes.bool, + // Custom icon to render on the right side of the option + customIcon: PropTypes.shape({ + // The icon source + src: PropTypes.func, + + // The color of the icon + color: PropTypes.string, + }), + // List of participants of the report participantsList: PropTypes.arrayOf(participantPropTypes), From 93cf62c08272a3c431b615d3e43001914494eb40 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Thu, 10 Nov 2022 16:13:35 -0800 Subject: [PATCH 11/17] Remove a few unneeded props --- src/pages/settings/Profile/PronounsPage.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/settings/Profile/PronounsPage.js b/src/pages/settings/Profile/PronounsPage.js index a3e6dfa2e7ce..acceda8fabec 100644 --- a/src/pages/settings/Profile/PronounsPage.js +++ b/src/pages/settings/Profile/PronounsPage.js @@ -61,8 +61,6 @@ const PronounsPage = props => { sections={[{data: pronounsList}]} onSelectRow={option => updatePronouns(option.value)} hideSectionHeaders - disableFocusOptions - optionMode="default" optionHoveredStyle={styles.hoveredComponentBG} shouldHaveOptionSeparator /> From a2185cee18e919d989d9a3224e05660479e85dd2 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Thu, 10 Nov 2022 16:27:45 -0800 Subject: [PATCH 12/17] Fix lint issues --- src/pages/settings/Profile/PronounsPage.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pages/settings/Profile/PronounsPage.js b/src/pages/settings/Profile/PronounsPage.js index acceda8fabec..6ac6a45d48e5 100644 --- a/src/pages/settings/Profile/PronounsPage.js +++ b/src/pages/settings/Profile/PronounsPage.js @@ -1,3 +1,4 @@ +import _ from 'underscore'; import lodashGet from 'lodash/get'; import React from 'react'; import {View} from 'react-native'; @@ -24,13 +25,13 @@ const defaultProps = { ...withCurrentUserPersonalDetailsDefaultProps, }; -const PronounsPage = props => { +const PronounsPage = (props) => { const currentPronouns = lodashGet(props.currentUserPersonalDetails, 'pronouns', ''); const pronounsList = _.map(props.translate('pronouns'), (value, key) => ({ text: value, value: key, keyForList: key, - + // Add green checkmark icon & bold the timezone text customIcon: key === currentPronouns ? {src: Expensicons.Checkmark, color: themeColors.textSuccess} @@ -41,7 +42,7 @@ const PronounsPage = props => { /** * @param {String} selectedPronouns */ - const updatePronouns = selectedPronouns => { + const updatePronouns = (selectedPronouns) => { PersonalDetails.updatePronouns(selectedPronouns); }; @@ -71,6 +72,7 @@ const PronounsPage = props => { PronounsPage.propTypes = propTypes; PronounsPage.defaultProps = defaultProps; +PronounsPage.displayName = 'PronounsPage'; export default compose( withLocalize, From 5c0992d81b917219f30e37706fad635b34b00591 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Thu, 10 Nov 2022 16:49:54 -0800 Subject: [PATCH 13/17] Add pronoun prefix to key --- src/pages/settings/Profile/PronounsPage.js | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/pages/settings/Profile/PronounsPage.js b/src/pages/settings/Profile/PronounsPage.js index 6ac6a45d48e5..b9bb8400bd04 100644 --- a/src/pages/settings/Profile/PronounsPage.js +++ b/src/pages/settings/Profile/PronounsPage.js @@ -15,6 +15,7 @@ import compose from '../../../libs/compose'; import OptionsList from '../../../components/OptionsList'; import themeColors from '../../../styles/themes/default'; import * as Expensicons from '../../../components/Icon/Expensicons'; +import CONST from '../../../CONST'; const propTypes = { ...withLocalizePropTypes, @@ -27,17 +28,20 @@ const defaultProps = { const PronounsPage = (props) => { const currentPronouns = lodashGet(props.currentUserPersonalDetails, 'pronouns', ''); - const pronounsList = _.map(props.translate('pronouns'), (value, key) => ({ - text: value, - value: key, - keyForList: key, + const pronounsList = _.map(props.translate('pronouns'), (value, key) => { + const fullPronounKey = `${CONST.PRONOUNS.PREFIX}${key}`; + return { + text: value, + value: fullPronounKey, + keyForList: key, - // Add green checkmark icon & bold the timezone text - customIcon: key === currentPronouns - ? {src: Expensicons.Checkmark, color: themeColors.textSuccess} - : null, - isUnread: key === currentPronouns, - })); + // Add green checkmark icon & bold the timezone text + customIcon: fullPronounKey === currentPronouns + ? {src: Expensicons.Checkmark, color: themeColors.textSuccess} + : null, + isUnread: fullPronounKey === currentPronouns, + }; + }); /** * @param {String} selectedPronouns From bce588b64263e36638b0b1d47db8ed7497f33c77 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Mon, 14 Nov 2022 15:36:40 -0800 Subject: [PATCH 14/17] Add a few additional pronouns --- src/languages/en.js | 19 +++++++++++++++---- src/languages/es.js | 14 ++++++++++++-- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index d3a78d390d9d..be1b3b612d22 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -308,10 +308,21 @@ export default { isShownOnProfile: 'Your pronouns are shown on your profile.', }, pronouns: { - heHimHis: 'He/him', - sheHerHers: 'She/her', - theyThemTheirs: 'They/them', - zeHirHirs: 'Ze/hir', + coCos: 'Co / Cos', + eEyEmEir: 'E / Ey / Em / Eir', + faeFaer: 'Fae / Faer', + heHimHis: 'He / Him / His', + sheHerHers: 'She / Her / Hers', + merMers: 'Mer / Mers', + neNirNirs: 'Ne / Nir / Nirs', + neeNerNers: 'Nee / Ner / Ners', + perPers: 'Per / Pers', + theyThemTheirs: 'They / Them / Theirs', + thonThons: 'Thon / Thons', + veVerVis: 'Ve / Ver / Vis', + viVir: 'Vi / Vir', + xeXemXyr: 'Xe / Xem / Xyr', + zeZieZirHir: 'Ze / Zie / Zir / Hir', callMeByMyName: 'Call me by my name', }, displayNamePage: { diff --git a/src/languages/es.js b/src/languages/es.js index 2b160a644607..73297343276d 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -263,7 +263,6 @@ export default { other: 'Error inesperado, por favor inténtalo más tarde', genericCreateFailureMessage: 'Error inesperado solicitando dinero, por favor inténtalo más tarde', genericCancelFailureMessage: ({type}) => `Error inesperado al ${type === 'decline' ? 'rechazar' : 'cancelar'} la solicitud de dinero, por favor inténtalo más tarde`, - }, }, notificationPreferences: { @@ -309,10 +308,21 @@ export default { isShownOnProfile: 'Tus pronombres se muestran en tu perfil.', }, pronouns: { + coCos: 'Co / Cos', + eEyEmEir: 'E / Ey / Em / Eir', + faeFaer: 'Fae / Faer', heHimHis: 'Él', sheHerHers: 'Ella', + merMers: 'Mer / Mers', + neNirNirs: 'Ne / Nir / Nirs', + neeNerNers: 'Nee / Ner / Ners', + perPers: 'Per / Pers', theyThemTheirs: 'Ellos', - zeHirHirs: 'Ze/hir', + thonThons: 'Thon / Thons', + veVerVis: 'Ve / Ver / Vis', + viVir: 'Vi / Vir', + xeXemXyr: 'Xe / Xem / Xyr', + zeHirHirs: 'Ze / Hir', callMeByMyName: 'Llámame por mi nombre', }, displayNamePage: { From a2662066fc821670e5309fd7ec9ad13c525e82b5 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Mon, 14 Nov 2022 15:46:54 -0800 Subject: [PATCH 15/17] Replace zeZieZirHir pronouns --- src/languages/es.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.js b/src/languages/es.js index 73297343276d..ffd4fb06748e 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -322,7 +322,7 @@ export default { veVerVis: 'Ve / Ver / Vis', viVir: 'Vi / Vir', xeXemXyr: 'Xe / Xem / Xyr', - zeHirHirs: 'Ze / Hir', + zeZieZirHir: 'Ze / Zie / Zir / Hir', callMeByMyName: 'Llámame por mi nombre', }, displayNamePage: { From cbff71dc218767f41d99a670bee1a2384458684a Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Mon, 14 Nov 2022 16:12:58 -0800 Subject: [PATCH 16/17] Fix pronoun list scrolling --- src/pages/settings/Profile/PronounsPage.js | 23 +++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/pages/settings/Profile/PronounsPage.js b/src/pages/settings/Profile/PronounsPage.js index b9bb8400bd04..53c35208934f 100644 --- a/src/pages/settings/Profile/PronounsPage.js +++ b/src/pages/settings/Profile/PronounsPage.js @@ -58,18 +58,17 @@ const PronounsPage = (props) => { onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_PROFILE)} onCloseButtonPress={() => Navigation.dismissModal(true)} /> - - - {props.translate('pronounsPage.isShownOnProfile')} - - updatePronouns(option.value)} - hideSectionHeaders - optionHoveredStyle={styles.hoveredComponentBG} - shouldHaveOptionSeparator - /> - + + {props.translate('pronounsPage.isShownOnProfile')} + + updatePronouns(option.value)} + hideSectionHeaders + optionHoveredStyle={styles.hoveredComponentBG} + shouldHaveOptionSeparator + contentContainerStyles={[styles.ph5]} + /> ); }; From 4b07208a3f9f3223ec3f7a8f8ed31709cb64f6c7 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Mon, 14 Nov 2022 16:56:14 -0800 Subject: [PATCH 17/17] Bye bye annoying import --- src/pages/settings/Profile/PronounsPage.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/settings/Profile/PronounsPage.js b/src/pages/settings/Profile/PronounsPage.js index 53c35208934f..796becb03cb3 100644 --- a/src/pages/settings/Profile/PronounsPage.js +++ b/src/pages/settings/Profile/PronounsPage.js @@ -1,7 +1,6 @@ import _ from 'underscore'; import lodashGet from 'lodash/get'; import React from 'react'; -import {View} from 'react-native'; import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../../components/withCurrentUserPersonalDetails'; import ScreenWrapper from '../../../components/ScreenWrapper'; import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton';