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

Clean up lastReadSequenceNumbers and reportMaxSequenceNumbers #9755

Merged
merged 18 commits into from
Jul 12, 2022

Conversation

marcaaron
Copy link
Contributor

@marcaaron marcaaron commented Jul 7, 2022

Details

Quick draft to explore getting rid of these two "maps" of local variables that we have.

They are making it kind of hard to reason about our "optimistic" updates that need to be made and ideally we would be able to control these things from the server. So a first step is to keep referencing them on the report object instead of in these maps.

Also tried to clean up the logic around setting unreadActionCount as I noticed that the setLocalLastRead() method was being used sometimes to update the lastReadSequenceNumbers directly (which just seems wrong) but it also performed a confusing side effect of updating the unreadActionCount which also seems wrong and made it difficult to tell what things are updating the unreadActionCount at all.

Fixed Issues

(Related to both of these since the setting of unreads is pretty wonky atm)

https://github.com/Expensify/Expensify/issues/212871
https://github.com/Expensify/Expensify/issues/211601

Tests & QA

Test unread action shows

  1. As User A start a chat with User B
  2. Navigate to a different chat so it it out of view
  3. As User B leave a comment
  4. As User A verify the chat is bold in the LHN
  5. Navigate to the chat
  6. Verify the chat no longer displays as "unread" in the LHN
  7. Navigate away to a new chat and back again
  8. Verify the new marker has disappeared
2022-07-07_14-49-29.mp4

Note: Also verify a browser notification shows on Desktop and Web (not mobile web)

Test unread action does not show when report is active

  1. As User A start a chat with User B
  2. Stay navigated on the chat and do not navigate to another chat
  3. As User B leave a comment
  4. As User A verify the chat is not bolded
2022-07-07_14-53-37.mp4

Manually marking chat works as expected

  1. Start with a chat that has no deleted items at all and several messages
  2. Manually mark a message as "unread"
  3. Verify the green floating counter badge shows the correct number of unreads
  4. Verify the chat is shown bold in the LHN
  5. Verify the new marker shows in the correct location
2022-07-07_14-56-28.mp4

Deleted comments behave as expected when calculating unreads and lastMessageText

  1. Start with a chat that has no deleted items at all and several messages from the current user at the bottom
  2. Manually mark a message as "unread"
  3. Verify the green floating badge shows the correct number of unreads
  4. Verify the chat is shown bold in the LHN
  5. Verify the new marker shows in the correct location
  6. Delete a chat message that is older than the message marked as unread
  7. Verify it has no impact on the global chat counter or floating green badge
  8. Verify it does not mark the report as read
  9. Verify the "last message text" in the LHN associated with the chat is correct (it should still be the last message)
  10. Delete a chat message that is more recent than the last read but not the very last message
  11. Verify the floating green counter decreases by one
  12. Verify the report is still marked as "unread"
  13. Delete the last message and verify the previous 3 steps, but also verify the last message text updates correctly and should be the message before the deleted one.
2022-07-07_15-09-52.mp4

Test tapping green message counter will reset new marker line and mark report as read

  1. Add a bunch of comments to a report
  2. Mark a comment in the middle as unread
  3. Scroll up to reveal the floating green counter button
  4. Tap it
  5. Verify the report scrolls to the bottom
  6. Verify the report is marked as "read"
  7. Verify the new marker is removed
2022-07-07_15-14-16.mp4
  • Verify that no errors appear in the JS console

PR Review Checklist

