Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[$250] Split - Chat does not scroll down when splitting expense #56510

Open
8 tasks done
mitarachim opened this issue Feb 7, 2025 · 19 comments
Open
8 tasks done

[$250] Split - Chat does not scroll down when splitting expense #56510

mitarachim opened this issue Feb 7, 2025 · 19 comments
Assignees
Labels
Bug Something is broken. Auto assigns a BugZero manager. Engineering External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2

Comments

@mitarachim
Copy link

mitarachim commented Feb 7, 2025

If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!


Version Number: 9.0.95-0
Reproducible in staging?: Yes
Reproducible in production?: No
If this was caught on HybridApp, is this reproducible on New Expensify Standalone?: N/A
If this was caught during regression testing, add the test name, ID and link from TestRail: Exp
Email or phone of affected tester (no customers): [email protected]
Issue reported by: Applause Internal Team
Device used: Mac 15.0 / Chrome
App Component: Money Requests

Action Performed:

  1. Go to staging.new.expensify.com
  2. Open chat with user that has no chat history.
  3. Click + > Split expense > Manual.
  4. Create a split manual expense.
  5. Scroll to the top of the chat.
  6. Repeat Step 3 to 5 a few times.

Expected Result:

The chat will scroll down each time a split expense is created.

Actual Result:

The chat does not scroll down and remains at the top each time a split expense is created.

Workaround:

Unknown

Platforms:

  • Android: Standalone
  • Android: HybridApp
  • Android: mWeb Chrome
  • iOS: Standalone
  • iOS: HybridApp
  • iOS: mWeb Safari
  • MacOS: Chrome / Safari
  • MacOS: Desktop

Screenshots/Videos

Bug6735800_1738893829326.20250207_100050.mp4

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~021889577320949386202
  • Upwork Job ID: 1889577320949386202
  • Last Price Increase: 2025-02-12
  • Automatic offers:
    • shubham1206agra | Reviewer | 106176130
Issue OwnerCurrent Issue Owner: @
@mitarachim mitarachim added Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 DeployBlocker Indicates it should block deploying the API DeployBlockerCash This issue or pull request should block deployment labels Feb 7, 2025
Copy link

melvin-bot bot commented Feb 7, 2025

Triggered auto assignment to @techievivek (DeployBlockerCash), see https://stackoverflowteams.com/c/expensify/questions/9980/ for more details.

Copy link

melvin-bot bot commented Feb 7, 2025

Triggered auto assignment to @laurenreidexpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

Copy link

melvin-bot bot commented Feb 7, 2025

💬 A slack conversation has been started in #expensify-open-source

@github-actions github-actions bot added Engineering Hourly KSv2 and removed Daily KSv2 labels Feb 7, 2025
Copy link
Contributor

github-actions bot commented Feb 7, 2025

👋 Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:

  1. Identify the pull request that introduced this issue and revert it.
  2. Find someone who can quickly fix the issue.
  3. Fix the issue yourself.

@techievivek
Copy link
Contributor

Seems like it was not fixed via this PR? #54863, I have pinged the author/reviewer.

@techievivek
Copy link
Contributor

Given this doesn't happen normally and a variant of this already exist as a separate GH, I will remove the blocker label.

@techievivek techievivek added Daily KSv2 and removed DeployBlockerCash This issue or pull request should block deployment Hourly KSv2 DeployBlocker Indicates it should block deploying the API labels Feb 7, 2025
@techievivek
Copy link
Contributor

@melvin-bot melvin-bot bot added the Overdue label Feb 10, 2025
Copy link

melvin-bot bot commented Feb 11, 2025

@techievivek, @laurenreidexpensify Whoops! This issue is 2 days overdue. Let's get this updated quick!

@techievivek
Copy link
Contributor

@techievivek techievivek added the External Added to denote the issue can be worked on by a contributor label Feb 12, 2025
@melvin-bot melvin-bot bot changed the title Split - Chat does not scroll down when splitting expense [$250] Split - Chat does not scroll down when splitting expense Feb 12, 2025
Copy link

melvin-bot bot commented Feb 12, 2025

