Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 106 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,119 @@ 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 the pronouns have changed, we need to update the pronouns list because refreshing the page
// breaks the component lifecycle, so we need to "manually" reset the component.
if (prevProps.currentUserPersonalDetails.pronouns === this.props.currentUserPersonalDetails.pronouns) {
return;
}

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 {Object} selectedPronouns
*/
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