Contributor (PR Author) Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • I verified there are no console errors (if there’s a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained “why” the code was doing something instead of only explaining “what” the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named “index.js”. All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose and it is
  • If a new CSS style is added I verified that:
    • A similar style doesn’t already exist
    • The style can’t be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.

PR Reviewer Checklist

  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I verified tests pass on all platforms & I tested again on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • I verified there are no console errors (if there’s a console error not related to the PR, report it or open an issue for it to be fixed)
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained “why” the code was doing something instead of only explaining “what” the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named “index.js”. All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn’t already exist
    • The style can’t be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.

Note: Tested on all platforms, but not posting videos since there are no UI changes.

@marcaaron marcaaron self-assigned this Jul 7, 2022
@marcaaron marcaaron mentioned this pull request Jul 7, 2022
89 tasks
@marcaaron
Copy link
Contributor Author

cc @madmax330 @tgolen

Coming from this comment thread... I wanted to start a big conversation about this stuff, but as I started to write it all down it became clear that it might be easier to just suss out a few ideas in a PR review first...

My ultimate goal is to get rid of this block of code here:

App/src/libs/actions/Report.js

Lines 1407 to 1420 in eb54f23

// When handling an action from the current users we can assume that their
// last read actionID has been updated in the server but not necessarily reflected
// locally so we must first update it and then calculate the unread (which should be 0)
if (isFromCurrentUser) {
setLocalLastRead(reportID, newMaxSequenceNumber);
}
const updatedReportObject = {
// Use updated lastReadSequenceNumber, value may have been modified by setLocalLastRead
// Here deletedComments count does not include the new action being added. We can safely assume that newly received action is not deleted.
unreadActionCount: newMaxSequenceNumber - (lastReadSequenceNumbers[reportID] || 0) - ReportActions.getDeletedCommentsCount(reportID, lastReadSequenceNumbers[reportID] || 0),
};
Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, updatedReportObject);

But getting rid of setLocalLastRead() requires the changes in this PR. So I wanted to unwind some of this first and then get some more 👀 on how to get rid of the side effect here that updates the unreadActionCount of a report.

At a high level it looks like we do this:

  • New comment appears for a report
    A. If it's from the current user we set the unreadActionCount for the report to 0 (hopefully)
    B. If it's not from the current user we recalculate the unreadActionCount based on the new sequence number

Getting rid of A seems easy enough. Just set the lastReadSequenceNumber and unreadActionCount in the server because the user just left a new comment on a report.

B is a little trickier because when sending out updates to participants you'd need to calculate the "unread" like we are doing in the frontend and then push that out as an onyx update. This process in the server would probably look something like:

  • Get each participant's lastRead_<accountID> rNVP for the report where a comment is added
  • Also get the number of "deleted comments" in the range between lastReadSequenceNumber and maxSequenceNumber
  • Calculate the unreadActionCount and push each clients unique value to them

I can't really think of any reason why that would not work, but feel like I'm missing something.

Regardless, I think some changes like I've got in this PR would be a good "stepping" stone since the setLocalLastRead() method is causing some confusion in the places where we are trying to refactor it away.

@tgolen
Copy link
Contributor

tgolen commented Jul 7, 2022

Hey Marc,

I like the direction this is doing in. It already feels cleaner and I love the removal of setLocalLastRead().

I know I'm not as close to this code as you are, so I don't have a full understanding over all the logic that exists. Hopefully, I can offer somewhat of an outsider perspective with my next suggestion.

Getting rid of A seems easy enough. Just set the lastReadSequenceNumber and unreadActionCount in the server because the user just left a new comment on a report.

This makes sense to me 👍

B is a little trickier because when sending out updates to participants you'd need to calculate the "unread" like we are doing in the frontend

My out-of-the-box idea here is that maybe instead of pushing out the unread count for each participant, we push out an event that is basically "increment the unread count for report ID: X". That way there doesn't really need to be any math or calculations done. We just know that there is a new comment for the report, and until the comment is explicitly seen, we know it should just increment the participants counter by 1.

That works if everyone is online and connected to pusher. If a participant is not connected to pusher, the next time they connect, the front-end (or maybe the server) should still be able to calculate the unread count properly.

Thoughts about that approach?

@madmax330
Copy link
Contributor

Same as Tim I agree with A.

For B I like the event idea, but we'd also have to have an event for deleted chats no? Depending on whether you're deleting a chat that has been read already or not.

Another idea is:

