Skip to content

Commit

Permalink
Create ReportActionsUtils - move methods out of ReportActionsView
Browse files Browse the repository at this point in the history
Move another method

remove fancy jsdocs

improve doc comments

use correct function name
  • Loading branch information
marcaaron committed Apr 28, 2022
1 parent 31e49ec commit a0f34ad
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 83 deletions.
82 changes: 82 additions & 0 deletions src/libs/ReportActionsUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import _ from 'underscore';
import CONST from '../CONST';

/**
* @param {Object} reportAction
* @returns {Boolean}
*/
function isDeletedAction(reportAction) {
// A deleted comment has either an empty array or an object with html field with empty string as value
return reportAction.message.length === 0 || reportAction.message[0].html === '';
}

/**
* Sorts the report actions by sequence number, filters out any that should not be shown and formats them for display.
*
* @param {Array} reportActions
* @returns {Array}
*/
function getSortedReportActions(reportActions) {
return _.chain(reportActions)
.sortBy('sequenceNumber')
.filter(action => action.actionName === CONST.REPORT.ACTIONS.TYPE.IOU
|| (action.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT && !isDeletedAction(action))
|| action.actionName === CONST.REPORT.ACTIONS.TYPE.RENAMED
|| action.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED)
.map((item, index) => ({action: item, index}))
.value()
.reverse();
}

/**
* Finds most recent IOU report action number.
*
* @param {Array} reportActions
* @returns {Number}
*/
function getMostRecentIOUReportSequenceNumber(reportActions) {
return _.chain(reportActions)
.sortBy('sequenceNumber')
.filter(action => action.actionName === CONST.REPORT.ACTIONS.TYPE.IOU)
.max(action => action.sequenceNumber)
.value().sequenceNumber;
}

/**
* Returns true when the report action immediately before the specified index is a comment made by the same actor who who is leaving a comment in the action at the specified index.
* Also checks to ensure that the comment is not too old to be shown as a grouped comment.
*
* @param {Array} reportActions
* @param {Number} actionIndex - index of the comment item in state to check
* @returns {Boolean}
*/
function isConsecutiveActionMadeByPreviousActor(reportActions, actionIndex) {
const previousAction = reportActions[actionIndex + 1];
const currentAction = reportActions[actionIndex];

// It's OK for there to be no previous action, and in that case, false will be returned
// so that the comment isn't grouped
if (!currentAction || !previousAction) {
return false;
}

// Comments are only grouped if they happen within 5 minutes of each other
if (currentAction.action.timestamp - previousAction.action.timestamp > 300) {
return false;
}

// Do not group if previous or current action was a renamed action
if (previousAction.action.actionName === CONST.REPORT.ACTIONS.TYPE.RENAMED
|| currentAction.action.actionName === CONST.REPORT.ACTIONS.TYPE.RENAMED) {
return false;
}

return currentAction.action.actorEmail === previousAction.action.actorEmail;
}

export {
getSortedReportActions,
getMostRecentIOUReportSequenceNumber,
isDeletedAction,
isConsecutiveActionMadeByPreviousActor,
};
3 changes: 2 additions & 1 deletion src/libs/actions/ReportActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ONYXKEYS from '../../ONYXKEYS';
import * as CollectionUtils from '../CollectionUtils';
import CONST from '../../CONST';
import * as ReportUtils from '../reportUtils';
import * as ReportActionsUtils from '../ReportActionsUtils';

