Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

15211: search pronouns #15317

Merged
merged 10 commits into from
Feb 28, 2023
151 changes: 104 additions & 47 deletions src/pages/settings/Profile/PronounsPage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _ from 'underscore';
import lodashGet from 'lodash/get';
import React from 'react';
import React, {Component} from 'react';
import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../../components/withCurrentUserPersonalDetails';
import ScreenWrapper from '../../../components/ScreenWrapper';
import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton';
Expand All @@ -11,10 +11,10 @@ import styles from '../../../styles/styles';
import Navigation from '../../../libs/Navigation/Navigation';
import * as PersonalDetails from '../../../libs/actions/PersonalDetails';
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';
import OptionsSelector from '../../../components/OptionsSelector';

const greenCheckmark = {src: Expensicons.Checkmark, color: themeColors.success};

Expand All @@ -27,60 +27,117 @@ const defaultProps = {
...withCurrentUserPersonalDetailsDefaultProps,
};

const PronounsPage = (props) => {
const currentPronouns = lodashGet(props.currentUserPersonalDetails, 'pronouns', '');
const pronounsList = _.map(props.translate('pronouns'), (value, key) => {
const fullPronounKey = `${CONST.PRONOUNS.PREFIX}${key}`;
return {
text: value,
value: fullPronounKey,
keyForList: key,
class PronounsPage extends Component {
constructor(props) {
super(props);

// Include the green checkmark icon to indicate the currently selected value
customIcon: fullPronounKey === currentPronouns ? greenCheckmark : undefined,
this.loadPronouns = this.loadPronouns.bind(this);
this.onChangeText = this.onChangeText.bind(this);
this.getFilteredPronouns = this.getFilteredPronouns.bind(this);

// This property will make the currently selected value have bold text
boldStyle: fullPronounKey === currentPronouns,
this.loadPronouns();
this.state = {
searchValue: '',
};
});
}

componentDidUpdate(prevProps) {
if (prevProps.currentUserPersonalDetails.pronouns === this.props.currentUserPersonalDetails.pronouns) {
return;
}
mountiny marked this conversation as resolved.
Show resolved Hide resolved

this.onChangeText();
this.loadPronouns();
}

onChangeText(searchValue = '') {
this.setState({searchValue});
}

/**
* @param {String} selectedPronouns
* Returns the pronouns list filtered by searchValue needed for the OptionsSelector.
* Empty array is returned if the searchValue is empty.
*
* @returns {Array}
*/
const updatePronouns = (selectedPronouns) => {
PersonalDetails.updatePronouns(selectedPronouns);
};

return (
<ScreenWrapper includeSafeAreaPaddingBottom={false}>
{({safeAreaPaddingBottomStyle}) => (
<>
<HeaderWithCloseButton
title={props.translate('pronounsPage.pronouns')}
shouldShowBackButton
onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_PROFILE)}
onCloseButtonPress={() => Navigation.dismissModal(true)}
/>
<Text style={[styles.ph5, styles.mb6]}>
{props.translate('pronounsPage.isShownOnProfile')}
</Text>
<OptionsList
sections={[{data: pronounsList}]}
onSelectRow={option => updatePronouns(option.value)}
hideSectionHeaders
optionHoveredStyle={styles.hoveredComponentBG}
shouldHaveOptionSeparator
contentContainerStyles={[styles.ph5, safeAreaPaddingBottomStyle]}
/>
</>
)}
</ScreenWrapper>
);
};
getFilteredPronouns() {
const searchedValue = this.state.searchValue.trim();
if (searchedValue.length === 0) {
return [];
}
return _.filter(this.pronounsList,
pronous => pronous.text.toLowerCase().indexOf(searchedValue.toLowerCase()) >= 0);
}

/**
* Loads the pronouns list from the translations and adds the green checkmark icon to the currently selected value.
*
* @returns {void}
*/
loadPronouns() {
const currentPronouns = lodashGet(this.props.currentUserPersonalDetails, 'pronouns', '');

this.pronounsList = _.map(this.props.translate('pronouns'), (value, key) => {
const fullPronounKey = `${CONST.PRONOUNS.PREFIX}${key}`;
const isCurrentPronouns = fullPronounKey === currentPronouns;

return {
text: value,
value: fullPronounKey,
keyForList: key,

// Include the green checkmark icon to indicate the currently selected value
customIcon: isCurrentPronouns ? greenCheckmark : undefined,

// This property will make the currently selected value have bold text
boldStyle: isCurrentPronouns,
};
});
}

/**
* @param {Obj} selectedPronouns
mountiny marked this conversation as resolved.
Show resolved Hide resolved
*/
updatePronouns(selectedPronouns) {
PersonalDetails.updatePronouns(selectedPronouns.value);
}

render() {
const filteredPronounsList = this.getFilteredPronouns();

return (
<ScreenWrapper includeSafeAreaPaddingBottom={false}>
{({safeAreaPaddingBottomStyle}) => (
<>
<HeaderWithCloseButton
title={this.props.translate('pronounsPage.pronouns')}
shouldShowBackButton
onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_PROFILE)}
onCloseButtonPress={() => Navigation.dismissModal(true)}
/>
<Text style={styles.ph5}>
{this.props.translate('pronounsPage.isShownOnProfile')}
</Text>
<OptionsSelector
textInputLabel={this.props.translate('pronounsPage.pronouns')}
sections={[{data: filteredPronounsList}]}
value={this.state.searchValue}
onSelectRow={this.updatePronouns}
onChangeText={this.onChangeText}
optionHoveredStyle={styles.hoveredComponentBG}
safeAreaPaddingBottomStyle={safeAreaPaddingBottomStyle}
shouldFocusOnSelectRow
shouldHaveOptionSeparator
/>
</>
)}
</ScreenWrapper>
);
}
}

PronounsPage.propTypes = propTypes;
PronounsPage.defaultProps = defaultProps;
PronounsPage.displayName = 'PronounsPage';

export default compose(
withLocalize,
Expand Down