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

fix: No results found issue and refactor & merge NewGroupPage into NewChatPage #5138

Merged
merged 16 commits into from
Oct 20, 2021
Merged
2 changes: 1 addition & 1 deletion src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ export default {
detailsPage: {
localTime: 'Local time',
},
newGroupPage: {
newChatPage: {
createGroup: 'Create group',
},
notFound: {
Expand Down
2 changes: 1 addition & 1 deletion src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ export default {
detailsPage: {
localTime: 'Hora local',
},
newGroupPage: {
newChatPage: {
createGroup: 'Crear grupo',
},
notFound: {
Expand Down
34 changes: 1 addition & 33 deletions src/libs/OptionsListUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -566,35 +566,6 @@ function getSearchOptions(
});
}

/**
* Build the options for the New Chat view
*
* @param {Object} reports
* @param {Object} personalDetails
* @param {Array<String>} betas
* @param {String} searchValue
* @param {Array} excludeLogins
* @returns {Object}
*/
function getNewChatOptions(
reports,
personalDetails,
betas = [],
searchValue = '',
excludeLogins = [],

) {
return getOptions(reports, personalDetails, {}, 0, {
betas,
searchValue,
excludeDefaultRooms: true,
includePersonalDetails: true,
includeRecentReports: true,
maxRecentReportsToShow: 5,
excludeLogins,
});
}

/**
* Build the IOUConfirmation options for showing MyPersonalDetail
*
Expand Down Expand Up @@ -638,14 +609,13 @@ function getIOUConfirmationOptionsFromParticipants(
* @param {Array} excludeLogins
* @returns {Object}
*/
function getNewGroupOptions(
function getNewChatOptions(
reports,
personalDetails,
betas = [],
searchValue = '',
selectedOptions = [],
excludeLogins = [],

) {
return getOptions(reports, personalDetails, {}, 0, {
betas,
Expand All @@ -654,7 +624,6 @@ function getNewGroupOptions(
excludeDefaultRooms: true,
includeRecentReports: true,
includePersonalDetails: true,
includeMultipleParticipantReports: false,
maxRecentReportsToShow: 5,
excludeLogins,
});
Expand Down Expand Up @@ -777,7 +746,6 @@ export {
isCurrentUser,
getSearchOptions,
getNewChatOptions,
getNewGroupOptions,
getSidebarOptions,
getHeaderMessage,
getPersonalDetailsForLogins,
Expand Down
192 changes: 153 additions & 39 deletions src/pages/NewChatPage.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import _ from 'underscore';
import React, {Component} from 'react';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import OptionsSelector from '../components/OptionsSelector';
import {getNewChatOptions, getHeaderMessage} from '../libs/OptionsListUtils';
import ONYXKEYS from '../ONYXKEYS';
import styles from '../styles/styles';
import {fetchOrCreateChatReport} from '../libs/actions/Report';
import KeyboardSpacer from '../components/KeyboardSpacer';
import CONST, {EXCLUDED_GROUP_EMAILS} from '../CONST';
import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions';
import HeaderWithCloseButton from '../components/HeaderWithCloseButton';
import Navigation from '../libs/Navigation/Navigation';
import ScreenWrapper from '../components/ScreenWrapper';
import FullScreenLoadingIndicator from '../components/FullscreenLoadingIndicator';
import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
import compose from '../libs/compose';
import Button from '../components/Button';
import KeyboardAvoidingView from '../components/KeyboardAvoidingView';
import FixedFooter from '../components/FixedFooter';

const personalDetailsPropTypes = PropTypes.shape({
/** The login of the person (either email or phone number) */
Expand All @@ -27,11 +31,12 @@ const personalDetailsPropTypes = PropTypes.shape({

/** This is either the user's full name, or their login if full name is an empty string */
displayName: PropTypes.string.isRequired,

...withLocalizePropTypes,
});

const propTypes = {
/** Whether screen is used to create group chat */
groupChat: PropTypes.bool,

/** Beta features list */
betas: PropTypes.arrayOf(PropTypes.string).isRequired,

Expand All @@ -50,13 +55,23 @@ const propTypes = {
}).isRequired,

...windowDimensionsPropTypes,

...withLocalizePropTypes,
};

const defaultProps = {
groupChat: false,
roryabraham marked this conversation as resolved.
Show resolved Hide resolved
};

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

this.toggleOption = this.toggleOption.bind(this);
this.createGroup = this.createGroup.bind(this);
this.whenOptionSelected = this.whenOptionSelected.bind(this);
this.createNewChat = this.createNewChat.bind(this);

const {
recentReports,
personalDetails,
Expand All @@ -65,23 +80,39 @@ class NewChatPage extends Component {
props.reports,
props.personalDetails,
props.betas,
'',
[],
this.props.groupChat ? EXCLUDED_GROUP_EMAILS : [],
roryabraham marked this conversation as resolved.
Show resolved Hide resolved
);

this.state = {
searchValue: '',
recentReports,
personalDetails,
selectedOptions: [],
userToInvite,
};
}

/**
* Returns the sections needed for the OptionsSelector
*
* @param {Boolean} maxParticipantsReached
* @returns {Array}
*/
getSections() {
getSections(maxParticipantsReached) {
const sections = [];
if (this.props.groupChat) {
sections.push({
title: undefined,
roryabraham marked this conversation as resolved.
Show resolved Hide resolved
data: this.state.selectedOptions,
shouldShow: true,
indexOffset: 0,
});

if (maxParticipantsReached) {
return sections;
}
}

sections.push({
title: this.props.translate('common.recents'),
Expand Down Expand Up @@ -109,6 +140,61 @@ class NewChatPage extends Component {
return sections;
}

/**
* Once all our options are selected this method will call the API and create new chat between all selected users
* and the currently logged in user
*/
createGroup() {
const userLogins = _.map(this.state.selectedOptions, option => option.login);
roryabraham marked this conversation as resolved.
Show resolved Hide resolved
if (userLogins.length < 1) {
return;
}
fetchOrCreateChatReport([this.props.session.email, ...userLogins]);
}

/**
* Removes a selected option from list if already selected. If not already selected add this option to the list.
* @param {Object} option
*/
toggleOption(option) {
this.setState((prevState) => {
const isOptionInList = _.some(prevState.selectedOptions, selectedOption => (
selectedOption.login === option.login
));

let newSelectedOptions;

if (isOptionInList) {
newSelectedOptions = _.reject(prevState.selectedOptions, selectedOption => (
selectedOption.login === option.login
));
} else {
newSelectedOptions = [...prevState.selectedOptions, option];
}

const {
recentReports,
personalDetails,
userToInvite,
} = getNewChatOptions(
this.props.reports,
this.props.personalDetails,
this.props.betas,
isOptionInList ? prevState.searchValue : '',
newSelectedOptions,
EXCLUDED_GROUP_EMAILS,
);

return {
selectedOptions: newSelectedOptions,
recentReports,
personalDetails,
userToInvite,
searchValue: isOptionInList ? prevState.searchValue : '',
};
});
}

/**
* Creates a new chat with the option
* @param {Object} option
Expand All @@ -120,63 +206,91 @@ class NewChatPage extends Component {
]);
}

whenOptionSelected(option) {
roryabraham marked this conversation as resolved.
Show resolved Hide resolved
if (this.props.groupChat) {
return this.toggleOption(option);
}

this.createNewChat(option);
}

render() {
const sections = this.getSections();
const maxParticipantsReached = this.state.selectedOptions.length === CONST.REPORT.MAXIMUM_PARTICIPANTS;
const sections = this.getSections(maxParticipantsReached);
const headerMessage = getHeaderMessage(
this.state.personalDetails.length + this.state.recentReports.length !== 0,
(this.state.personalDetails.length + this.state.recentReports.length) !== 0,
Boolean(this.state.userToInvite),
this.state.searchValue,
maxParticipantsReached,
);

return (
<ScreenWrapper>
{({didScreenTransitionEnd}) => (
<>
<KeyboardAvoidingView>
<HeaderWithCloseButton
title={this.props.translate('sidebarScreen.newChat')}
title={this.props.groupChat
? this.props.translate('sidebarScreen.newGroup')
: this.props.translate('sidebarScreen.newChat')}
onCloseButtonPress={() => Navigation.dismissModal(true)}
/>
<View style={[styles.flex1, styles.w100, styles.pRelative]}>
<FullScreenLoadingIndicator visible={!didScreenTransitionEnd} />
{didScreenTransitionEnd && (
<OptionsSelector
sections={sections}
value={this.state.searchValue}
onSelectRow={this.createNewChat}
onChangeText={(searchValue = '') => {
const {
recentReports,
personalDetails,
userToInvite,
} = getNewChatOptions(
this.props.reports,
this.props.personalDetails,
this.props.betas,
searchValue,
);
this.setState({
searchValue,
recentReports,
userToInvite,
personalDetails,
});
}}
headerMessage={headerMessage}
disableArrowKeysActions
hideAdditionalOptionStates
forceTextUnreadStyle
/>
<>
<OptionsSelector
canSelectMultipleOptions={this.props.groupChat}
sections={sections}
selectedOptions={this.state.selectedOptions}
value={this.state.searchValue}
onSelectRow={this.whenOptionSelected}
onChangeText={(searchValue = '') => {
const {
recentReports,
personalDetails,
userToInvite,
} = getNewChatOptions(
this.props.reports,
this.props.personalDetails,
this.props.betas,
searchValue,
[],
this.props.groupChat ? EXCLUDED_GROUP_EMAILS : [],
);
this.setState({
searchValue,
userToInvite,
recentReports,
personalDetails,
});
}}
headerMessage={headerMessage}
disableArrowKeysActions
hideAdditionalOptionStates
forceTextUnreadStyle
/>
{!this.props.groupChat && <KeyboardSpacer />}
{this.props.groupChat && this.state.selectedOptions?.length > 0 && (
<FixedFooter>
<Button
success
onPress={this.createGroup}
style={[styles.w100]}
text={this.props.translate('newChatPage.createGroup')}
/>
</FixedFooter>
)}
</>
)}
</View>
<KeyboardSpacer />
</>
</KeyboardAvoidingView>
)}
</ScreenWrapper>
);
}
}

NewChatPage.propTypes = propTypes;
NewChatPage.defaultProps = defaultProps;

export default compose(
withLocalize,
Expand Down
Loading