Job added to Upwork: https://www.upwork.com/jobs/~021889577320949386202

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Feb 12, 2025
Copy link

melvin-bot bot commented Feb 12, 2025

Current assignee @shubham1206agra is eligible for the External assigner, not assigning anyone new.

@bernhardoj
Copy link
Contributor

Proposal

Please re-state the problem that we are trying to solve in this issue.

The chat doesn't scroll to the bottom when doing split bill in a DM. This only happens if there are unsettled expense on the DM.

What is the root cause of that problem?

It will scroll to the bottom if the report lastVisibleActionCreated is equal to the last action created value.

const hasNewestReportAction = lastAction?.created === lastVisibleActionCreated;
const hasNewestReportActionRef = useRef(hasNewestReportAction);

if (!hasNewestReportActionRef.current) {
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(report.reportID));
return;
}
reportScrollManager.scrollToBottom();

However, when we create a split bill in a DM, the lastVisibleActionCreated is not updated, or specifically, it's updated but with the current value. To understand it better, when we create a split bill, there are 2 kinds of report data that are being updated. First, is the split chat report, and the second one is the DM chat.

For example, if we split bill in a group chat of 3 users (including the current user), the split chat report is the group chat,

const {splitChatReport, existingSplitChatReport} = getOrCreateOptimisticSplitChatReport(existingSplitChatReportID, participants, participantAccountIDs, currentUserAccountID);

App/src/libs/actions/IOU.ts

Lines 5076 to 5096 in 4c1919e

splitChatReport.lastReadTime = DateUtils.getDBTime();
splitChatReport.lastMessageText = getReportActionText(splitIOUReportAction);
splitChatReport.lastMessageHtml = getReportActionHtml(splitIOUReportAction);
splitChatReport.lastActorAccountID = currentUserAccountID;
splitChatReport.lastVisibleActionCreated = splitIOUReportAction.created;
// If we have an existing splitChatReport (group chat or workspace) use it's pending fields, otherwise indicate that we are adding a chat
if (!existingSplitChatReport) {
splitChatReport.pendingFields = {
createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
};
}
const optimisticData: OnyxUpdate[] = [
{
// Use set for new reports because it doesn't exist yet, is faster,
// and we need the data to be available when we navigate to the chat page
onyxMethod: existingSplitChatReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.REPORT}${splitChatReport.reportID}`,
value: splitChatReport,
},

and there are 2 DM chats.

App/src/libs/actions/IOU.ts

Lines 5347 to 5353 in 4c1919e

const [oneOnOneOptimisticData, oneOnOneSuccessData, oneOnOneFailureData] = buildOnyxDataForMoneyRequest({
isNewChatReport: isNewOneOnOneChatReport,
shouldCreateNewMoneyRequestReport: shouldCreateNewOneOnOneIOUReport,
isOneOnOneSplit: true,
optimisticParams: {
chat: {
report: oneOnOneChatReport,

App/src/libs/actions/IOU.ts

Lines 1053 to 1067 in 4c1919e

if (chat.report) {
optimisticData.push({
// Use SET for new reports because it doesn't exist yet, is faster and we need the data to be available when we navigate to the chat page
onyxMethod: isNewChatReport ? Onyx.METHOD.SET : Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${chat.report.reportID}`,
value: {
...chat.report,
lastReadTime: DateUtils.getDBTime(),
...(shouldCreateNewMoneyRequestReport ? {lastVisibleActionCreated: chat.reportPreviewAction.created} : {}),
iouReportID: iou.report.reportID,
...outstandingChildRequest,
...(isNewChatReport ? {pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}} : {}),
},
});
}

Each report is updated by merging the report object with the new data. But if we split in a DM, the split chat report and the DM chat are the same. So, both updates will update the same report. We already correctly update the split chat report (which is the DM) lastVisibleActionCreated here:

splitChatReport.lastVisibleActionCreated = splitIOUReportAction.created;

But when updating the DM, we destructure the DM report which contains the old lastVisibleActionCreated.

App/src/libs/actions/IOU.ts

Lines 1053 to 1066 in 6000b2a

