Skip to content

Commit

Permalink
Merge pull request #20178 from priyeshshah11/migrate/pronouns-page
Browse files Browse the repository at this point in the history
Migrated PronounsPage to functional component
  • Loading branch information
mountiny authored Jun 21, 2023
2 parents 40ece23 + 409f391 commit c2059ef
Showing 1 changed file with 75 additions and 88 deletions.
163 changes: 75 additions & 88 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, {Component} from 'react';
import React, {useState, useEffect, useMemo, useCallback} from 'react';
import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../../components/withCurrentUserPersonalDetails';
import ScreenWrapper from '../../../components/ScreenWrapper';
import HeaderWithBackButton from '../../../components/HeaderWithBackButton';
Expand All @@ -27,69 +27,29 @@ const defaultProps = {
...withCurrentUserPersonalDetailsDefaultProps,
};

class PronounsPage extends Component {
constructor(props) {
super(props);

this.loadPronouns = this.loadPronouns.bind(this);
this.onChangeText = this.onChangeText.bind(this);
this.getFilteredPronouns = this.getFilteredPronouns.bind(this);
this.updatePronouns = this.updatePronouns.bind(this);
this.initiallyFocusedOption = {};

this.loadPronouns();
this.state = {
searchValue: this.initiallyFocusedOption.text || '',
};
}

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});
}

/**
* Returns the pronouns list filtered by searchValue needed for the OptionsSelector.
* Empty array is returned if the searchValue is empty.
*
* @returns {Array}
*/
getFilteredPronouns() {
const searchedValue = this.state.searchValue.trim();
if (searchedValue.length === 0) {
return [];
}
return _.filter(this.pronounsList, (pronous) => pronous.text.toLowerCase().indexOf(searchedValue.toLowerCase()) >= 0);
}
function PronounsPage(props) {
const [initiallyFocusedOption, setInitiallyFocusedOption] = useState({});
const [searchValue, setSearchValue] = useState('');
const [pronounsList, setPronounsList] = useState([]);

/**
* 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', '');
const loadPronouns = useCallback(() => {
const currentPronouns = lodashGet(props.currentUserPersonalDetails, 'pronouns', '');

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

if (isCurrentPronouns) {
this.initiallyFocusedOption = {
setInitiallyFocusedOption({
text: value,
keyForList: key,
};
});
}

return {
Expand All @@ -106,51 +66,78 @@ class PronounsPage extends Component {
})
.sortBy((pronoun) => pronoun.text.toLowerCase())
.value();
}

setPronounsList(pronouns);

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.currentUserPersonalDetails.pronouns]);

const onChangeText = (value = '') => {
setSearchValue(value);
};

/**
* @param {Object} selectedPronouns
*/
updatePronouns(selectedPronouns) {
PersonalDetails.updatePronouns(selectedPronouns.keyForList === this.initiallyFocusedOption.keyForList ? '' : lodashGet(selectedPronouns, 'value', ''));
}

render() {
const filteredPronounsList = this.getFilteredPronouns();
const headerMessage = this.state.searchValue.trim() && !filteredPronounsList.length ? this.props.translate('common.noResultsFound') : '';

return (
<ScreenWrapper includeSafeAreaPaddingBottom={false}>
{({safeAreaPaddingBottomStyle}) => (
<>
<HeaderWithBackButton
title={this.props.translate('pronounsPage.pronouns')}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_PROFILE)}
/>
<Text style={[styles.ph5, styles.mb3]}>{this.props.translate('pronounsPage.isShownOnProfile')}</Text>
<OptionsSelector
textInputLabel={this.props.translate('pronounsPage.pronouns')}
placeholderText={this.props.translate('pronounsPage.placeholderText')}
headerMessage={headerMessage}
sections={[{data: filteredPronounsList, indexOffset: 0}]}
value={this.state.searchValue}
onSelectRow={this.updatePronouns}
onChangeText={this.onChangeText}
optionHoveredStyle={styles.hoveredComponentBG}
safeAreaPaddingBottomStyle={safeAreaPaddingBottomStyle}
shouldDelayFocus
shouldFocusOnSelectRow
shouldHaveOptionSeparator
initiallyFocusedOptionKey={this.initiallyFocusedOption.keyForList}
/>
</>
)}
</ScreenWrapper>
);
}
const updatePronouns = (selectedPronouns) => {
PersonalDetails.updatePronouns(selectedPronouns.keyForList === initiallyFocusedOption.keyForList ? '' : lodashGet(selectedPronouns, 'value', ''));
};

/**
* Pronouns list filtered by searchValue needed for the OptionsSelector.
* Empty array if the searchValue is empty.
*/
const filteredPronounsList = useMemo(() => {
const searchedValue = searchValue.trim();
if (searchedValue.length === 0) {
return [];
}
return _.filter(pronounsList, (pronous) => pronous.text.toLowerCase().indexOf(searchedValue.toLowerCase()) >= 0);
}, [pronounsList, searchValue]);

const headerMessage = searchValue.trim() && !filteredPronounsList.length ? props.translate('common.noResultsFound') : '';

useEffect(() => {
setSearchValue(initiallyFocusedOption.text);
}, [initiallyFocusedOption]);

useEffect(() => {
onChangeText();
loadPronouns();
}, [loadPronouns]);

return (
<ScreenWrapper includeSafeAreaPaddingBottom={false}>
{({safeAreaPaddingBottomStyle}) => (
<>
<HeaderWithBackButton
title={props.translate('pronounsPage.pronouns')}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_PROFILE)}
/>
<Text style={[styles.ph5, styles.mb3]}>{props.translate('pronounsPage.isShownOnProfile')}</Text>
<OptionsSelector
textInputLabel={props.translate('pronounsPage.pronouns')}
placeholderText={props.translate('pronounsPage.placeholderText')}
headerMessage={headerMessage}
sections={[{data: filteredPronounsList, indexOffset: 0}]}
value={searchValue}
onSelectRow={updatePronouns}
onChangeText={onChangeText}
optionHoveredStyle={styles.hoveredComponentBG}
safeAreaPaddingBottomStyle={safeAreaPaddingBottomStyle}
shouldDelayFocus
shouldFocusOnSelectRow
shouldHaveOptionSeparator
initiallyFocusedOptionKey={initiallyFocusedOption.keyForList}
/>
</>
)}
</ScreenWrapper>
);
}

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

export default compose(withLocalize, withCurrentUserPersonalDetails)(PronounsPage);

0 comments on commit c2059ef

Please sign in to comment.