Skip to content

Commit 5273794

Browse files
adhorodyskiclaude
andcommitted
ReportActionCompose 4/6: extract input hooks
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent df08b0d commit 5273794

5 files changed

Lines changed: 203 additions & 187 deletions

File tree

src/pages/inbox/report/ReportActionCompose/ComposerInput.tsx

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
1-
import {useRoute} from '@react-navigation/native';
21
import React from 'react';
32
import type {MeasureInWindowOnSuccessCallback} from 'react-native';
43
import type {LocalizedTranslate} from '@components/LocaleContextProvider';
54
import useIsScrollLikelyLayoutTriggered from '@hooks/useIsScrollLikelyLayoutTriggered';
65
import useLocalize from '@hooks/useLocalize';
7-
import useNetwork from '@hooks/useNetwork';
86
import useOnyx from '@hooks/useOnyx';
9-
import usePaginatedReportActions from '@hooks/usePaginatedReportActions';
10-
import useParentReportAction from '@hooks/useParentReportAction';
117
import useReportIsArchived from '@hooks/useReportIsArchived';
12-
import useReportTransactionsCollection from '@hooks/useReportTransactionsCollection';
138
import FS from '@libs/Fullstory';
14-
import {getAllNonDeletedTransactions} from '@libs/MoneyRequestReportUtils';
15-
import {getCombinedReportActions, getFilteredReportActionsForReportView, getOneTransactionThreadReportID, isMoneyRequestAction, isSentMoneyReportAction} from '@libs/ReportActionsUtils';
169
import {
17-
canEditReportAction,
1810
canUserPerformWriteAction as canUserPerformWriteActionReportUtils,
1911
chatIncludesChronos,
2012
chatIncludesConcierge,
@@ -25,14 +17,13 @@ import {isEmojiPickerVisible} from '@userActions/EmojiPickerAction';
2517
import {isBlockedFromConcierge as isBlockedFromConciergeUserAction} from '@userActions/User';
2618
import CONST from '@src/CONST';
2719
import ONYXKEYS from '@src/ONYXKEYS';
28-
import SCREENS from '@src/SCREENS';
2920
import type {FileObject} from '@src/types/utils/Attachment';
3021
import {useComposerActions, useComposerMeta, useComposerSendActions, useComposerSendState, useComposerState} from './ComposerContext';
3122
import ComposerWithSuggestions from './ComposerWithSuggestions';
23+
import useComposerSubmit from './useComposerSubmit';
3224

3325
type ComposerInputProps = {
3426
reportID: string;
35-
submitForm: (comment: string) => void;
3627
onPasteFile: (files: FileObject | FileObject[]) => void;
3728
};
3829

@@ -43,15 +34,16 @@ function getRandomPlaceholder(translate: LocalizedTranslate): string {
4334
return translate(AI_PLACEHOLDER_KEYS[randomIndex]);
4435
}
4536

46-
function ComposerInput({reportID, submitForm, onPasteFile}: ComposerInputProps) {
37+
function ComposerInput({reportID, onPasteFile}: ComposerInputProps) {
4738
const {translate, preferredLocale} = useLocalize();
48-
const {isOffline} = useNetwork();
4939
const {isMenuVisible} = useComposerState();
5040
const {isBlockedFromConcierge} = useComposerSendState();
5141
const {setIsFullComposerAvailable, onBlur, onFocus, setComposerRef} = useComposerActions();
5242
const {handleSendMessage, onValueChange} = useComposerSendActions();
5343
const {containerRef, suggestionsRef, isNextModalWillOpenRef} = useComposerMeta();
5444

45+
const submitForm = useComposerSubmit(reportID);
46+
5547
const [isComposerFullSize = false] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_IS_COMPOSER_FULL_SIZE}${reportID}`);
5648
const [shouldShowComposeInput = true] = useOnyx(ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT);
5749
const [blockedFromConcierge] = useOnyx(ONYXKEYS.NVP_BLOCKED_FROM_CONCIERGE);
@@ -66,26 +58,6 @@ function ComposerInput({reportID, submitForm, onPasteFile}: ComposerInputProps)
6658
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
6759
const isReportArchived = useReportIsArchived(report?.reportID);
6860

69-
// --- lastReportAction derivation (moves to useLastEditableAction hook in PR 4) ---
70-
const {reportActions: unfilteredReportActions} = usePaginatedReportActions(report?.reportID);
71-
const filteredReportActions = getFilteredReportActionsForReportView(unfilteredReportActions);
72-
const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.chatReportID}`);
73-
const allReportTransactions = useReportTransactionsCollection(reportID);
74-
const reportTransactions = getAllNonDeletedTransactions(allReportTransactions, filteredReportActions, isOffline, true);
75-
const visibleTransactions = isOffline ? reportTransactions : reportTransactions?.filter((t) => t.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);
76-
const reportTransactionIDs = visibleTransactions?.map((t) => t.transactionID);
77-
const isSentMoneyReport = filteredReportActions.some((action) => isSentMoneyReportAction(action));
78-
const transactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, filteredReportActions, isOffline, reportTransactionIDs);
79-
const effectiveTransactionThreadReportID = isSentMoneyReport ? undefined : transactionThreadReportID;
80-
const parentReportAction = useParentReportAction(report);
81-
const [transactionThreadReportActionsOnyx] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${effectiveTransactionThreadReportID}`);
82-
const transactionThreadReportActionsArray = transactionThreadReportActionsOnyx ? Object.values(transactionThreadReportActionsOnyx) : [];
83-
const combinedReportActions = getCombinedReportActions(filteredReportActions, effectiveTransactionThreadReportID ?? null, transactionThreadReportActionsArray);
84-
const route = useRoute();
85-
const isOnSearchMoneyRequestReport = route.name === SCREENS.RIGHT_MODAL.SEARCH_MONEY_REQUEST_REPORT || route.name === SCREENS.RIGHT_MODAL.EXPENSE_REPORT;
86-
const actionsForLastEditable = isOnSearchMoneyRequestReport ? filteredReportActions : combinedReportActions;
87-
const lastReportAction = [...actionsForLastEditable, parentReportAction].find((action) => !isMoneyRequestAction(action) && canEditReportAction(action, undefined));
88-
8961
const includesConcierge = chatIncludesConcierge({participants: report?.participants});
9062
const isGroupPolicyReport = !!report?.policyID && report.policyID !== CONST.POLICY.ID_FAKE;
9163
const isExpenseRelatedReport = isReportTransactionThread(report) || isMoneyRequestReport(report);
@@ -111,7 +83,6 @@ function ComposerInput({reportID, submitForm, onPasteFile}: ComposerInputProps)
11183
policyID={report?.policyID}
11284
includeChronos={chatIncludesChronos(report)}
11385
isGroupPolicyReport={isGroupPolicyReport}
114-
lastReportAction={lastReportAction}
11586
isMenuVisible={isMenuVisible}
11687
inputPlaceholder={inputPlaceholder}
11788
isComposerFullSize={isComposerFullSize}

src/pages/inbox/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import getScrollPosition from '@pages/inbox/report/ReportActionCompose/getScroll
5353
import type {SuggestionsRef} from '@pages/inbox/report/ReportActionCompose/ReportActionCompose';
5454
import SilentCommentUpdater from '@pages/inbox/report/ReportActionCompose/SilentCommentUpdater';
5555
import Suggestions from '@pages/inbox/report/ReportActionCompose/Suggestions';
56+
import useLastEditableAction from '@pages/inbox/report/ReportActionCompose/useLastEditableAction';
5657
import {isEmojiPickerVisible} from '@userActions/EmojiPickerAction';
5758
import type {OnEmojiSelected} from '@userActions/EmojiPickerAction';
5859
import {inputFocusChange} from '@userActions/InputFocus';
@@ -61,7 +62,6 @@ import {broadcastUserIsTyping, saveReportActionDraft, saveReportDraftComment} fr
6162
import CONST from '@src/CONST';
6263
import ONYXKEYS from '@src/ONYXKEYS';
6364
import SCREENS from '@src/SCREENS';
64-
import type * as OnyxTypes from '@src/types/onyx';
6565
import type {FileObject} from '@src/types/utils/Attachment';
6666
import type ChildrenProps from '@src/types/utils/ChildrenProps';
6767
// eslint-disable-next-line no-restricted-imports
@@ -112,9 +112,6 @@ type ComposerWithSuggestionsProps = Partial<ChildrenProps> &
112112
/** Whether the input is disabled, defaults to false */
113113
disabled?: boolean;
114114

115-
/** Function to set whether the comment is empty */
116-
setIsCommentEmpty?: (isCommentEmpty: boolean) => void;
117-
118115
/** Function to handle sending a message */
119116
onEnterKeyPress: () => void;
120117

@@ -136,9 +133,6 @@ type ComposerWithSuggestionsProps = Partial<ChildrenProps> &
136133
/** The ref to the next modal will open */
137134
isNextModalWillOpenRef: RefObject<boolean | null>;
138135

139-
/** The last report action */
140-
lastReportAction?: OnyxEntry<OnyxTypes.ReportAction>;
141-
142136
/** Whether to include chronos */
143137
includeChronos?: boolean;
144138

@@ -148,9 +142,6 @@ type ComposerWithSuggestionsProps = Partial<ChildrenProps> &
148142
/** policy ID of the report */
149143
policyID?: string;
150144

151-
/** Whether the main composer was hidden */
152-
didHideComposerInput?: boolean;
153-
154145
/** Reference to the outer element */
155146
ref?: Ref<ComposerRef | null>;
156147
};
@@ -214,7 +205,6 @@ function ComposerWithSuggestions({
214205
// Props: Report
215206
reportID,
216207
includeChronos,
217-
lastReportAction,
218208
isGroupPolicyReport,
219209
policyID,
220210

@@ -230,7 +220,6 @@ function ComposerWithSuggestions({
230220
inputPlaceholder,
231221
onPasteFile,
232222
disabled,
233-
setIsCommentEmpty,
234223
onEnterKeyPress,
235224
shouldShowComposeInput,
236225
measureParentContainer = () => {},
@@ -246,11 +235,11 @@ function ComposerWithSuggestions({
246235

247236
// For testing
248237
children,
249-
didHideComposerInput,
250238

251239
// Fullstory
252240
forwardedFSClass,
253241
}: ComposerWithSuggestionsProps) {
242+
const lastReportAction = useLastEditableAction(reportID);
254243
const route = useRoute();
255244
const {isKeyboardShown} = useKeyboardState();
256245
const theme = useTheme();
@@ -293,7 +282,7 @@ function ComposerWithSuggestions({
293282

294283
const {shouldUseNarrowLayout} = useResponsiveLayout();
295284
const maxComposerLines = shouldUseNarrowLayout ? CONST.COMPOSER.MAX_LINES_SMALL_SCREEN : CONST.COMPOSER.MAX_LINES;
296-
const shouldAutoFocus = (shouldFocusInputOnScreenFocus || !!draftComment) && shouldShowComposeInput && areAllModalsHidden() && isFocused && !didHideComposerInput;
285+
const shouldAutoFocus = (shouldFocusInputOnScreenFocus || !!draftComment) && shouldShowComposeInput && areAllModalsHidden() && isFocused;
297286
const delayedAutoFocusRouteKeyRef = useRef<string | null>(null);
298287

299288
const valueRef = useRef(value);
@@ -455,13 +444,6 @@ function ComposerWithSuggestions({
455444
}
456445
}
457446
const newCommentConverted = convertToLTRForComposer(newComment);
458-
const isNewCommentEmpty = !!newCommentConverted.match(/^(\s)*$/);
459-
const isPrevCommentEmpty = !!commentRef.current.match(/^(\s)*$/);
460-
461-
/** Only update isCommentEmpty state if it's different from previous one */
462-
if (isNewCommentEmpty !== isPrevCommentEmpty) {
463-
setIsCommentEmpty?.(isNewCommentEmpty);
464-
}
465447
emojisPresentBefore.current = emojis;
466448

467449
setValue(newCommentConverted);
@@ -497,7 +479,6 @@ function ComposerWithSuggestions({
497479
preferredLocale,
498480
preferredSkinTone,
499481
reportID,
500-
setIsCommentEmpty,
501482
suggestionsRef,
502483
raiseIsScrollLikelyLayoutTriggered,
503484
debouncedSaveReportComment,

0 commit comments

Comments
 (0)