diff --git a/Mobile-Expensify b/Mobile-Expensify
index 2d8ef298da1b..3821cbce92ba 160000
--- a/Mobile-Expensify
+++ b/Mobile-Expensify
@@ -1 +1 @@
-Subproject commit 2d8ef298da1b9ca92aa63ab59746566a7d46f742
+Subproject commit 3821cbce92ba84a2d3fbb51dc36a8a729e6752cc
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 46d2f91ca930..5cc67a022724 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -114,8 +114,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
- versionCode 1009019810
- versionName "9.1.98-10"
+ versionCode 1009019811
+ versionName "9.1.98-11"
// Supported language variants must be declared here to avoid from being removed during the compilation.
// This also helps us to not include unnecessary language variants in the APK.
resConfigs "en", "es"
diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist
index c8d728e6cd53..20ef1d304f20 100644
--- a/ios/NewExpensify/Info.plist
+++ b/ios/NewExpensify/Info.plist
@@ -44,7 +44,7 @@
CFBundleVersion
- 9.1.98.10
+ 9.1.98.11
FullStory
OrgId
diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist
index 84699fedc238..c8ff1f6fde81 100644
--- a/ios/NotificationServiceExtension/Info.plist
+++ b/ios/NotificationServiceExtension/Info.plist
@@ -13,7 +13,7 @@
CFBundleShortVersionString
9.1.98
CFBundleVersion
- 9.1.98.10
+ 9.1.98.11
NSExtension
NSExtensionPointIdentifier
diff --git a/ios/ShareViewController/Info.plist b/ios/ShareViewController/Info.plist
index 24296310ac83..f5b380704d61 100644
--- a/ios/ShareViewController/Info.plist
+++ b/ios/ShareViewController/Info.plist
@@ -13,7 +13,7 @@
CFBundleShortVersionString
9.1.98
CFBundleVersion
- 9.1.98.10
+ 9.1.98.11
NSExtension
NSExtensionAttributes
diff --git a/package-lock.json b/package-lock.json
index 018634cd5461..d3b9414db83e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "new.expensify",
- "version": "9.1.98-10",
+ "version": "9.1.98-11",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "new.expensify",
- "version": "9.1.98-10",
+ "version": "9.1.98-11",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
diff --git a/package.json b/package.json
index fef7940626d6..f4f1d4724816 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
- "version": "9.1.98-10",
+ "version": "9.1.98-11",
"author": "Expensify, Inc.",
"homepage": "https://new.expensify.com",
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts
index 3637ad7772e5..3720af54b78f 100755
--- a/src/ONYXKEYS.ts
+++ b/src/ONYXKEYS.ts
@@ -569,9 +569,6 @@ const ONYXKEYS = {
NVP_LAST_ECASH_ANDROID_LOGIN: 'nvp_lastECashAndroidLogin',
NVP_LAST_ANDROID_LOGIN: 'nvp_lastAndroidLogin',
- /** Draft report comments */
- NVP_DRAFT_REPORT_COMMENTS: 'nvp_draftReportComments',
-
/** Collection Keys */
COLLECTION: {
DOWNLOAD: 'download_',
@@ -604,8 +601,7 @@ const ONYXKEYS = {
REPORT_ACTIONS_DRAFTS: 'reportActionsDrafts_',
REPORT_ACTIONS_PAGES: 'reportActionsPages_',
REPORT_ACTIONS_REACTIONS: 'reportActionsReactions_',
- /** @deprecated */
- REPORT_DRAFT_COMMENT: 'reportDraftComment_', // eslint-disable-line deprecation/deprecation
+ REPORT_DRAFT_COMMENT: 'reportDraftComment_',
REPORT_IS_COMPOSER_FULL_SIZE: 'reportIsComposerFullSize_',
REPORT_USER_IS_TYPING: 'reportUserIsTyping_',
REPORT_USER_IS_LEAVING_ROOM: 'reportUserIsLeavingRoom_',
@@ -1008,7 +1004,6 @@ type OnyxCollectionValuesMapping = {
[ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS]: OnyxTypes.ReportActionsDrafts;
[ONYXKEYS.COLLECTION.REPORT_ACTIONS_PAGES]: OnyxTypes.Pages;
[ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS]: OnyxTypes.ReportActionReactions;
- // eslint-disable-next-line deprecation/deprecation
[ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT]: string;
[ONYXKEYS.COLLECTION.REPORT_IS_COMPOSER_FULL_SIZE]: boolean;
[ONYXKEYS.COLLECTION.REPORT_USER_IS_TYPING]: OnyxTypes.ReportUserIsTyping;
@@ -1234,7 +1229,6 @@ type OnyxValuesMapping = {
[ONYXKEYS.ONBOARDING_USER_REPORTED_INTEGRATION]: OnboardingAccounting;
[ONYXKEYS.HYBRID_APP]: OnyxTypes.HybridApp;
[ONYXKEYS.NVP_CSV_EXPORT_LAYOUTS]: Record;
- [ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS]: OnyxTypes.DraftReportComments;
};
type OnyxDerivedValuesMapping = {
diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx
index 9ed2e8ea6405..8c6a12efb22a 100644
--- a/src/components/LHNOptionsList/LHNOptionsList.tsx
+++ b/src/components/LHNOptionsList/LHNOptionsList.tsx
@@ -19,6 +19,7 @@ import useRootNavigationState from '@hooks/useRootNavigationState';
import useScrollEventEmitter from '@hooks/useScrollEventEmitter';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
+import {isValidDraftComment} from '@libs/DraftCommentUtils';
import getPlatform from '@libs/getPlatform';
import Log from '@libs/Log';
import {getIOUReportIDOfLastAction, getLastMessageTextForReport} from '@libs/OptionsListUtils';
@@ -52,7 +53,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio
const [policy] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: false});
const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {canBeMissing: true});
const [transactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION, {canBeMissing: false});
- const [draftComments] = useOnyx(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, {canBeMissing: true});
+ const [draftComments] = useOnyx(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, {canBeMissing: false});
const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: false});
const [dismissedProductTraining, dismissedProductTrainingMetadata] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING, {canBeMissing: true});
const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: true});
@@ -188,7 +189,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio
? (getOriginalMessage(itemParentReportAction)?.IOUTransactionID ?? CONST.DEFAULT_NUMBER_ID)
: CONST.DEFAULT_NUMBER_ID;
const itemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];
- const hasDraftComment = !!draftComments?.[reportID];
+ const hasDraftComment = isValidDraftComment(draftComments?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`]);
const isReportArchived = !!itemReportNameValuePairs?.private_isArchived;
const canUserPerformWrite = canUserPerformWriteAction(item, isReportArchived);
@@ -287,6 +288,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio
policy,
personalDetails,
data.length,
+ draftComments,
optionMode,
preferredLocale,
transactions,
@@ -303,6 +305,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio
policy,
personalDetails,
data.length,
+ draftComments,
optionMode,
preferredLocale,
transactions,
diff --git a/src/hooks/useDiffPrevious.ts b/src/hooks/useDiffPrevious.ts
deleted file mode 100644
index 2687a17b7670..000000000000
--- a/src/hooks/useDiffPrevious.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import union from 'lodash/union';
-import {useMemo} from 'react';
-import usePrevious from './usePrevious';
-
-/** This hook provides a list of which keys changed in an object vs the previous render
- * akin to `sourceValue` for collections. Generally, using this hook at all is an anti-pattern.
- * Avoid it at all costs */
-export default function useDiffPrevious>(value: T): string[] {
- const previous = usePrevious(value);
- const diff = useMemo(() => {
- const allKeys = union(Object.keys(value), Object.keys(previous));
- return allKeys.filter((key) => value[key] !== previous[key]);
- }, [value, previous]);
-
- return diff;
-}
diff --git a/src/hooks/usePriorityChange.ts b/src/hooks/usePriorityChange.ts
index a3b01857ceb0..62c83bed29ed 100644
--- a/src/hooks/usePriorityChange.ts
+++ b/src/hooks/usePriorityChange.ts
@@ -7,7 +7,7 @@ import usePrevious from './usePrevious';
function usePriorityMode() {
const [priorityMode] = useOnyx(ONYXKEYS.NVP_PRIORITY_MODE, {canBeMissing: true});
- const [allReportsWithDraftComments] = useOnyx(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, {canBeMissing: true});
+ const [allReportsWithDraftComments] = useOnyx(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, {canBeMissing: true});
const prevPriorityMode = usePrevious(priorityMode);
useEffect(() => {
diff --git a/src/hooks/useSidebarOrderedReports.tsx b/src/hooks/useSidebarOrderedReports.tsx
index c99dd892e1b0..12122453898b 100644
--- a/src/hooks/useSidebarOrderedReports.tsx
+++ b/src/hooks/useSidebarOrderedReports.tsx
@@ -7,12 +7,10 @@ import SidebarUtils from '@libs/SidebarUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type * as OnyxTypes from '@src/types/onyx';
-import {getEmptyObject} from '@src/types/utils/EmptyObject';
import mapOnyxCollectionItems from '@src/utils/mapOnyxCollectionItems';
import useCurrentReportID from './useCurrentReportID';
import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails';
import useDeepCompareRef from './useDeepCompareRef';
-import useDiffPrevious from './useDiffPrevious';
import useLocalize from './useLocalize';
import useOnyx from './useOnyx';
import usePrevious from './usePrevious';
@@ -68,8 +66,7 @@ function SidebarOrderedReportsContextProvider({
const [transactions, {sourceValue: transactionsUpdates}] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION, {canBeMissing: true});
const [transactionViolations, {sourceValue: transactionViolationsUpdates}] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true});
const [reportNameValuePairs, {sourceValue: reportNameValuePairsUpdates}] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS, {canBeMissing: true});
- const [drafts = getEmptyObject()] = useOnyx(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, {canBeMissing: true});
- const reportsDraftsUpdates = useDiffPrevious(drafts);
+ const [, {sourceValue: reportsDraftsUpdates}] = useOnyx(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, {canBeMissing: true});
const [betas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: true});
const [reportAttributes] = useOnyx(ONYXKEYS.DERIVED.REPORT_ATTRIBUTES, {selector: (value) => value?.reports, canBeMissing: true});
const [currentReportsToDisplay, setCurrentReportsToDisplay] = useState({});
@@ -102,8 +99,8 @@ function SidebarOrderedReportsContextProvider({
reportsToUpdate = Object.keys(transactionViolationsUpdates ?? {})
.map((key) => key.replace(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, ONYXKEYS.COLLECTION.TRANSACTION))
.map((key) => `${ONYXKEYS.COLLECTION.REPORT}${transactions?.[key]?.reportID}`);
- } else if (reportsDraftsUpdates.length > 0) {
- reportsToUpdate = reportsDraftsUpdates.map((key) => `${ONYXKEYS.COLLECTION.REPORT}${key}`);
+ } else if (reportsDraftsUpdates) {
+ reportsToUpdate = Object.keys(reportsDraftsUpdates).map((key) => key.replace(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, ONYXKEYS.COLLECTION.REPORT));
} else if (policiesUpdates) {
const updatedPolicies = Object.keys(policiesUpdates).map((key) => key.replace(ONYXKEYS.COLLECTION.POLICY, ''));
reportsToUpdate = Object.entries(chatReports ?? {})
@@ -154,10 +151,10 @@ function SidebarOrderedReportsContextProvider({
derivedCurrentReportID,
priorityMode === CONST.PRIORITY_MODE.GSD,
betas,
+ policies,
transactionViolations,
reportNameValuePairs,
reportAttributes,
- drafts,
);
} else {
reportsToDisplay = SidebarUtils.getReportsToDisplayInLHN(
@@ -169,13 +166,12 @@ function SidebarOrderedReportsContextProvider({
transactionViolations,
reportNameValuePairs,
reportAttributes,
- drafts,
);
}
return reportsToDisplay;
// Rule disabled intentionally — triggering a re-render on currentReportsToDisplay would cause an infinite loop
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
- }, [getUpdatedReports, chatReports, derivedCurrentReportID, priorityMode, betas, policies, transactionViolations, reportNameValuePairs, reportAttributes, reportsDraftsUpdates]);
+ }, [getUpdatedReports, chatReports, derivedCurrentReportID, priorityMode, betas, policies, transactionViolations, reportNameValuePairs, reportAttributes]);
const deepComparedReportsToDisplayInLHN = useDeepCompareRef(reportsToDisplayInLHN);
@@ -184,7 +180,7 @@ function SidebarOrderedReportsContextProvider({
}, [reportsToDisplayInLHN]);
const getOrderedReportIDs = useCallback(
- () => SidebarUtils.sortReportsToDisplayInLHN(deepComparedReportsToDisplayInLHN ?? {}, priorityMode, localeCompare, reportNameValuePairs, reportAttributes, drafts),
+ () => SidebarUtils.sortReportsToDisplayInLHN(deepComparedReportsToDisplayInLHN ?? {}, priorityMode, localeCompare, reportNameValuePairs, reportAttributes),
// Rule disabled intentionally - reports should be sorted only when the reportsToDisplayInLHN changes
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
[reportsToDisplayInLHN, localeCompare],
diff --git a/src/libs/API/parameters/SaveReportDraftCommentParams.ts b/src/libs/API/parameters/SaveReportDraftCommentParams.ts
deleted file mode 100644
index 583742b7488f..000000000000
--- a/src/libs/API/parameters/SaveReportDraftCommentParams.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-type SaveReportDraftCommentParams = {
- reportID: string;
- reportComment: string;
-};
-
-export default SaveReportDraftCommentParams;
diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts
index 2f8400a96ac0..d951fe4f2f7f 100644
--- a/src/libs/API/parameters/index.ts
+++ b/src/libs/API/parameters/index.ts
@@ -419,4 +419,3 @@ export type {default as ReopenReportParams} from './ReopenReportParams';
export type {default as OpenUnreportedExpensesPageParams} from './OpenUnreportedExpensesPageParams';
export type {default as VerifyTestDriveRecipientParams} from './VerifyTestDriveRecipientParams';
export type {default as ExportSearchWithTemplateParams} from './ExportSearchWithTemplateParams';
-export type {default as SaveReportDraftCommentParams} from './SaveReportDraftCommentParams';
diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts
index 3ac4cd240de2..1b48c5bbfc54 100644
--- a/src/libs/API/types.ts
+++ b/src/libs/API/types.ts
@@ -11,7 +11,6 @@ import type UpdateBeneficialOwnersForBankAccountParams from './parameters/Update
type ApiRequestType = ValueOf;
const WRITE_COMMANDS = {
- SAVE_REPORT_DRAFT_COMMENT: 'SaveReportDraftComment',
CLEAN_POLICY_TAGS: 'ClearPolicyTags',
IMPORT_MULTI_LEVEL_TAGS: 'ImportMultiLevelTags',
SET_WORKSPACE_AUTO_REPORTING_FREQUENCY: 'SetWorkspaceAutoReportingFrequency',
@@ -862,7 +861,6 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.FINISH_CORPAY_BANK_ACCOUNT_ONBOARDING]: Parameters.FinishCorpayBankAccountOnboardingParams;
[WRITE_COMMANDS.DELETE_VACATION_DELEGATE]: null;
[WRITE_COMMANDS.REOPEN_REPORT]: Parameters.ReopenReportParams;
- [WRITE_COMMANDS.SAVE_REPORT_DRAFT_COMMENT]: Parameters.SaveReportDraftCommentParams;
[WRITE_COMMANDS.DELETE_MONEY_REQUEST_ON_SEARCH]: Parameters.DeleteMoneyRequestOnSearchParams;
[WRITE_COMMANDS.HOLD_MONEY_REQUEST_ON_SEARCH]: Parameters.HoldMoneyRequestOnSearchParams;
diff --git a/src/libs/DraftCommentUtils.ts b/src/libs/DraftCommentUtils.ts
index b95294820b1e..b3cb32498725 100644
--- a/src/libs/DraftCommentUtils.ts
+++ b/src/libs/DraftCommentUtils.ts
@@ -1,14 +1,14 @@
-import type {OnyxEntry} from 'react-native-onyx';
+import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import ONYXKEYS from '@src/ONYXKEYS';
-import type {DraftReportComments} from '@src/types/onyx';
-let draftComments: OnyxEntry = {};
+let draftCommentCollection: OnyxCollection = {};
Onyx.connect({
- key: ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS,
+ key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT,
callback: (nextVal) => {
- draftComments = nextVal;
+ draftCommentCollection = nextVal;
},
+ waitForCollectionCallback: true,
});
/**
@@ -17,15 +17,22 @@ Onyx.connect({
* A valid use-case of this function is outside React components, like in utility functions.
*/
function getDraftComment(reportID: string): OnyxEntry | null | undefined {
- return draftComments?.[reportID];
+ return draftCommentCollection?.[ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT + reportID];
+}
+
+/**
+ * Returns true if the report has a valid draft comment.
+ * A valid draft comment is a non-empty string.
+ */
+function isValidDraftComment(comment?: string | null): boolean {
+ return !!comment;
}
/**
* Returns true if the report has a valid draft comment.
- * NOTE: please prefer useOnyx when possible
*/
function hasValidDraftComment(reportID: string): boolean {
- return !!getDraftComment(reportID);
+ return isValidDraftComment(getDraftComment(reportID));
}
/**
@@ -37,4 +44,4 @@ function prepareDraftComment(comment: string | null) {
return comment || null;
}
-export {getDraftComment, hasValidDraftComment, prepareDraftComment};
+export {getDraftComment, isValidDraftComment, hasValidDraftComment, prepareDraftComment};
diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts
index 5a4418f7746e..4cf427263033 100644
--- a/src/libs/SidebarUtils.ts
+++ b/src/libs/SidebarUtils.ts
@@ -6,17 +6,7 @@ import type {LocaleContextProps} from '@components/LocaleContextProvider';
import type {PartialPolicyForSidebar, ReportsToDisplayInLHN} from '@hooks/useSidebarOrderedReports';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
-import type {
- Card,
- DraftReportComments,
- PersonalDetails,
- PersonalDetailsList,
- ReportActions,
- ReportAttributesDerivedValue,
- ReportNameValuePairs,
- Transaction,
- TransactionViolation,
-} from '@src/types/onyx';
+import type {Card, PersonalDetails, PersonalDetailsList, ReportActions, ReportAttributesDerivedValue, ReportNameValuePairs, Transaction, TransactionViolation} from '@src/types/onyx';
import type Beta from '@src/types/onyx/Beta';
import type {ReportAttributes} from '@src/types/onyx/DerivedValues';
import type {Errors} from '@src/types/onyx/OnyxCommon';
@@ -25,6 +15,7 @@ import type PriorityMode from '@src/types/onyx/PriorityMode';
import type Report from '@src/types/onyx/Report';
import type ReportAction from '@src/types/onyx/ReportAction';
import {extractCollectionItemID} from './CollectionUtils';
+import {hasValidDraftComment} from './DraftCommentUtils';
import {translateLocal} from './Localize';
import {getLastActorDisplayName, getLastMessageTextForReport, getPersonalDetailsForAccountIDs, shouldShowLastActorDisplayName} from './OptionsListUtils';
import Parser from './Parser';
@@ -217,7 +208,6 @@ function shouldDisplayReportInLHN(
transactionViolations: OnyxCollection,
isReportArchived?: boolean,
reportAttributes?: ReportAttributesDerivedValue['reports'],
- draftReportComments?: DraftReportComments,
) {
if (!report) {
return {shouldDisplay: false};
@@ -248,12 +238,7 @@ function shouldDisplayReportInLHN(
// Check if report should override hidden status
const isSystemChat = isSystemChatUtil(report);
const shouldOverrideHidden =
- !!draftReportComments?.[report.reportID] ||
- hasErrorsOtherThanFailedReceipt ||
- isFocused ||
- isSystemChat ||
- !!report.isPinned ||
- reportAttributes?.[report?.reportID]?.requiresAttention;
+ hasValidDraftComment(report.reportID) || hasErrorsOtherThanFailedReceipt || isFocused || isSystemChat || !!report.isPinned || reportAttributes?.[report?.reportID]?.requiresAttention;
if (isHidden && !shouldOverrideHidden) {
return {shouldDisplay: false};
@@ -284,7 +269,6 @@ function getReportsToDisplayInLHN(
transactionViolations: OnyxCollection,
reportNameValuePairs?: OnyxCollection,
reportAttributes?: ReportAttributesDerivedValue['reports'],
- draftReportComments?: DraftReportComments,
) {
const isInFocusMode = priorityMode === CONST.PRIORITY_MODE.GSD;
const allReportsDictValues = reports ?? {};
@@ -304,7 +288,6 @@ function getReportsToDisplayInLHN(
transactionViolations,
isArchivedReport(reportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report.reportID}`]),
reportAttributes,
- draftReportComments,
);
if (shouldDisplay) {
@@ -322,10 +305,10 @@ function updateReportsToDisplayInLHN(
currentReportId: string | undefined,
isInFocusMode: boolean,
betas: OnyxEntry,
+ policies: OnyxCollection,
transactionViolations: OnyxCollection,
reportNameValuePairs?: OnyxCollection,
reportAttributes?: ReportAttributesDerivedValue['reports'],
- draftReportComments?: DraftReportComments,
) {
const displayedReportsCopy = {...displayedReports};
updatedReportsKeys.forEach((reportID) => {
@@ -343,7 +326,6 @@ function updateReportsToDisplayInLHN(
transactionViolations,
isArchivedReport(reportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report.reportID}`]),
reportAttributes,
- draftReportComments,
);
if (shouldDisplay) {
@@ -362,7 +344,6 @@ function categorizeReportsForLHN(
reportsToDisplay: ReportsToDisplayInLHN,
reportNameValuePairs?: OnyxCollection,
reportAttributes?: ReportAttributesDerivedValue['reports'],
- draftReportComments?: DraftReportComments,
) {
const pinnedAndGBRReports: MiniReport[] = [];
const errorReports: MiniReport[] = [];
@@ -375,7 +356,7 @@ function categorizeReportsForLHN(
const reportID = report.reportID;
const isPinned = !!report.isPinned;
const hasErrors = !!report.hasErrorsOtherThanFailedReceipt;
- const hasDraft = reportID ? !!draftReportComments?.[reportID] : false;
+ const hasDraft = reportID ? hasValidDraftComment(reportID) : false;
const reportNameValuePairsKey = `${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${reportID}`;
const rNVPs = reportNameValuePairs?.[reportNameValuePairsKey];
@@ -489,7 +470,6 @@ function sortReportsToDisplayInLHN(
localeCompare: LocaleContextProps['localeCompare'],
reportNameValuePairs?: OnyxCollection,
reportAttributes?: ReportAttributesDerivedValue['reports'],
- draftReportComments?: DraftReportComments,
): string[] {
Performance.markStart(CONST.TIMING.GET_ORDERED_REPORT_IDS);
@@ -507,7 +487,7 @@ function sortReportsToDisplayInLHN(
// - Sorted by reportDisplayName in GSD (focus) view mode
// Step 1: Categorize reports
- const categories = categorizeReportsForLHN(reportsToDisplay, reportNameValuePairs, reportAttributes, draftReportComments);
+ const categories = categorizeReportsForLHN(reportsToDisplay, reportNameValuePairs, reportAttributes);
// Step 2: Sort each category
const sortedCategories = sortCategorizedReports(categories, isInDefaultMode, localeCompare);
diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts
index 838c4b1a7e0d..2021ac46dff2 100644
--- a/src/libs/actions/App.ts
+++ b/src/libs/actions/App.ts
@@ -287,7 +287,7 @@ function getOnyxDataForOpenOrReconnect(
// This ensures that any report with a draft comment is preserved in Onyx even if it doesn’t contain chat history
const reportsWithDraftComments = Object.entries(allReportsWithDraftComments ?? {})
.filter(([, value]) => value !== null)
- .map(([key]) => key.replace(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, ''))
+ .map(([key]) => key.replace(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, ''))
.map((reportID) => allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]);
reportsWithDraftComments?.forEach((report) => {
diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts
index 58fb04cd9d41..0d44e8c319bb 100644
--- a/src/libs/actions/IOU.ts
+++ b/src/libs/actions/IOU.ts
@@ -771,19 +771,17 @@ Onyx.connect({
const policyID = key.replace(ONYXKEYS.COLLECTION.POLICY, '');
const policyReports = getAllPolicyReports(policyID);
const cleanUpMergeQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT}${string}`, NullishDeep> = {};
- const cleanUpSetQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`, null> = {};
- const cleanUpDrafts: Record = {};
+ const cleanUpSetQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${string}` | `${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`, null> = {};
policyReports.forEach((policyReport) => {
if (!policyReport) {
return;
}
const {reportID} = policyReport;
- cleanUpDrafts[reportID] = null;
+ cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] = null;
cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${reportID}`] = null;
});
Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, cleanUpMergeQueries);
Onyx.multiSet(cleanUpSetQueries);
- Onyx.merge(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, cleanUpDrafts);
delete allPolicies[key];
return;
}
diff --git a/src/libs/actions/Policy/Member.ts b/src/libs/actions/Policy/Member.ts
index f2808add75e9..645aed4920a7 100644
--- a/src/libs/actions/Policy/Member.ts
+++ b/src/libs/actions/Policy/Member.ts
@@ -73,19 +73,17 @@ Onyx.connect({
const policyID = key.replace(ONYXKEYS.COLLECTION.POLICY, '');
const policyReports = ReportUtils.getAllPolicyReports(policyID);
const cleanUpMergeQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT}${string}`, NullishDeep> = {};
- const cleanUpSetQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`, null> = {};
- const cleanUpDrafts: Record = {};
+ const cleanUpSetQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${string}` | `${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`, null> = {};
policyReports.forEach((policyReport) => {
if (!policyReport) {
return;
}
const {reportID} = policyReport;
- cleanUpDrafts[reportID] = null;
+ cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] = null;
cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${reportID}`] = null;
});
Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, cleanUpMergeQueries);
Onyx.multiSet(cleanUpSetQueries);
- Onyx.merge(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, cleanUpDrafts);
delete allPolicies[key];
return;
}
diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts
index 3174782a9424..5d6d9143d7a5 100644
--- a/src/libs/actions/Policy/Policy.ts
+++ b/src/libs/actions/Policy/Policy.ts
@@ -181,19 +181,17 @@ Onyx.connect({
const policyID = key.replace(ONYXKEYS.COLLECTION.POLICY, '');
const policyReports = ReportUtils.getAllPolicyReports(policyID);
const cleanUpMergeQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT}${string}`, NullishDeep> = {};
- const cleanUpDrafts: Record = {};
- const cleanUpSetQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`, null> = {};
+ const cleanUpSetQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${string}` | `${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`, null> = {};
policyReports.forEach((policyReport) => {
if (!policyReport) {
return;
}
const {reportID} = policyReport;
- cleanUpDrafts[reportID] = null;
+ cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] = null;
cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${reportID}`] = null;
});
Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, cleanUpMergeQueries);
Onyx.multiSet(cleanUpSetQueries);
- Onyx.merge(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, cleanUpDrafts);
delete allPolicies[key];
return;
}
diff --git a/src/libs/actions/Policy/ReportField.ts b/src/libs/actions/Policy/ReportField.ts
index f08280c5ae97..85a25754b7e1 100644
--- a/src/libs/actions/Policy/ReportField.ts
+++ b/src/libs/actions/Policy/ReportField.ts
@@ -61,19 +61,17 @@ Onyx.connect({
const policyID = key.replace(ONYXKEYS.COLLECTION.POLICY, '');
const policyReports = ReportUtils.getAllPolicyReports(policyID);
const cleanUpMergeQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT}${string}`, NullishDeep> = {};
- const cleanUpDrafts: Record = {};
- const cleanUpSetQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`, null> = {};
+ const cleanUpSetQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${string}` | `${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`, null> = {};
policyReports.forEach((policyReport) => {
if (!policyReport) {
return;
}
const {reportID} = policyReport;
- cleanUpDrafts[reportID] = null;
+ cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] = null;
cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${reportID}`] = null;
});
Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, cleanUpMergeQueries);
Onyx.multiSet(cleanUpSetQueries);
- Onyx.merge(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, cleanUpDrafts);
delete allPolicies[key];
return;
}
diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts
index 4fbaaec634b0..2f98884b9cfd 100644
--- a/src/libs/actions/Policy/Tag.ts
+++ b/src/libs/actions/Policy/Tag.ts
@@ -49,16 +49,17 @@ Onyx.connect({
const policyID = key.replace(ONYXKEYS.COLLECTION.POLICY, '');
const policyReports = ReportUtils.getAllPolicyReports(policyID);
const cleanUpMergeQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT}${string}`, NullishDeep> = {};
- const cleanUpDrafts: Record = {};
+ const cleanUpSetQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${string}` | `${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`, null> = {};
policyReports.forEach((policyReport) => {
if (!policyReport) {
return;
}
const {reportID} = policyReport;
- cleanUpDrafts[reportID] = null;
+ cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] = null;
+ cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${reportID}`] = null;
});
Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, cleanUpMergeQueries);
- Onyx.merge(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, cleanUpDrafts);
+ Onyx.multiSet(cleanUpSetQueries);
delete allPolicies[key];
return;
}
diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts
index 5e47526932c5..32c60b50a699 100644
--- a/src/libs/actions/Report.ts
+++ b/src/libs/actions/Report.ts
@@ -177,7 +177,6 @@ import INPUT_IDS from '@src/types/form/NewRoomForm';
import type {
Account,
DismissedProductTraining,
- DraftReportComments,
IntroSelected,
InvitedEmailsToAccountIDs,
NewGroupChatDraft,
@@ -406,9 +405,10 @@ Onyx.connect({
callback: (val) => (introSelected = val),
});
-let allReportDraftComments: OnyxEntry = {};
+let allReportDraftComments: Record = {};
Onyx.connect({
- key: ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS,
+ key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT,
+ waitForCollectionCallback: true,
callback: (value) => (allReportDraftComments = value),
});
@@ -431,18 +431,16 @@ Onyx.connect({
// More info: https://github.com/Expensify/App/issues/14260
const policyID = key.replace(ONYXKEYS.COLLECTION.POLICY, '');
const policyReports = getAllPolicyReports(policyID);
- const cleanUpSetQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`, null> = {};
- const cleanUpDrafts: Record = {};
+ const cleanUpSetQueries: Record<`${typeof ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${string}` | `${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`, null> = {};
policyReports.forEach((policyReport) => {
if (!policyReport) {
return;
}
const {reportID} = policyReport;
- cleanUpDrafts[reportID] = null;
+ cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] = null;
cleanUpSetQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${reportID}`] = null;
});
Onyx.multiSet(cleanUpSetQueries);
- Onyx.merge(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, cleanUpDrafts);
delete allPolicies[key];
return;
}
@@ -1767,22 +1765,10 @@ function saveReportDraft(reportID: string, report: Report) {
/**
* Saves the comment left by the user as they are typing. By saving this data the user can switch between chats, close
* tab, refresh etc without worrying about loosing what they typed out.
+ * When empty string or null is passed, it will delete the draft comment from Onyx store.
*/
function saveReportDraftComment(reportID: string, comment: string | null, callback: () => void = () => {}) {
- API.write(
- WRITE_COMMANDS.SAVE_REPORT_DRAFT_COMMENT,
- {
- reportID,
- // reportComment is quoted to intentionally preserve trailing whitespace as the user types
- // otherwise it will be trimmed by the WAF _and_ Auth's SParseHTTP function
- reportComment: `"${comment}"`,
- },
- {optimisticData: [{onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, value: {[reportID]: prepareDraftComment(comment)}}]},
- {
- checkAndFixConflictingRequest: (persistedRequests) =>
- resolveDuplicationConflictAction(persistedRequests, (request) => request.command === WRITE_COMMANDS.SAVE_REPORT_DRAFT_COMMENT && request.data?.reportID === reportID),
- },
- ).then(callback);
+ Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`, prepareDraftComment(comment)).then(callback);
}
/** Broadcasts whether or not a user is typing on a report over the report's private pusher channel. */
@@ -1835,7 +1821,7 @@ function handleReportChanged(report: OnyxEntry) {
// Replacing the existing report's participants to avoid duplicates
participants: existingReport?.participants ?? report.participants,
});
- Onyx.merge(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, {[reportID]: null});
+ Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`, null);
};
// Only re-route them if they are still looking at the optimistically created report
if (Navigation.getActiveRoute().includes(`/r/${reportID}`)) {
@@ -1857,7 +1843,7 @@ function handleReportChanged(report: OnyxEntry) {
// In case the user is not on the report screen, we will transfer the report draft comment directly to the existing report
// after that clear the optimistically created report
- const draftReportComment = allReportDraftComments?.[reportID];
+ const draftReportComment = allReportDraftComments?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`];
if (!draftReportComment) {
callback();
return;
diff --git a/src/libs/migrateOnyx.ts b/src/libs/migrateOnyx.ts
index 59b62b563ebd..1279799cc29c 100644
--- a/src/libs/migrateOnyx.ts
+++ b/src/libs/migrateOnyx.ts
@@ -1,6 +1,5 @@
import Log from './Log';
import KeyReportActionsDraftByReportActionID from './migrations/KeyReportActionsDraftByReportActionID';
-import MoveDraftsToNVP from './migrations/MoveDraftsToNVP';
import MoveIsOptimisticReportToMetadata from './migrations/MoveIsOptimisticReportToMetadata';
import PendingMembersToMetadata from './migrations/PendingMembersToMetadata';
import PronounsMigration from './migrations/PronounsMigration';
@@ -20,7 +19,6 @@ export default function () {
PronounsMigration,
MoveIsOptimisticReportToMetadata,
PendingMembersToMetadata,
- MoveDraftsToNVP,
];
// Reduce all promises down to a single promise. All promises run in a linear fashion, waiting for the
diff --git a/src/libs/migrations/MoveDraftsToNVP.ts b/src/libs/migrations/MoveDraftsToNVP.ts
deleted file mode 100644
index eb2b1851ee5e..000000000000
--- a/src/libs/migrations/MoveDraftsToNVP.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import Onyx from 'react-native-onyx';
-import type {OnyxCollection, OnyxKey, OnyxMultiSetInput} from 'react-native-onyx';
-import Log from '@libs/Log';
-import ONYXKEYS from '@src/ONYXKEYS';
-import type {DraftReportComments} from '@src/types/onyx';
-
-// moves individual drafts from `${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}` to ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS
-export default function (): Promise {
- return new Promise((resolve) => {
- // eslint-disable-next-line rulesdir/no-onyx-connect
- const connection = Onyx.connect({
- // eslint-disable-next-line deprecation/deprecation
- key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT,
- waitForCollectionCallback: true,
- callback: (drafts: OnyxCollection) => {
- Onyx.disconnect(connection);
-
- if (!drafts) {
- Log.info('[Migrate Onyx] Skipped migration MoveDraftsToNVP because there were no drafts');
- return resolve();
- }
-
- const newDrafts: DraftReportComments = {};
- const draftsToClear: OnyxMultiSetInput = {};
- for (const [reportOnyxKey, draft] of Object.entries(drafts)) {
- if (!draft) {
- continue;
- }
- // eslint-disable-next-line deprecation/deprecation
- newDrafts[reportOnyxKey.replace(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, '')] = draft;
- draftsToClear[reportOnyxKey as OnyxKey] = null;
- }
-
- // eslint-disable-next-line rulesdir/prefer-actions-set-data
- Onyx.set(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, newDrafts);
-
- // eslint-disable-next-line rulesdir/prefer-actions-set-data
- Onyx.multiSet(draftsToClear);
- resolve();
- },
- });
- });
-}
diff --git a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx
index f02ec4d08b5c..d9c14cdeae53 100644
--- a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx
+++ b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx
@@ -34,18 +34,20 @@ import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus';
import {forceClearInput} from '@libs/ComponentUtils';
import {canSkipTriggerHotkeys, findCommonSuffixLength, insertText, insertWhiteSpaceAtIndex} from '@libs/ComposerUtils';
import convertToLTRForComposer from '@libs/convertToLTRForComposer';
+import {getDraftComment} from '@libs/DraftCommentUtils';
import {containsOnlyEmojis, extractEmojis, getAddedEmojis, getPreferredSkinToneIndex, replaceAndExtractEmojis} from '@libs/EmojiUtils';
import focusComposerWithDelay from '@libs/focusComposerWithDelay';
import getPlatform from '@libs/getPlatform';
import {addKeyDownPressListener, removeKeyDownPressListener} from '@libs/KeyboardShortcut/KeyDownPressListener';
import Parser from '@libs/Parser';
import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager';
-import {shouldAutoFocusOnKeyPress} from '@libs/ReportUtils';
+import {isValidReportIDFromPath, shouldAutoFocusOnKeyPress} from '@libs/ReportUtils';
import updateMultilineInputRange from '@libs/updateMultilineInputRange';
import willBlurTextInputOnTapOutsideFunc from '@libs/willBlurTextInputOnTapOutside';
import getCursorPosition from '@pages/home/report/ReportActionCompose/getCursorPosition';
import getScrollPosition from '@pages/home/report/ReportActionCompose/getScrollPosition';
import type {SuggestionsRef} from '@pages/home/report/ReportActionCompose/ReportActionCompose';
+import SilentCommentUpdater from '@pages/home/report/ReportActionCompose/SilentCommentUpdater';
import Suggestions from '@pages/home/report/ReportActionCompose/Suggestions';
import type {FileObject} from '@pages/media/AttachmentModalScreen/types';
import {isEmojiPickerVisible} from '@userActions/EmojiPickerAction';
@@ -244,22 +246,16 @@ function ComposerWithSuggestions(
const mobileInputScrollPosition = useRef(0);
const cursorPositionValue = useSharedValue({x: 0, y: 0});
const tag = useSharedValue(-1);
- const [draftReportComment] = useOnyx(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, {canBeMissing: true, selector: (draftReportComments) => draftReportComments?.[reportID]});
+ const draftComment = getDraftComment(reportID) ?? '';
const [value, setValue] = useState(() => {
- if (draftReportComment) {
- emojisPresentBefore.current = extractEmojis(draftReportComment);
+ if (draftComment) {
+ emojisPresentBefore.current = extractEmojis(draftComment);
}
- return draftReportComment ?? '';
+ return draftComment;
});
const commentRef = useRef(value);
- useEffect(() => {
- setValue(draftReportComment ?? '');
- setIsCommentEmpty(!draftReportComment || !!draftReportComment.match(CONST.REGEX.EMPTY_COMMENT));
- commentRef.current = draftReportComment ?? '';
- }, [draftReportComment, setIsCommentEmpty]);
-
const [modal] = useOnyx(ONYXKEYS.MODAL, {canBeMissing: true});
const [preferredSkinTone = CONST.EMOJI_DEFAULT_SKIN_TONE] = useOnyx(ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE, {selector: getPreferredSkinToneIndex, canBeMissing: true});
const [editFocused] = useOnyx(ONYXKEYS.INPUT_FOCUSED, {canBeMissing: true});
@@ -377,7 +373,7 @@ function ComposerWithSuggestions(
* Update the value of the comment in Onyx
*/
const updateComment = useCallback(
- (commentValue: string) => {
+ (commentValue: string, shouldDebounceSaveComment?: boolean) => {
raiseIsScrollLikelyLayoutTriggered();
const {startIndex, endIndex, diff} = findNewlyAddedChars(lastTextRef.current, commentValue);
const isEmojiInserted = diff.length && endIndex > startIndex && diff.trim() === diff && containsOnlyEmojis(diff);
@@ -419,9 +415,12 @@ function ComposerWithSuggestions(
}
commentRef.current = newCommentConverted;
-
- isCommentPendingSaved.current = true;
- debouncedSaveReportComment(reportID, newCommentConverted);
+ if (shouldDebounceSaveComment) {
+ isCommentPendingSaved.current = true;
+ debouncedSaveReportComment(reportID, newCommentConverted);
+ } else {
+ saveReportDraftComment(reportID, newCommentConverted);
+ }
if (newCommentConverted) {
debouncedBroadcastUserIsTyping(reportID);
}
@@ -436,7 +435,7 @@ function ComposerWithSuggestions(
(text: string) => {
// selection replacement should be debounced to avoid conflicts with text typing
// (f.e. when emoji is being picked and 1 second still did not pass after user finished typing)
- updateComment(insertText(commentRef.current, selection, text));
+ updateComment(insertText(commentRef.current, selection, text), true);
},
[selection, updateComment],
);
@@ -494,7 +493,7 @@ function ComposerWithSuggestions(
positionX: prevSelection.positionX,
positionY: prevSelection.positionY,
}));
- updateComment(newText);
+ updateComment(newText, true);
}
}
},
@@ -503,7 +502,7 @@ function ComposerWithSuggestions(
const onChangeText = useCallback(
(commentValue: string) => {
- updateComment(commentValue);
+ updateComment(commentValue, true);
if (isIOSNative && syncSelectionWithOnChangeTextRef.current) {
const positionSnapshot = syncSelectionWithOnChangeTextRef.current.position;
@@ -725,7 +724,7 @@ function ComposerWithSuggestions(
mobileInputScrollPosition.current = 0;
// Note: use the value when the clear happened, not the current value which might have changed already
onCleared(text);
- updateComment('');
+ updateComment('', true);
},
[onCleared, updateComment],
);
@@ -843,6 +842,16 @@ function ComposerWithSuggestions(
resetKeyboardInput={resetKeyboardInput}
/>
+ {isValidReportIDFromPath(reportID) && (
+
+ )}
+
{/* Only used for testing so far */}
{children}
>
diff --git a/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/index.android.tsx b/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/index.android.tsx
new file mode 100644
index 000000000000..b64672b28f9f
--- /dev/null
+++ b/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/index.android.tsx
@@ -0,0 +1,29 @@
+import {useEffect} from 'react';
+import useOnyx from '@hooks/useOnyx';
+import ONYXKEYS from '@src/ONYXKEYS';
+import type SilentCommentUpdaterProps from './types';
+
+/**
+ * Adding .android component to disable updating comment when prev comment is different
+ * it fixes issue on Android, assuming we don't need tab sync on mobiles - https://github.com/Expensify/App/issues/28562
+ */
+
+/**
+ * This component doesn't render anything. It runs a side effect to update the comment of a report under certain conditions.
+ * It is connected to the actual draft comment in onyx. The comment in onyx might updates multiple times, and we want to avoid
+ * re-rendering a UI component for that. That's why the side effect was moved down to a separate component.
+ */
+function SilentCommentUpdater({updateComment, reportID}: SilentCommentUpdaterProps) {
+ const [comment = ''] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`, {canBeMissing: true});
+
+ useEffect(() => {
+ updateComment(comment);
+ // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps -- We need to run this on mount
+ }, []);
+
+ return null;
+}
+
+SilentCommentUpdater.displayName = 'SilentCommentUpdater';
+
+export default SilentCommentUpdater;
diff --git a/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/index.tsx b/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/index.tsx
new file mode 100644
index 000000000000..efe1c79c28d8
--- /dev/null
+++ b/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/index.tsx
@@ -0,0 +1,43 @@
+import {useEffect} from 'react';
+import useLocalize from '@hooks/useLocalize';
+import useOnyx from '@hooks/useOnyx';
+import usePrevious from '@hooks/usePrevious';
+import ONYXKEYS from '@src/ONYXKEYS';
+import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
+import type SilentCommentUpdaterProps from './types';
+
+/**
+ * This component doesn't render anything. It runs a side effect to update the comment of a report under certain conditions.
+ * It is connected to the actual draft comment in onyx. The comment in onyx might updates multiple times, and we want to avoid
+ * re-rendering a UI component for that. That's why the side effect was moved down to a separate component.
+ */
+function SilentCommentUpdater({commentRef, reportID, value, updateComment, isCommentPendingSaved}: SilentCommentUpdaterProps) {
+ const [comment = '', commentResult] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`, {canBeMissing: true});
+ const prevCommentProp = usePrevious(comment);
+ const prevReportId = usePrevious(reportID);
+ const {preferredLocale} = useLocalize();
+ const prevPreferredLocale = usePrevious(preferredLocale);
+
+ useEffect(() => {
+ if (isLoadingOnyxValue(commentResult)) {
+ return;
+ }
+ // Value state does not have the same value as comment props when the comment gets changed from another tab.
+ // In this case, we should synchronize the value between tabs.
+ const shouldSyncComment = prevCommentProp !== comment && value !== comment && !isCommentPendingSaved.current;
+
+ // As the report IDs change, make sure to update the composer comment as we need to make sure
+ // we do not show incorrect data in there (ie. draft of message from other report).
+ if (preferredLocale === prevPreferredLocale && reportID === prevReportId && !shouldSyncComment) {
+ return;
+ }
+
+ updateComment(comment ?? '');
+ }, [prevCommentProp, prevPreferredLocale, prevReportId, comment, preferredLocale, reportID, updateComment, value, commentRef, isCommentPendingSaved, commentResult]);
+
+ return null;
+}
+
+SilentCommentUpdater.displayName = 'SilentCommentUpdater';
+
+export default SilentCommentUpdater;
diff --git a/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/types.ts b/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/types.ts
new file mode 100644
index 000000000000..2768dfc1250a
--- /dev/null
+++ b/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/types.ts
@@ -0,0 +1,18 @@
+type SilentCommentUpdaterProps = {
+ /** Updates the comment */
+ updateComment: (comment: string) => void;
+
+ /** The ID of the report associated with the comment */
+ reportID: string;
+
+ /** The value of the comment */
+ value: string;
+
+ /** The ref of the comment */
+ commentRef: React.RefObject;
+
+ /** The ref to check whether the comment saving is in progress */
+ isCommentPendingSaved: React.RefObject;
+};
+
+export default SilentCommentUpdaterProps;
diff --git a/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx b/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx
index dda9a41879be..180718a4a670 100644
--- a/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx
+++ b/src/pages/home/report/ReportActionCompose/SuggestionEmoji.tsx
@@ -72,7 +72,7 @@ function SuggestionEmoji(
const emojiCode = emojiObject?.types?.at(preferredSkinTone) && preferredSkinTone !== -1 ? emojiObject.types.at(preferredSkinTone) : emojiObject?.code;
const commentAfterColonWithEmojiNameRemoved = value.slice(selection.end);
- updateComment(`${commentBeforeColon}${emojiCode} ${trimLeadingSpace(commentAfterColonWithEmojiNameRemoved)}`);
+ updateComment(`${commentBeforeColon}${emojiCode} ${trimLeadingSpace(commentAfterColonWithEmojiNameRemoved)}`, true);
// In some Android phones keyboard, the text to search for the emoji is not cleared
// will be added after the user starts typing again on the keyboard. This package is
diff --git a/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx b/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx
index 865931aab9ac..87cdfd34fdd7 100644
--- a/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx
+++ b/src/pages/home/report/ReportActionCompose/SuggestionMention.tsx
@@ -203,7 +203,7 @@ function SuggestionMention(
suggestionValues.atSignIndex + Math.max(originalMention.length, suggestionValues.mentionPrefix.length + suggestionValues.prefixType.length),
);
- updateComment(`${commentBeforeAtSign}${mentionCode} ${trimLeadingSpace(commentAfterMention)}`);
+ updateComment(`${commentBeforeAtSign}${mentionCode} ${trimLeadingSpace(commentAfterMention)}`, true);
const selectionPosition = suggestionValues.atSignIndex + mentionCode.length + CONST.SPACE_LENGTH;
setSelection({
start: selectionPosition,
diff --git a/src/pages/home/report/ReportActionCompose/Suggestions.tsx b/src/pages/home/report/ReportActionCompose/Suggestions.tsx
index 74efae903116..8b7171340b63 100644
--- a/src/pages/home/report/ReportActionCompose/Suggestions.tsx
+++ b/src/pages/home/report/ReportActionCompose/Suggestions.tsx
@@ -21,7 +21,7 @@ type SuggestionProps = {
setSelection: (newSelection: TextSelection) => void;
/** Callback to update the comment draft */
- updateComment: (newComment: string) => void;
+ updateComment: (newComment: string, shouldDebounceSaveComment?: boolean) => void;
/** Measures the parent container's position and dimensions. Also add cursor coordinates */
measureParentContainerAndReportCursor: (callback: MeasureParentContainerAndCursorCallback) => void;
diff --git a/src/types/onyx/DraftReportComments.ts b/src/types/onyx/DraftReportComments.ts
deleted file mode 100644
index 385a9623a36a..000000000000
--- a/src/types/onyx/DraftReportComments.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Map of reportID => comment
- */
-type DraftReportComments = Record;
-
-export default DraftReportComments;
diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts
index 4aa8b7f0951d..d169a7730462 100644
--- a/src/types/onyx/index.ts
+++ b/src/types/onyx/index.ts
@@ -27,7 +27,6 @@ import type {OutstandingReportsByPolicyIDDerivedValue, ReportAttributesDerivedVa
import type DismissedProductTraining from './DismissedProductTraining';
import type DismissedReferralBanners from './DismissedReferralBanners';
import type Download from './Download';
-import type DraftReportComments from './DraftReportComments';
import type ExpensifyCardBankAccountMetadata from './ExpensifyCardBankAccountMetadata';
import type ExpensifyCardSettings from './ExpensifyCardSettings';
import type ExportTemplate from './ExportTemplate';
@@ -274,5 +273,4 @@ export type {
BillingReceiptDetails,
ExportTemplate,
HybridApp,
- DraftReportComments,
};
diff --git a/tests/ui/LHNItemsPresence.tsx b/tests/ui/LHNItemsPresence.tsx
index 4e01be0ceafc..95374059dd7f 100644
--- a/tests/ui/LHNItemsPresence.tsx
+++ b/tests/ui/LHNItemsPresence.tsx
@@ -177,7 +177,7 @@ describe('SidebarLinksData', () => {
await waitForBatchedUpdatesWithAct();
// And a draft message is added to the report.
- await Onyx.merge(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, {[draftReport.reportID]: 'draft report message'});
+ await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${draftReport.reportID}`, 'draft report message');
// Then the sidebar should display the draft report.
expect(getDisplayNames()).toHaveLength(1);
diff --git a/tests/unit/DebugUtilsTest.ts b/tests/unit/DebugUtilsTest.ts
index 34e71bc2996c..c3346c726922 100644
--- a/tests/unit/DebugUtilsTest.ts
+++ b/tests/unit/DebugUtilsTest.ts
@@ -739,7 +739,7 @@ describe('DebugUtils', () => {
expect(reason).toBeNull();
});
it('returns correct reason when report has a valid draft comment', async () => {
- await Onyx.set(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, {[baseReport.reportID]: 'Hello world!'});
+ await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}1`, 'Hello world!');
const reason = DebugUtils.getReasonForShowingRowInLHN({report: baseReport, chatReport: chatReportR14932, doesReportHaveViolations: false});
expect(reason).toBe('debug.reasonVisibleInLHN.hasDraftComment');
});
diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts
index f36ac88abf2a..4f91e397c1cf 100644
--- a/tests/unit/ReportUtilsTest.ts
+++ b/tests/unit/ReportUtilsTest.ts
@@ -2312,7 +2312,7 @@ describe('ReportUtils', () => {
const isInFocusMode = false;
const betas = [CONST.BETAS.DEFAULT_ROOMS];
- await Onyx.merge(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, {[report.reportID]: 'fake draft'});
+ await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report.reportID}`, 'fake draft');
expect(
shouldReportBeInOptionList({
diff --git a/tests/unit/SidebarFilterTest.ts b/tests/unit/SidebarFilterTest.ts
index 7e35b7108cb0..f2b3078994c1 100644
--- a/tests/unit/SidebarFilterTest.ts
+++ b/tests/unit/SidebarFilterTest.ts
@@ -27,7 +27,6 @@ const ONYXKEYS = {
REPORT_DRAFT_COMMENT: 'reportDraftComment_',
},
NETWORK: 'network',
- NVP_DRAFT_REPORT_COMMENTS: 'nvp_draftReportComments',
} as const;
// We need to fix this test as a follow up. There seems to be some problems with memory after filtering got more complicated.
@@ -121,7 +120,7 @@ xdescribe('Sidebar', () => {
Onyx.multiSet({
[ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails,
[ONYXKEYS.IS_LOADING_APP]: false,
- [ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS]: {[report.reportID]: 'This is a draft message'},
+ [`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report.reportID}`]: 'This is a draft message',
...reportCollectionDataSet,
}),
)
@@ -496,7 +495,7 @@ xdescribe('Sidebar', () => {
[ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.GSD,
[ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails,
[ONYXKEYS.IS_LOADING_APP]: false,
- [ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS]: {[draftReport.reportID]: 'draft report message'},
+ [`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${draftReport.reportID}`]: 'draft report message',
...reportCollectionDataSet,
}),
)
@@ -720,7 +719,7 @@ xdescribe('Sidebar', () => {
[ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails,
[ONYXKEYS.IS_LOADING_APP]: false,
[`${ONYXKEYS.COLLECTION.POLICY}${policy.policyID}`]: policy,
- [ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS]: {[report2.reportID]: hasDraft ? 'report2 draft' : null},
+ [`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report2.reportID}`]: hasDraft ? 'report2 draft' : null,
...reportCollectionDataSet,
}),
)
diff --git a/tests/unit/SidebarOrderTest.ts b/tests/unit/SidebarOrderTest.ts
index 0efe35d485a5..84f967b5a1db 100644
--- a/tests/unit/SidebarOrderTest.ts
+++ b/tests/unit/SidebarOrderTest.ts
@@ -187,7 +187,7 @@ describe('Sidebar', () => {
[ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT,
[ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails,
[ONYXKEYS.IS_LOADING_APP]: false,
- [ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS]: {[report1.reportID]: 'report1 draft'},
+ [`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report1.reportID}`]: 'report1 draft',
...reportCollectionDataSet,
}),
)
@@ -501,7 +501,7 @@ describe('Sidebar', () => {
[ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT,
[ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails,
[ONYXKEYS.IS_LOADING_APP]: false,
- [ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS]: {[report2.reportID]: 'This is a draft'},
+ [ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT + report2.reportID]: 'This is a draft',
...reportCollectionDataSet,
}),
)
@@ -548,7 +548,7 @@ describe('Sidebar', () => {
[ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT,
[ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails,
[ONYXKEYS.IS_LOADING_APP]: false,
- [ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS]: {[report.reportID]: 'This is a draft'},
+ [`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report.reportID}`]: 'This is a draft',
...reportCollectionDataSet,
}),
)
@@ -559,7 +559,7 @@ describe('Sidebar', () => {
})
// When the draft is removed
- .then(() => Onyx.merge(ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS, {[report.reportID]: null}))
+ .then(() => Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report.reportID}`, null))
// Then the pencil icon goes away
.then(() => {
@@ -674,7 +674,7 @@ describe('Sidebar', () => {
[ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT,
[ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails,
[ONYXKEYS.IS_LOADING_APP]: false,
- [ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS]: {[report2.reportID]: 'Report2 draft comment'},
+ [`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report2.reportID}`]: 'Report2 draft comment',
...reportCollectionDataSet,
}),
)
@@ -785,11 +785,9 @@ describe('Sidebar', () => {
};
const reportDraftCommentCollectionDataSet = {
- [ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS]: {
- [report1.reportID]: 'report1 draft',
- [report2.reportID]: 'report2 draft',
- [report3.reportID]: 'report3 draft',
- },
+ [`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report1.reportID}`]: 'report1 draft',
+ [`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report2.reportID}`]: 'report2 draft',
+ [`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report3.reportID}`]: 'report3 draft',
};
return (
@@ -821,7 +819,7 @@ describe('Sidebar', () => {
.then(() =>
Onyx.multiSet({
...reportDraftCommentCollectionDataSet,
- [ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS]: {[report4.reportID]: 'report4 draft'},
+ [`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report4.reportID}`]: 'report4 draft',
[`${ONYXKEYS.COLLECTION.REPORT}${report4.reportID}`]: report4,
...reportCollectionDataSet,
}),
diff --git a/tests/unit/SidebarUtilsTest.ts b/tests/unit/SidebarUtilsTest.ts
index f50a338ba8b6..32cfe0a187d0 100644
--- a/tests/unit/SidebarUtilsTest.ts
+++ b/tests/unit/SidebarUtilsTest.ts
@@ -1492,15 +1492,14 @@ describe('SidebarUtils', () => {
describe('sortReportsToDisplayInLHN', () => {
describe('categorizeReportsForLHN', () => {
it('should categorize reports into correct groups', () => {
- const {reports, reportNameValuePairs, reportAttributes} = createSidebarTestData();
+ // Given hasValidDraftComment is mocked to return true for report '2'
+ const {hasValidDraftComment} = require('@libs/DraftCommentUtils') as {hasValidDraftComment: jest.Mock};
+ hasValidDraftComment.mockImplementation((reportID: string) => reportID === '2');
- // Given draftReportComments with a draft for report '2'
- const draftReportComments = {
- '2': 'This is a draft comment',
- };
+ const {reports, reportNameValuePairs, reportAttributes} = createSidebarTestData();
// When the reports are categorized
- const result = SidebarUtils.categorizeReportsForLHN(reports, reportNameValuePairs, reportAttributes, draftReportComments);
+ const result = SidebarUtils.categorizeReportsForLHN(reports, reportNameValuePairs, reportAttributes);
// Then the reports are categorized into the correct groups
expect(result.pinnedAndGBRReports).toHaveLength(1);
@@ -1536,7 +1535,7 @@ describe('SidebarUtils', () => {
};
// When the reports are categorized
- const result = SidebarUtils.categorizeReportsForLHN(reports, undefined, reportAttributes, undefined);
+ const result = SidebarUtils.categorizeReportsForLHN(reports, undefined, reportAttributes);
// Then the reports are categorized into the correct groups
expect(result.pinnedAndGBRReports).toHaveLength(1);
@@ -1563,7 +1562,7 @@ describe('SidebarUtils', () => {
};
// When the reports are categorized
- const result = SidebarUtils.categorizeReportsForLHN(reports, undefined, undefined, undefined);
+ const result = SidebarUtils.categorizeReportsForLHN(reports);
// Then the reports are categorized into the correct groups
expect(result.pinnedAndGBRReports).toHaveLength(0);
@@ -1577,7 +1576,7 @@ describe('SidebarUtils', () => {
it('should handle empty reports object', () => {
// Given the reports are empty
- const result = SidebarUtils.categorizeReportsForLHN({}, undefined, undefined, undefined);
+ const result = SidebarUtils.categorizeReportsForLHN({});
// Then the reports are categorized into the correct groups
expect(result.pinnedAndGBRReports).toHaveLength(0);
@@ -1586,37 +1585,6 @@ describe('SidebarUtils', () => {
expect(result.nonArchivedReports).toHaveLength(0);
expect(result.archivedReports).toHaveLength(0);
});
-
- it('should categorize draft reports using draftReportComments parameter', () => {
- // Given reports with no drafts initially
- const reports = createSidebarReportsCollection([
- {
- reportName: 'Report 1',
- isPinned: false,
- hasErrorsOtherThanFailedReceipt: false,
- },
- {
- reportName: 'Report 2',
- isPinned: false,
- hasErrorsOtherThanFailedReceipt: false,
- },
- ]);
-
- // Given draftReportComments with drafts for both reports
- const draftReportComments = {
- '0': 'Draft comment for report 1',
- '1': 'Draft comment for report 2',
- };
-
- // When the reports are categorized
- const result = SidebarUtils.categorizeReportsForLHN(reports, undefined, undefined, draftReportComments);
-
- // Then both reports should be categorized as draft reports
- expect(result.draftReports).toHaveLength(2);
- expect(result.draftReports.at(0)?.reportID).toBe('0');
- expect(result.draftReports.at(1)?.reportID).toBe('1');
- expect(result.nonArchivedReports).toHaveLength(0);
- });
});
describe('sortCategorizedReports', () => {
@@ -1845,7 +1813,7 @@ describe('SidebarUtils', () => {
const priorityMode = CONST.PRIORITY_MODE.DEFAULT;
// When the reports are sorted
- const result = SidebarUtils.sortReportsToDisplayInLHN(reports, priorityMode, mockLocaleCompare, undefined, undefined, undefined);
+ const result = SidebarUtils.sortReportsToDisplayInLHN(reports, priorityMode, mockLocaleCompare);
// Then the reports are sorted in the correct order
expect(result).toEqual(['0', '1', '2']); // Pinned first, Error second, Normal third
@@ -1871,10 +1839,10 @@ describe('SidebarUtils', () => {
const mockLocaleCompare = (a: string, b: string) => a.localeCompare(b);
// When the reports are sorted in default mode
- const defaultResult = SidebarUtils.sortReportsToDisplayInLHN(reports, CONST.PRIORITY_MODE.DEFAULT, mockLocaleCompare, undefined, undefined, undefined);
+ const defaultResult = SidebarUtils.sortReportsToDisplayInLHN(reports, CONST.PRIORITY_MODE.DEFAULT, mockLocaleCompare);
// When the reports are sorted in GSD mode
- const gsdResult = SidebarUtils.sortReportsToDisplayInLHN(reports, CONST.PRIORITY_MODE.GSD, mockLocaleCompare, undefined, undefined, undefined);
+ const gsdResult = SidebarUtils.sortReportsToDisplayInLHN(reports, CONST.PRIORITY_MODE.GSD, mockLocaleCompare);
// Then the reports are sorted in the correct order
expect(defaultResult).toEqual(['1', '0']); // Most recent first (index 1 has later date)
diff --git a/tests/unit/useSidebarOrderedReportsTest.tsx b/tests/unit/useSidebarOrderedReportsTest.tsx
index 9b0aff784821..4f660b3861e0 100644
--- a/tests/unit/useSidebarOrderedReportsTest.tsx
+++ b/tests/unit/useSidebarOrderedReportsTest.tsx
@@ -58,7 +58,6 @@ describe('useSidebarOrderedReports', () => {
[ONYXKEYS.COLLECTION.TRANSACTION]: {},
[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS]: {},
[ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS]: {},
- [ONYXKEYS.NVP_DRAFT_REPORT_COMMENTS]: {},
[ONYXKEYS.BETAS]: [],
[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES]: {reports: {}},
} as unknown as OnyxMultiSetInput);
@@ -184,7 +183,6 @@ describe('useSidebarOrderedReports', () => {
expect.any(Function), // localeCompare
expect.any(Object), // reportNameValuePairs
expect.any(Object), // reportAttributes
- expect.any(Object), // drafts
);
});