/**
* Map of the most recent non-loading sequenceNumber for a reportActions_* key in Onyx by reportID.
Expand Down Expand Up @@ -103,7 +104,7 @@ function getDeletedCommentsCount(reportID, sequenceNumber) {
*/
function getLastVisibleMessageText(reportID) {
const lastMessageIndex = _.findLastIndex(reportActions[reportID], action => (
!ReportUtils.isDeletedAction(action)
!ReportActionsUtils.isDeletedAction(action)
));

return ReportUtils.formatReportLastMessageText(
Expand Down
11 changes: 0 additions & 11 deletions src/libs/reportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,16 +289,6 @@ function canShowReportRecipientLocalTime(personalDetails, report) {
&& reportRecipientTimezone.selected;
}

/**
* Check if the comment is deleted
* @param {Object} action
* @returns {Boolean}
*/
function isDeletedAction(action) {
// A deleted comment has either an empty array or an object with html field with empty string as value
return action.message.length === 0 || action.message[0].html === '';
}

/**
* Trim the last message text to a fixed limit.
* @param {String} lastMessageText
Expand Down Expand Up @@ -375,7 +365,6 @@ function getIcons(report, personalDetails, policies, defaultIcon = null) {

export {
getReportParticipantsTitle,
isDeletedAction,
isReportMessageAttachment,
findLastAccessedReport,
canEditReportAction,
Expand Down
77 changes: 6 additions & 71 deletions src/pages/home/report/ReportActionsView.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import EmojiPicker from '../../../components/EmojiPicker';
import * as EmojiPickerAction from '../../../libs/actions/EmojiPickerAction';
import FloatingMessageCounter from './FloatingMessageCounter';
import networkPropTypes from '../../../components/networkPropTypes';
import * as ReportActionsUtils from '../../../libs/ReportActionsUtils';

const propTypes = {
/** The ID of the report actions will be created for */
Expand Down Expand Up @@ -111,7 +112,6 @@ class ReportActionsView extends React.Component {
this.onVisibilityChange = this.onVisibilityChange.bind(this);
this.recordTimeToMeasureItemLayout = this.recordTimeToMeasureItemLayout.bind(this);
this.loadMoreChats = this.loadMoreChats.bind(this);
this.sortedReportActions = [];
this.appStateChangeListener = null;

this.didLayout = false;
Expand All @@ -122,8 +122,8 @@ class ReportActionsView extends React.Component {
};

this.currentScrollOffset = 0;
this.updateSortedReportActions(props.reportActions);
this.updateMostRecentIOUReportActionNumber(props.reportActions);
this.sortedReportActions = ReportActionsUtils.getSortedReportActions(props.reportActions);
this.mostRecentIOUReportSequenceNumber = ReportActionsUtils.getMostRecentIOUReportSequenceNumber(props.reportActions);
this.keyExtractor = this.keyExtractor.bind(this);
this.trackScroll = this.trackScroll.bind(this);
this.showFloatingMessageCounter = this.showFloatingMessageCounter.bind(this);
Expand Down Expand Up @@ -168,8 +168,8 @@ class ReportActionsView extends React.Component {

shouldComponentUpdate(nextProps, nextState) {
if (!_.isEqual(nextProps.reportActions, this.props.reportActions)) {
this.updateSortedReportActions(nextProps.reportActions);
this.updateMostRecentIOUReportActionNumber(nextProps.reportActions);
this.sortedReportActions = ReportActionsUtils.getSortedReportActions(nextProps.reportActions);
this.mostRecentIOUReportSequenceNumber = ReportActionsUtils.getMostRecentIOUReportSequenceNumber(nextProps.reportActions);
return true;
}

Expand Down Expand Up @@ -351,71 +351,6 @@ class ReportActionsView extends React.Component {
return Math.ceil(availableHeight / minimumReportActionHeight);
}

/**
* Updates and sorts the report actions by sequence number
*
* @param {Array<{sequenceNumber, actionName}>} reportActions
*/
updateSortedReportActions(reportActions) {
this.sortedReportActions = _.chain(reportActions)
.sortBy('sequenceNumber')
.filter(action => action.actionName === CONST.REPORT.ACTIONS.TYPE.IOU
|| (action.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT && !ReportUtils.isDeletedAction(action))
|| action.actionName === CONST.REPORT.ACTIONS.TYPE.RENAMED
|| action.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED)
.map((item, index) => ({action: item, index}))
.value()
.reverse();
}

/**
* Returns true when the report action immediately before the
* specified index is a comment made by the same actor who who
* is leaving a comment in the action at the specified index.
* Also checks to ensure that the comment is not too old to
* be considered part of the same comment
*
* @param {Number} actionIndex - index of the comment item in state to check
*
* @return {Boolean}
*/
isConsecutiveActionMadeByPreviousActor(actionIndex) {
const previousAction = this.sortedReportActions[actionIndex + 1];
const currentAction = this.sortedReportActions[actionIndex];

// It's OK for there to be no previous action, and in that case, false will be returned
// so that the comment isn't grouped
if (!currentAction || !previousAction) {
return false;
}

// Comments are only grouped if they happen within 5 minutes of each other
if (currentAction.action.timestamp - previousAction.action.timestamp > 300) {
return false;
}

// Do not group if previous or current action was a renamed action
if (previousAction.action.actionName === CONST.REPORT.ACTIONS.TYPE.RENAMED
|| currentAction.action.actionName === CONST.REPORT.ACTIONS.TYPE.RENAMED) {
return false;
}

return currentAction.action.actorEmail === previousAction.action.actorEmail;
}

/**
* Finds and updates most recent IOU report action number
*
* @param {Array<{sequenceNumber, actionName}>} reportActions
*/
updateMostRecentIOUReportActionNumber(reportActions) {
this.mostRecentIOUReportSequenceNumber = _.chain(reportActions)
.sortBy('sequenceNumber')
.filter(action => action.actionName === CONST.REPORT.ACTIONS.TYPE.IOU)
.max(action => action.sequenceNumber)
.value().sequenceNumber;
}

/**
* This function is triggered from the ref callback for the scrollview. That way it can be scrolled once all the
* items have been rendered. If the number of actions has changed since it was last rendered, then
Expand Down Expand Up @@ -567,7 +502,7 @@ class ReportActionsView extends React.Component {
<ReportActionItem
reportID={this.props.reportID}
action={item.action}
displayAsGroup={this.isConsecutiveActionMadeByPreviousActor(index)}
displayAsGroup={ReportActionsUtils.isConsecutiveActionMadeByPreviousActor(this.sortedReportActions, index)}
shouldDisplayNewIndicator={shouldDisplayNewIndicator}
isMostRecentIOUReportAction={item.action.sequenceNumber === this.mostRecentIOUReportSequenceNumber}
hasOutstandingIOU={this.props.report.hasOutstandingIOU}
Expand Down

0 comments on commit a0f34ad

Please sign in to comment.