The unread count should always be lastReadSequenceNumber - maxSequenceNumber that way it's super simple.
How that would work is, when we get chats we ignore the deleted ones, so they're not included in the maxSequenceNumber.
When we delete a chat, we just decrement maxSequenceNumber and lastReadSequenceNumber b/c that's basically what will happen on the server.
To account for deleted chats that may or may not have been read. We do deletedSequenceNumber > lastRead ? decrementBoth() : decrementMaxSequenceNumber()

Basically we're optimistically predicting the changes in the sequenceNumber from the server response.

@madmax330
Copy link
Contributor

Or even simpler, this might be a naive question, but why can't we just count the number of actions after the lastReadSequenceNumber that aren't deleted?

@marcaaron
Copy link
Contributor Author

Oh wow, nice, I really love both of these ideas!

@tgolen I like this because we can essentially stop tracking maxSequenceNumber altogether and avoid any calculations in the client (I think we still need lastReadSequenceNumber for the "new marker", but we can stop using the maxSequenceNumber - which seems exclusively used to calculate the "unread count").

That way there doesn't really need to be any math or calculations done. We just know that there is a new comment for the report, and until the comment is explicitly seen, we know it should just increment the participants counter by 1.

Very cool, so something like:

  • Fetch initial report -> user starts with base count from server
  • Report action deleted optimistically -> count--
  • Report action failed to be deleted (rollback) -> count++
  • New action appears from current user -> reset count to 0
  • New action appears from a different user -> count++

We could let the server send out these "increment" or "decrement" instructions that way we don't have to have specific events to track "new comment" vs "deleted comment" and could just do stuff like:

[
    'onyxMethod' => 'merge',
    'key' => 'report_1',
    'value' => [
        'unreadActionCount' => '++',
    ],
],

Not sure if we want something like that or something simpler like just having an event like updateReportUnreadCount that sends a payload like:

[
    'action' => 'increment'
    'reportID' => 1, 
],

@madmax330 your idea sounds nice since we won't need specific events to tell the client to increment or decrement. But it seems like in practice we could have something like this...

0 - deleted
1 - deleted
2 - deleted
3 - deleted
4 - Comment 1
5 - Comment 2 (last read)
6 - Comment 3

and the last read would be 5 but the maxSequenceNumber would be 2? But maybe you are saying that in this case the lastReadSequenceNumber would not be 5 and would be 1 - which would give us a count of 1 unread.

The only potential issue I see with this is that when modifying the lastReadSequenceNumber we would need to figure out where to position the "new marker" since the report actions themselves are not having their sequenceNumber decremented when things are deleted.

Or even simpler, this might be a naive question, but why can't we just count the number of actions after the lastReadSequenceNumber that aren't deleted?

The problem with counting the report actions themselves is that they might not exist at all locally.

@madmax330
Copy link
Contributor

The problem with counting the report actions themselves is that they might not exist at all locally.

Can you elaborate on this? Why wouldn't they?

@marcaaron
Copy link
Contributor Author

marcaaron commented Jul 7, 2022

Can you elaborate on this? Why wouldn't they?

Because they are paginated and we only download a subset of the chats you have when the app starts not all of your chats and chat messages. They can also get "evicted" if we run out of device storage but that is rarer now (especially on web)

@madmax330
Copy link
Contributor

Because they are paginated and we only download a subset of the chats you have when the app starts

This is only an issue if you have more unreads than the page size though right?
And it's also an issue for all the other solution as well right? Because before incrementing or decrementing we have to base ourselves on something to get the initial count. That something being the reportActions. Or am I missing something?

They can also get "evicted" if we run out of device storage but that is rarer now (especially on web)

Yeah I'm not sure how to deal with this.

@marcaaron
Copy link
Contributor Author

This is only an issue if you have more unreads than the page size though right?

Yes, to use the reportActions alone we'd need to have all the chat messages for all the chats from the "last read" to the "most recent".

And it's also an issue for all the other solution as well right? Because before incrementing or decrementing we have to base ourselves on something to get the initial count. That something being the reportActions. Or am I missing something?

