-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
#3293 update last message details on message deletion #3526
#3293 update last message details on message deletion #3526
Conversation
I'm sorry if I'm missing lots of the context behind why you did this a certain way, but why can't we just let the pusher event ( |
@Beamanator This particular MR and the linked issue are about deletion on sender's screen, and not on participants screens. There is an issue with deleting messages on other people screens which I have reported here: #3524 Or do you think that once that issue is resolved we will be able to move this whole logic into |
Actually, I agree. Since we are not doing an optimistic update here, there is no reason to do it the way I did it. However, I would assume down the line you would want every API action to have an optimistic update. This a quote from @NikkiWines from the original issue:
Not really sure if that implies, that down the line the behavior of Anyway, I do not mind moving my code to |
Yeah I believe you're right - for now I think we can go the simpler way as long as we still get the necessary fix we need 😅
Oof yeah good point, I've been seeing those weird |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of small comments
… reportAction variable names in one function
src/libs/actions/Report.js
Outdated
// Update last message information in the report object | ||
Onyx.connect({ | ||
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, | ||
callback: _.once((reportActionList) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry but the use of _.once
is very bad here. You are creating n number of subscriptions without releasing them. Where n === no of deleted comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry but _.once
is required there. If you remove _.once
and put console.log
inside that callback, you'll see that the callback is called 2-3 times per message delete call. Can you please explain what exactly is the big downside to this approach? Is it using extra memory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you can call Onyx.disconnect here after the operation is done. Otherwise, this subscription will remain, and On the next delete operation, both old ones and the new ones will be called. And I believe that this _.once will not be required then. But it is possible that while you are listening to this key, other factors update the Store, and thus this callback fire multiple times.
So yeah just Onyx.disconnect
will be fine. _.once
has not drawbacks just I was thinking that it won't be required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I'll check that out and update PR accordingly if that helps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That actually works flawlessly. Thanks.
PR is updated.
src/libs/actions/Report.js
Outdated
// Update last message information in the report object | ||
Onyx.connect({ | ||
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, | ||
callback: _.once((reportActionList) => { | ||
// Find last non-empty message |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to pitch in very late but this solution does not seem to follow the optimistic approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The decision to ditch optimistic approach is validated with Expensify engineers. The tl;dr is since the edit comment doesn't update last message optimistically, there is no reason the delete comment should.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/Expensify/Expensify.cash/blob/3c54c020bfab47a66f75d3dd8a8cc158b2337e42/src/libs/actions/Report.js#L1061-L1072
This is happening optimistically. In simpler words, we delete the comment from the Onyx even though we have not called the API yet. and then based on API response if there was a failure we revert it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sir, how is that code snippet you linked relevant to what I said?
the edit comment doesn't update last message optimistically
The code snippet you sent doesn't have anything to do with edit comment action or LHN.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, just saw a post from Nikki about this. It's fine then. But can't we do this before the API call. and revert those changes if the response is not 200?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we can. That's actually what I was going to do initially, but since Nikki said there is no need to do it optimistically, I happily abandoned that idea. Anyway I didn't want to think about any potential race conditions with both optimistic update and then revert update happening in async manner, deleting multiple comments in a quick succession, etc.
lastMessageDetails.lastActorEmail = ''; | ||
} | ||
|
||
Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, lastMessageDetails); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This statement causes a recursion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please explain how does it cause a recursion? Is there some specific edge case I didn't see. The code runs only once after the response from BE arrives.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh sorry didn't notice at first sight that this is a different subscription key.
lastMessageDetails.lastActorEmail = ''; | ||
} | ||
|
||
Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, lastMessageDetails); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please release the connection here before this statement. And remove _.once
. Could you please try to think of your solution in an optimistic way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am aware this is not the best approach. As I stated in one of the messages above, ideally we move this entire code to updateReportActionMessage
function and have the handling for delete action next to edit action. However, until #3524 is resolved this cannot be done for delete action.
Hello, @NikkiWines. Pinging you just in case you forgot about this PR. There has been no activity from Expensify team members here for more than 5 days now. Please let me know if this is blocked because of some other PR and if I need to do any more changes. Thanks. |
hi @dklymenk, apologies for the delay on our end. Just so you're aware, it looks like #3524 has been resolved, so I'm not sure if you'd like to make additional modifications based on that. Additionally, I would recommend posting to #expensify-open-source (as recommended here) regarding the usage of |
…n-message-deletion
Hello
Actually, thanks to a suggestion by @parasharrajat, there is no more
A change that I would have made here is taking all the code this PR adds to This means that if you delete last message and then edit the next last message, the LHN is not updated because you are editing a message that does not have So, I suggest we merge this PR as is. There is no bugs and it doesn't do anything sub-optimal. I, however, think that moving that code to |
@NikkiWines I have created a new issue #3743 for |
Thanks for the update @dklymenk, that sounds like a good plan. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works well, @Beamanator final review is all yours
const connectionID = Onyx.connect({ | ||
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, | ||
callback: (reportActionList) => { | ||
// To make sure the callback is only called once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB: // Disconnect to ensure the callback is only called once
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I'm getting some pretty unexpected behavior while testing on Web, are either of you getting this?
My first test was:
- Send a new message. Notice LHN updates correctly
- Refresh the page, LHN shows the previous message (not good!)
- Refresh again, the LHN now shows the latest message correctly
The second test:
- Deleting a message I just sent shows the phone number in the LHN (bad)
- Deleting a previous message shows the first message I deleted (bad)
Screen.Recording.2021-06-25.at.1.02.49.PM.mov
I have merged main into this branch yesterday to test how the // If this is the most recent message, update the lastMessageText in the report object as well
if (sequenceNumber === reportMaxSequenceNumbers[reportID]) {
Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {
lastMessageText: message.html,
});
} There a lot wrong with this function now and it is a cause of multiple issues at this point. That's why I created issue #3743 with a proposal for it's refactor, that should solve everything. I didn't realize at the time that #3524 broke this PR, so I think it would be better for me to first implement the proposal for #3743, and then update this PR accordingly. What do you think? As for your first test, I would assume it caused by some some code interruption issue, where you see an old version of localstorage because new one didn't persist because you've refreshed the page too fast. I actually cannot reproduce that one. The timing must be very precise by the looks of it. |
I will move the PR state to draft. Good thing I have merged main into this branch and you have noticed the new issues now and not after merge. |
@dklymenk does this still need to be open? |
@NikkiWines sorry, I have completely forgot about this one. Closed. |
Details
Fixes incorrect display of last message on LHN after deleting last message of the chat.
Fixed Issues
Fixes #3293
Tests/QA Steps
Tested On
Screenshots
Web
screen.mp4
Mobile Web
screen1.mp4
Desktop
Screen.Recording.2021-06-10.at.18.24.04.mov
iOS
Simulator.Screen.Recording.-.iPhone.12.-.2021-06-10.at.18.20.53.mp4
Android
3293.mp4