if (chat.report) {
optimisticData.push({
// Use SET for new reports because it doesn't exist yet, is faster and we need the data to be available when we navigate to the chat page
onyxMethod: isNewChatReport ? Onyx.METHOD.SET : Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${chat.report.reportID}`,
value: {
...chat.report,
lastReadTime: DateUtils.getDBTime(),
...(shouldCreateNewMoneyRequestReport ? {lastVisibleActionCreated: chat.reportPreviewAction.created} : {}),
iouReportID: iou.report.reportID,
...outstandingChildRequest,
...(isNewChatReport ? {pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}} : {}),
},
});

For example, let's say the DM lastVisibleActionCreated is 1. We have
split chat report (different object, but the same report data)
DM report (different object, but the same report data)

When we split bill, the split chat report lastVisibleActionCreated is set to 2, the onyx update will look like this

key: report_123,
value: {
  lastVisibleActionCreated: '2',
  ...,
}

Then, the DM report onyx update will look like this

key: report_123,
value: {
  lastVisibleActionCreated: '1', (destructure from chat.report)
  ...,
}

So, the lastVisibleActionCreated is not updated.

What changes do you think we should make in order to solve the problem?

Both split chat report and DM report are a different object even though it's the same report. There is already a solution here so that both reports are the same objects,

App/src/libs/actions/IOU.ts

Lines 5237 to 5245 in 6000b2a

// If this is a split between two people only and the function
// wasn't provided with an existing group chat report id
// or, if the split is being made from the workspace chat, then the oneOnOneChatReport is the same as the splitChatReport
// in this case existingSplitChatReport will belong to the policy expense chat and we won't be
// entering code that creates optimistic personal details
if ((!hasMultipleParticipants && !existingSplitChatReportID) || isOwnPolicyExpenseChat) {
oneOnOneChatReport = splitChatReport;
shouldCreateOptimisticPersonalDetails = !existingSplitChatReport && !personalDetailExists;
} else {

but it currently only covers 2 case,

  1. if it's a policy expense chat
  2. or if it's a split bill done from the FAB (!existingSplitChatReportID, which is not possible anymore) and only 1 participant, because it will do the split in a DM

In our case, we do the split bill directly from the DM. So, what we can do is add a check if the split chat report is a DM chat.

if ((!hasMultipleParticipants && !existingSplitChatReportID) || isOwnPolicyExpenseChat || isOneOnOneChat(splitChatReport)) {

What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?

We can do a unit test by split bill twice in a DM and making sure the lastVisibleActionCreated is updated.

@laurenreidexpensify
Copy link
Contributor

@shubham1206agra bump for review pls

@laurenreidexpensify
Copy link
Contributor

@shubham1206agra 👋 ^^

@melvin-bot melvin-bot bot removed the Overdue label Feb 17, 2025
@shubham1206agra
Copy link
Contributor

@bernhardoj's proposal looks good.

🎀👀🎀 C+ reviewed

Copy link

melvin-bot bot commented Feb 18, 2025

Triggered auto assignment to @justinpersaud, see https://stackoverflow.com/c/expensify/questions/7972 for more details.

@melvin-bot melvin-bot bot removed the Help Wanted Apply this label when an issue is open to proposals by contributors label Feb 18, 2025
Copy link

melvin-bot bot commented Feb 18, 2025

📣 @shubham1206agra 🎉 An offer has been automatically sent to your Upwork account for the Reviewer role 🎉 Thanks for contributing to the Expensify app!

Offer link
Upwork job

@melvin-bot melvin-bot bot added Reviewing Has a PR in review Weekly KSv2 and removed Daily KSv2 labels Feb 21, 2025
@bernhardoj
Copy link
Contributor

PR us ready

cc: @shubham1206agra

@dylanexpensify dylanexpensify moved this to Bugs and Follow Up Issues in [#whatsnext] #expense Feb 25, 2025
@shubham1206agra
Copy link
Contributor

Waiting for @techievivek's review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something is broken. Auto assigns a BugZero manager. Engineering External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2
Projects
Status: Bugs and Follow Up Issues
Development

No branches or pull requests

6 participants