Skip to content
Draft
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable rulesdir/prefer-early-return */
import {useIsFocused, useRoute} from '@react-navigation/native';
import stableReportSelector from '@selectors/stableReportSelector';
import isEmpty from 'lodash/isEmpty';
import React, {useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react';
import type {LayoutChangeEvent, ListRenderItemInfo, NativeScrollEvent, NativeSyntheticEvent} from 'react-native';
Expand Down Expand Up @@ -51,6 +52,7 @@ import Visibility from '@libs/Visibility';
import isSearchTopmostFullScreenRoute from '@navigation/helpers/isSearchTopmostFullScreenRoute';
import FloatingMessageCounter from '@pages/inbox/report/FloatingMessageCounter';
import getInitialNumToRender from '@pages/inbox/report/getInitialNumReportActionsToRender';
import ReportActionIndexContext from '@pages/inbox/report/ReportActionIndexContext';
import ReportActionsListItemRenderer from '@pages/inbox/report/ReportActionsListItemRenderer';
import {getUnreadMarkerReportAction} from '@pages/inbox/report/shouldDisplayNewMarkerOnReportAction';
import useReportUnreadMessageScrollTracking from '@pages/inbox/report/useReportUnreadMessageScrollTracking';
Expand Down Expand Up @@ -99,6 +101,7 @@ function MoneyRequestReportActionsList({onLayout}: MoneyRequestReportListProps)
// Self-subscribe to report, policy, metadata, actions, transactions
// report is guaranteed to exist — callers only render this component when report is loaded
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportIDFromRoute}`) as unknown as [OnyxTypes.Report];
const [reportStable] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportIDFromRoute}`, {selector: stableReportSelector});
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(report?.policyID)}`);
const [reportLoadingState] = useOnyx(`${ONYXKEYS.COLLECTION.RAM_ONLY_REPORT_LOADING_STATE}${reportIDFromRoute}`);
const [reportPaginationState] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_PAGINATION_STATE}${reportIDFromRoute}`);
Expand Down Expand Up @@ -559,34 +562,35 @@ function MoneyRequestReportActionsList({onLayout}: MoneyRequestReportListProps)
!isConsecutiveChronosAutomaticTimerAction(visibleReportActions, index, chatIncludesChronosWithID(reportAction?.reportID), isOffline) &&
hasNextActionMadeBySameActor(visibleReportActions, index, isOffline);

const originalReportID = getOriginalReportID(report?.reportID, reportAction, reportActionsObject);
const originalReportID = getOriginalReportID(reportStable?.reportID, reportAction, reportActionsObject);