unreadActionCount is always initially based on the lastReadSequenceNumber and number of report actions (we return a reportActionCount from Auth and know this without having to count the actions themselves in the frontend).

@tgolen
Copy link
Contributor

tgolen commented Jul 7, 2022

Yes, to use the reportActions alone we'd need to have all the chat messages for all the chats from the "last read" to the "most recent".

Just a quick thought on this... it actually sounds like that could be an improvement to our pagination. Instead of always getting the 50 most recent chats for the first page, the first page could be either the 50 most recent OR all the chats since "last read".

I love this! ❤️ Slight tweak below in bold is needed (I think)

Very cool, so something like:

Fetch initial report -> user starts with base count from server
Report action deleted optimistically -> count--
Report action failed to be deleted (rollback) -> count++
New action appears from current user -> reset count to 0
New action appears from a different user -> count++
Action is deleted from a different user -> count-- (?) I'm not exactly sure what would happen here

Not sure if we want something like that or something simpler like just having an event like updateReportUnreadCount that sends a payload like:

I'd vote for something like that ^, yeah. I think the other option just makes it a little too magical and I fear it could wreak havoc in unexpected ways at some point without knowing it.

@marcaaron
Copy link
Contributor Author

Action is deleted from a different user -> count-- (?) I'm not exactly sure what would happen here

Oh yes, actually I think if an action is deleted by any user we would still need to look at the lastReadSequenceNumber to decide what to do...

action deleted has a sequenceNumber > the lastReadSequenceNumber -> count--
action deleted has a sequenceNumber < the lastReadSequenceNumber -> do nothing since only actions greater than the lastReadSequenceNumber would affect the count

@marcaaron
Copy link
Contributor Author

Just a quick thought on this... it actually sounds like that could be an improvement to our pagination. Instead of always getting the 50 most recent chats for the first page, the first page could be either the 50 most recent OR all the chats since "last read".

We could possibly send out paginated report actions with every new comment that gets added...

e.g.

  • User A has no chat messages locally stored for a chat with User B (the chat itself has 200 historical messages)
  • The last message User A read was sequenceNumber 50
  • User B sends a new message with sequenceNumber 201
  • In the server, we look at User A's last read recorded and send every message from 50 - 201 to User A
  • User A can now figure out that their unread count based on actions alone

@tgolen
Copy link
Contributor

tgolen commented Jul 7, 2022 via email

@marcaaron
Copy link
Contributor Author

marcaaron commented Jul 7, 2022

Ah came across an edge case where we need to calculate the unreads in the client based on the deleted report actions 😄

When a user manually marks a comment as “unread” we will have to use the report actions to "optimistically determine" the unread count since we don’t know how many deleted comments are between the lastReadSequenceNumber and maxSequenceNumber. That might be fine though, because to manually mark something as read you must be in possession of all the relevant comments.

So I think that leaves us with:

Action Count Modified
Fetch initial report user starts with base count from Auth (deleted comments factored in)
New action appears from current user (report visible or not) reset count to 0
Current user opens report (mark as read) reset count to 0
New action appears from a different user (report visible) reset count to 0
New action appears from a different user (report not visible) count++ if sequenceNumber of new action > lastReadSequenceNumber
Report action deleted by another user count-- if sequenceNumber of deleted action > lastReadSequenceNumber
Report action deleted optimistically by current user count-- if sequenceNumber of deleted action > lastReadSequenceNumber
Report action failed to be deleted (rollback) count++ if sequenceNumber of deleted action > lastReadSequenceNumber
Historical report action marked as unread maxSequenceNumber - lastReadSequenceNumber - "deleted comments in range"

Not sure how to get around that last one...

cc @PauloGasparSv on this conversation too since I think they will run into this while refactoring the Edit / Delete comment stuff.

Kill reportMaxSequenceNumbers

Clean up some usages getUnreadActionCOunt

remove getLastReadSequenceNumber

Get rid of .then() calls in Report.js

Remove ambiguous `updateReportActionMessage` method

Remove last .then() in Report.js

