From 8e627f78220734d90ded03d7c46746dc0a8af80d Mon Sep 17 00:00:00 2001
From: Bernhard Owen Josephus <bernhard.josephus@gmail.com>
Date: Mon, 7 Aug 2023 22:18:04 +0800
Subject: [PATCH 1/3] revert last message and others when add comment fails

---
 src/libs/actions/Report.js | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js
index 9dedfc3c595..55ebf91c9d8 100644
--- a/src/libs/actions/Report.js
+++ b/src/libs/actions/Report.js
@@ -243,14 +243,6 @@ function addActions(reportID, text = '', file) {
 
     const currentTime = DateUtils.getDBTime();
 
-    const lastVisibleMessage = ReportActionsUtils.getLastVisibleMessage(reportID);
-    let prevVisibleMessageText;
-    if (lastVisibleMessage.lastMessageTranslationKey) {
-        prevVisibleMessageText = Localize.translateLocal(lastVisibleMessage.lastMessageTranslationKey);
-    } else {
-        prevVisibleMessageText = lastVisibleMessage.lastMessageText;
-    }
-
     const lastCommentText = ReportUtils.formatReportLastMessageText(lastAction.message[0].text);
 
     const optimisticReport = {
@@ -301,9 +293,23 @@ function addActions(reportID, text = '', file) {
         },
     ];
 
-    const failureReport = {
-        lastMessageText: prevVisibleMessageText,
+    let failureReport = {
+        lastMessageTranslationKey: '',
+        lastMessageText: '',
+        lastVisibleActionCreated: '',
     };
+    const {lastMessageText = '', lastMessageTranslationKey = ''} = ReportActionsUtils.getLastVisibleMessage(reportID);
+    if (lastMessageText || lastMessageTranslationKey) {
+        const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(reportID);
+        const lastVisibleActionCreated = lastVisibleAction.created;
+        const lastActorAccountID = lastVisibleAction.actorAccountID;
+        failureReport = {
+            lastMessageTranslationKey,
+            lastMessageText,
+            lastVisibleActionCreated,
+            lastActorAccountID,
+        };
+    }
     const failureData = [
         {
             onyxMethod: Onyx.METHOD.MERGE,

From accdf6039d2fd282e426427b68e510b865a1864b Mon Sep 17 00:00:00 2001
From: Bernhard Owen Josephus <bernhard.josephus@gmail.com>
Date: Mon, 7 Aug 2023 22:18:52 +0800
Subject: [PATCH 2/3] fix LHN red dot does not update

---
 .../LHNOptionsList/OptionRowLHNData.js        | 21 ++++++++++++++++---
 src/libs/OptionsListUtils.js                  |  4 +---
 src/libs/SidebarUtils.js                      |  6 ++----
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/src/components/LHNOptionsList/OptionRowLHNData.js b/src/components/LHNOptionsList/OptionRowLHNData.js
index dff1cd3b15b..5b010593f1e 100644
--- a/src/components/LHNOptionsList/OptionRowLHNData.js
+++ b/src/components/LHNOptionsList/OptionRowLHNData.js
@@ -66,7 +66,18 @@ const defaultProps = {
  * The OptionRowLHN component is memoized, so it will only
  * re-render if the data really changed.
  */
-function OptionRowLHNData({shouldDisableFocusOptions, currentReportID, fullReport, personalDetails, preferredLocale, comment, policies, parentReportActions, ...propsToForward}) {
+function OptionRowLHNData({
+    shouldDisableFocusOptions,
+    currentReportID,
+    fullReport,
+    reportActions,
+    personalDetails,
+    preferredLocale,
+    comment,
+    policies,
+    parentReportActions,
+    ...propsToForward
+}) {
     const reportID = propsToForward.reportID;
     // We only want to pass a boolean to the memoized component,
     // instead of a changing number (so we prevent unnecessary re-renders).
@@ -79,7 +90,7 @@ function OptionRowLHNData({shouldDisableFocusOptions, currentReportID, fullRepor
     const optionItemRef = useRef();
     const optionItem = useMemo(() => {
         // Note: ideally we'd have this as a dependent selector in onyx!
-        const item = SidebarUtils.getOptionData(fullReport, personalDetails, preferredLocale, policy);
+        const item = SidebarUtils.getOptionData(fullReport, reportActions, personalDetails, preferredLocale, policy);
         if (deepEqual(item, optionItemRef.current)) {
             return optionItemRef.current;
         }
@@ -87,7 +98,7 @@ function OptionRowLHNData({shouldDisableFocusOptions, currentReportID, fullRepor
         return item;
         // Listen parentReportAction to update title of thread report when parentReportAction changed
         // eslint-disable-next-line react-hooks/exhaustive-deps
-    }, [fullReport, personalDetails, preferredLocale, policy, parentReportAction]);
+    }, [fullReport, reportActions, personalDetails, preferredLocale, policy, parentReportAction]);
 
     useEffect(() => {
         if (!optionItem || optionItem.hasDraftComment || !comment || comment.length <= 0 || isFocused) {
@@ -154,6 +165,10 @@ export default React.memo(
             fullReport: {
                 key: (props) => ONYXKEYS.COLLECTION.REPORT + props.reportID,
             },
+            reportActions: {
+                key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`,
+                canEvict: false,
+            },
             personalDetails: {
                 key: ONYXKEYS.PERSONAL_DETAILS_LIST,
                 selector: personalDetailsSelector,
diff --git a/src/libs/OptionsListUtils.js b/src/libs/OptionsListUtils.js
index 9c27fcaab8b..dacca54b8a9 100644
--- a/src/libs/OptionsListUtils.js
+++ b/src/libs/OptionsListUtils.js
@@ -349,10 +349,8 @@ function getSearchText(report, reportName, personalDetailList, isChatRoomOrPolic
 function getAllReportErrors(report, reportActions) {
     const reportErrors = report.errors || {};
     const reportErrorFields = report.errorFields || {};
-    const reportID = report.reportID;
-    const reportsActions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] || {};
     const reportActionErrors = _.reduce(
-        reportsActions,
+        reportActions,
         (prevReportActionErrors, action) => (!action || _.isEmpty(action.errors) ? prevReportActionErrors : _.extend(prevReportActionErrors, action.errors)),
         {},
     );
diff --git a/src/libs/SidebarUtils.js b/src/libs/SidebarUtils.js
index dd55b025b55..54035f93323 100644
--- a/src/libs/SidebarUtils.js
+++ b/src/libs/SidebarUtils.js
@@ -16,7 +16,6 @@ import * as PersonalDetailsUtils from './PersonalDetailsUtils';
 
 const visibleReportActionItems = {};
 const lastReportActions = {};
-const reportActions = {};
 Onyx.connect({
     key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
     callback: (actions, key) => {
@@ -35,8 +34,6 @@ Onyx.connect({
             (reportAction, actionKey) => ReportActionsUtils.shouldReportActionBeVisible(reportAction, actionKey) && reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED,
         );
         visibleReportActionItems[reportID] = _.last(reportActionsForDisplay);
-
-        reportActions[key] = actions;
     },
 });
 
@@ -180,12 +177,13 @@ function getOrderedReportIDs(currentReportId, allReportsDict, betas, policies, p
  * Gets all the data necessary for rendering an OptionRowLHN component
  *
  * @param {Object} report
+ * @param {Object} reportActions
  * @param {Object} personalDetails
  * @param {String} preferredLocale
  * @param {Object} [policy]
  * @returns {Object}
  */
-function getOptionData(report, personalDetails, preferredLocale, policy) {
+function getOptionData(report, reportActions, personalDetails, preferredLocale, policy) {
     // When a user signs out, Onyx is cleared. Due to the lazy rendering with a virtual list, it's possible for
     // this method to be called after the Onyx data has been cleared out. In that case, it's fine to do
     // a null check here and return early.

From 73f13c1e4b359a4f44aa677049b16438180633db Mon Sep 17 00:00:00 2001
From: Bernhard Owen Josephus <bernhard.josephus@gmail.com>
Date: Mon, 7 Aug 2023 22:51:34 +0800
Subject: [PATCH 3/3] fix lint

---
 src/libs/actions/Report.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js
index 55ebf91c9d8..51e2e5fc514 100644
--- a/src/libs/actions/Report.js
+++ b/src/libs/actions/Report.js
@@ -28,7 +28,6 @@ import * as PersonalDetailsUtils from '../PersonalDetailsUtils';
 import SidebarUtils from '../SidebarUtils';
 import * as OptionsListUtils from '../OptionsListUtils';
 import * as Environment from '../Environment/Environment';
-import * as Localize from '../Localize';
 
 let currentUserAccountID;
 Onyx.connect({