return (
<ReportActionsListItemRenderer
reportAction={reportAction}
parentReportAction={parentReportAction}
parentReportActionForTransactionThread={EmptyParentReportActionForTransactionThread}
index={index}
report={report}
transactionThreadReport={transactionThreadReport}
displayAsGroup={displayAsGroup}
shouldDisplayNewMarker={reportAction.reportActionID === unreadMarkerReportActionID}
shouldDisplayReplyDivider={visibleReportActions.length > 1}
isFirstVisibleReportAction={firstVisibleReportActionID === reportAction.reportActionID}
shouldHideThreadDividerLine
linkedReportActionID={linkedReportActionID}
personalDetails={personalDetails}
originalReportID={originalReportID}
isReportArchived={isReportArchived}
isHarvestCreatedExpenseReport={shouldShowHarvestCreatedAction}
/>
<ReportActionIndexContext.Provider value={index}>
<ReportActionsListItemRenderer
reportAction={reportAction}
parentReportAction={parentReportAction}
parentReportActionForTransactionThread={EmptyParentReportActionForTransactionThread}
report={reportStable}
transactionThreadReport={transactionThreadReport}
displayAsGroup={displayAsGroup}
shouldDisplayNewMarker={reportAction.reportActionID === unreadMarkerReportActionID}
shouldDisplayReplyDivider={visibleReportActions.length > 1}
isFirstVisibleReportAction={firstVisibleReportActionID === reportAction.reportActionID}
shouldHideThreadDividerLine
linkedReportActionID={linkedReportActionID}
personalDetails={personalDetails}
originalReportID={originalReportID}
isReportArchived={isReportArchived}
isHarvestCreatedExpenseReport={shouldShowHarvestCreatedAction}
/>
</ReportActionIndexContext.Provider>
);
},
[
visibleReportActions,
reportActionsObject,
parentReportAction,
report,
reportStable,
isOffline,
transactionThreadReport,
unreadMarkerReportActionID,
Expand Down
4 changes: 2 additions & 2 deletions src/components/Search/SearchList/ListItem/ChatListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import stableReportSelector from '@selectors/stableReportSelector';
import React from 'react';
import BaseListItem from '@components/SelectionList/ListItem/BaseListItem';
import type {ListItem} from '@components/SelectionList/types';
Expand Down Expand Up @@ -28,7 +29,7 @@ function ChatListItem<TItem extends ListItem>({
personalDetails,
}: ChatListItemProps<TItem>) {
const reportActionItem = item as unknown as ReportActionListItemType;
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportActionItem?.reportID}`);
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportActionItem?.reportID}`, {selector: stableReportSelector});
const styles = useThemeStyles();
const theme = useTheme();
const animatedHighlightStyle = useAnimatedHighlightStyle({
Expand Down Expand Up @@ -79,7 +80,6 @@ function ChatListItem<TItem extends ListItem>({
parentReportAction={undefined}
displayAsGroup={false}
shouldDisplayNewMarker={false}
index={item.index ?? 0}
isFirstVisibleReportAction={false}
shouldDisplayContextMenu={false}
shouldShowDraftMessage={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ function DebugReportActionCreatePage({
parentReportAction={undefined}
displayAsGroup={false}
shouldDisplayNewMarker={false}
index={0}
isFirstVisibleReportAction={false}
shouldDisplayContextMenu={false}
personalDetails={personalDetailsList}
Expand Down
1 change: 0 additions & 1 deletion src/pages/Debug/ReportAction/DebugReportActionPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ function DebugReportActionPreview({reportAction, reportID}: DebugReportActionPre
parentReportAction={undefined}
displayAsGroup={false}
shouldDisplayNewMarker={false}
index={0}
isFirstVisibleReportAction={false}
shouldDisplayContextMenu={false}
personalDetails={personalDetails}
Expand Down
31 changes: 17 additions & 14 deletions src/pages/TransactionDuplicate/DuplicateTransactionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import useThemeStyles from '@hooks/useThemeStyles';
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
import {getOriginalMessage, getReportAction, isMoneyRequestAction} from '@libs/ReportActionsUtils';
import {getOriginalReportID} from '@libs/ReportUtils';
import ReportActionIndexContext from '@pages/inbox/report/ReportActionIndexContext';
import ReportActionItem from '@pages/inbox/report/ReportActionItem';
import {ReportActionItemActionsContext, ReportActionItemStateContext} from '@pages/inbox/report/ReportActionItemContext';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Transaction} from '@src/types/onyx';
import stableReportSelector from '@src/selectors/stableReportSelector';

type DuplicateTransactionItemProps = {
transaction: OnyxEntry<Transaction>;
Expand All @@ -25,7 +27,7 @@ function DuplicateTransactionItem({transaction, index, onPreviewPressed}: Duplic
const styles = useThemeStyles();
const personalDetails = usePersonalDetails();

const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`);
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`, {selector: stableReportSelector});
const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.reportID}`);

const action = Object.values(reportActions ?? {})?.find((reportAction) => {
Expand Down Expand Up @@ -58,19 +60,20 @@ function DuplicateTransactionItem({transaction, index, onPreviewPressed}: Duplic
<View style={styles.pb2}>
<ReportActionItemStateContext.Provider value={stateValue}>
<ReportActionItemActionsContext.Provider value={actionsValue}>
<ReportActionItem
action={action}
report={report}
parentReportAction={getReportAction(report?.parentReportID, report?.parentReportActionID)}
index={index}
displayAsGroup={false}
shouldDisplayNewMarker={false}
isFirstVisibleReportAction={false}
shouldDisplayContextMenu={false}
personalDetails={personalDetails}
draftMessage={matchingDraftMessage}
linkedTransactionRouteError={linkedTransactionRouteError}
/>
<ReportActionIndexContext.Provider value={index}>
<ReportActionItem
action={action}
report={report}
parentReportAction={getReportAction(report?.parentReportID, report?.parentReportActionID)}
displayAsGroup={false}
shouldDisplayNewMarker={false}
isFirstVisibleReportAction={false}
shouldDisplayContextMenu={false}
personalDetails={personalDetails}
draftMessage={matchingDraftMessage}
linkedTransactionRouteError={linkedTransactionRouteError}
/>
</ReportActionIndexContext.Provider>
</ReportActionItemActionsContext.Provider>
</ReportActionItemStateContext.Provider>
</View>
Expand Down
6 changes: 0 additions & 6 deletions src/pages/inbox/report/PureReportActionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@ type PureReportActionItemProps = {
/** Should we display the new marker on top of the comment? */
shouldDisplayNewMarker: boolean;

/** Position index of the report action in the overall report FlatList view */
index: number;

/** Flag to show, hide the thread divider line */
shouldHideThreadDividerLine?: boolean;

Expand Down Expand Up @@ -168,7 +165,6 @@ function PureReportActionItem({
transactionThreadReport,
linkedReportActionID,
displayAsGroup,
index,
parentReportAction,
shouldDisplayNewMarker,
shouldHideThreadDividerLine = false,
Expand Down Expand Up @@ -608,7 +604,6 @@ function PureReportActionItem({
isHarvestCreatedExpenseReport={isHarvestCreatedExpenseReport}
shouldShowBorder={shouldShowBorder}
isOnSearch={isOnSearch}
index={index}
setIsPaymentMethodPopoverActive={setIsPaymentMethodPopoverActive}
/>
{Permissions.canUseLinkPreviews() && !isHidden && (action.linkMetadata?.length ?? 0) > 0 && (
Expand Down Expand Up @@ -679,7 +674,6 @@ export default memo(PureReportActionItem, (prevProps, nextProps) => {
prevProps.report?.description === nextProps.report?.description &&
isCompletedTaskReport(prevProps.report) === isCompletedTaskReport(nextProps.report) &&
prevProps.report?.managerID === nextProps.report?.managerID &&
prevProps.index === nextProps.index &&
prevProps.shouldHideThreadDividerLine === nextProps.shouldHideThreadDividerLine &&
prevProps.report?.total === nextProps.report?.total &&
prevProps.report?.nonReimbursableTotal === nextProps.report?.nonReimbursableTotal &&
Expand Down
13 changes: 13 additions & 0 deletions src/pages/inbox/report/ReportActionIndexContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {createContext} from 'react';

/**
* Carries an action item's position index from the list renderer down to the rare consumers that
* actually need it (e.g. `ReportActionItemMessageEdit` for scroll-to-index during edit mode).
*
* Using context keeps `index` out of the prop signatures of every intermediate component, so a
* position shift caused by a new message arriving doesn't cascade re-renders through items that
* never read it. Only components that `useContext(ReportActionIndexContext)` re-render on change.
*/
const ReportActionIndexContext = createContext<number>(0);

export default ReportActionIndexContext;
3 changes: 2 additions & 1 deletion src/pages/inbox/report/ReportActionItem.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import stableReportSelector from '@selectors/stableReportSelector';
import React, {useCallback} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import useOnyx from '@hooks/useOnyx';
Expand Down Expand Up @@ -26,7 +27,7 @@ function ReportActionItem({action, report, draftMessage, personalDetails, linked
const reportID = report?.reportID;
const originalReportID = useOriginalReportID(reportID, action);
const isOriginalReportArchived = useReportIsArchived(originalReportID);
const [originalReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${originalReportID}`);
const [originalReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${originalReportID}`, {selector: stableReportSelector});
const [iouReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getIOUReportIDFromReportActionPreview(action)}`);

const transactionsOnIOUReport = useReportTransactions(iouReport?.reportID);
Expand Down
8 changes: 3 additions & 5 deletions src/pages/inbox/report/ReportActionItemMessageEdit.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import lodashDebounce from 'lodash/debounce';
import type {ForwardedRef} from 'react';
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import React, {useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
// eslint-disable-next-line no-restricted-imports
import {InteractionManager, View} from 'react-native';
import type {BlurEvent, MeasureInWindowOnSuccessCallback, TextInput, TextInputKeyPressEvent, TextInputScrollEvent} from 'react-native';
Expand Down Expand Up @@ -59,6 +59,7 @@ import getCursorPosition from './ReportActionCompose/getCursorPosition';
import getScrollPosition from './ReportActionCompose/getScrollPosition';
import type {SuggestionsRef} from './ReportActionCompose/ReportActionCompose';
import Suggestions from './ReportActionCompose/Suggestions';
import ReportActionIndexContext from './ReportActionIndexContext';
import shouldUseEmojiPickerSelection from './shouldUseEmojiPickerSelection';

type ReportActionItemMessageEditProps = {
Expand All @@ -77,9 +78,6 @@ type ReportActionItemMessageEditProps = {
/** PolicyID of the policy the report belongs to */
policyID?: string;

/** Position index of the report action in the overall report FlatList view */
index: number;

/** Whether or not the emoji picker is disabled */
shouldDisableEmojiPicker?: boolean;

Expand All @@ -106,11 +104,11 @@ function ReportActionItemMessageEdit({
reportID,
originalReportID,
policyID,
index,
isGroupPolicyReport,
shouldDisableEmojiPicker = false,
ref,
}: ReportActionItemMessageEditProps) {
const index = useContext(ReportActionIndexContext);
const [preferredSkinTone = CONST.EMOJI_DEFAULT_SKIN_TONE] = useOnyx(ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE);
const {email} = useCurrentUserPersonalDetails();
const theme = useTheme();
Expand Down
5 changes: 0 additions & 5 deletions src/pages/inbox/report/ReportActionItemParentAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ type ReportActionItemParentActionProps = {
/** Flag to show, hide the thread divider line */
shouldHideThreadDividerLine?: boolean;

/** Position index of the report parent action in the overall report FlatList view */
index: number;

/** The id of the report */

reportID: string;
Expand Down Expand Up @@ -72,7 +69,6 @@ function ReportActionItemParentAction({
action,
transactionThreadReport,
parentReportAction,
index = 0,
shouldHideThreadDividerLine = false,
shouldDisplayReplyDivider,
isFirstVisibleReportAction = false,
Expand Down Expand Up @@ -214,7 +210,6 @@ function ReportActionItemParentAction({
action={ancestorReportAction}
displayAsGroup={false}
shouldDisplayNewMarker={ancestor.shouldDisplayNewMarker}
index={index}
isFirstVisibleReportAction={isFirstVisibleReportAction}
shouldUseThreadDividerLine={shouldUseThreadDividerLine}
isThreadReportParentAction
Expand Down
Loading
Loading