Fix lastMessageText bug

Dont decrement count when handling deleted comment events from current user

undo random/bad change

Add Math.max()

Update names in ReportActionsView

Clear new marker when tapping floating message counter
@marcaaron marcaaron force-pushed the marcaaron-lastReadSequenceNumbers branch from ed52691 to e9e72f9 Compare July 7, 2022 23:39
@marcaaron marcaaron changed the title [WIP] Clean up lastReadSequenceNumbers and reportMaxSequenceNumbers Clean up lastReadSequenceNumbers and reportMaxSequenceNumbers Jul 7, 2022
@marcaaron
Copy link
Contributor Author

I still need to test this on other platforms besides web, but pretty happy with where this changes landed and everything is feeling more consistent and testing well. Going to open this up for some reviews now.

@marcaaron marcaaron marked this pull request as ready for review July 7, 2022 23:48
@marcaaron marcaaron requested a review from a team as a code owner July 7, 2022 23:48
@melvin-bot melvin-bot bot requested review from neil-marcellini and removed request for a team July 7, 2022 23:48
@marcaaron marcaaron requested a review from madmax330 July 7, 2022 23:48
@tgolen
Copy link
Contributor

tgolen commented Jul 8, 2022 via email

@marcaaron
Copy link
Contributor Author

Some of the stuff in that table is maybe a little bit off. For example, "New
action appears from a different user (report not visible)" mentions the
sequence number of "deleted" action. I think that's not quite right?

Nice catch, that should be "new" not "deleted". Updated. Thanks!

For that last use case (marking a comment as unread), it sounds very much
to me like exact same case as the first one (fetch initial report).

Yeah, they are pretty much the same except that when we are fetching the initial report the server is the one with the knowledge of any "deleted actions" and when we are marking a comment as "unread" it's the client that knows about them.

caveat: Does seem like some of this will be changing in the future as there was a discussion here about possibly just tracking whether a report is read or unread and not the exact number of "unread" messages it has.

Copy link
Contributor

@neil-marcellini neil-marcellini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few questions and comments, but other than that it looks really good! Thanks for cleaning this up a bit before the refactor.

src/libs/actions/Report.js Outdated Show resolved Hide resolved
src/libs/actions/Report.js Show resolved Hide resolved
src/libs/actions/Report.js Outdated Show resolved Hide resolved
src/libs/actions/Report.js Outdated Show resolved Hide resolved
src/libs/actions/Report.js Outdated Show resolved Hide resolved
neil-marcellini
neil-marcellini previously approved these changes Jul 8, 2022
Copy link
Contributor

@neil-marcellini neil-marcellini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh cool, moment().unix() does the job.

@marcaaron
Copy link
Contributor Author

Hey @neil-marcellini thanks for the review!

I ended up adding a test for this in a new branch and noticed some things that were off with my code so going to do one more update here (sorry).

Copy link
Contributor

@Luke9389 Luke9389 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few questions that will help me understand everything that's happening here.
They're pretty basic but necessary none the less.

src/libs/actions/Report.js Show resolved Hide resolved
src/libs/actions/Report.js Show resolved Hide resolved
@marcaaron
Copy link
Contributor Author

Ready for another review.

Copy link
Contributor

@neil-marcellini neil-marcellini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests are passing and the changes look good.

@marcaaron
Copy link
Contributor Author

Thanks @neil-marcellini! Gonna go for the merge to avoid conflicts 🙃.

Will continue to look into improvements to the unreadActionCount stuff in this Web-Expensify PR.

@marcaaron marcaaron merged commit 52c2b8b into main Jul 12, 2022
@marcaaron marcaaron deleted the marcaaron-lastReadSequenceNumbers branch July 12, 2022 02:05
@OSBotify
Copy link
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify
Copy link
Contributor

🚀 Deployed to staging by @marcaaron in version: 1.1.83-1 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

@OSBotify
Copy link
Contributor

🚀 Deployed to production by @chiragsalian in version: 1.1.84-13 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants