fix: Ensure actions happen against the correct status #373
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Previously when the user interacted with a status the operation (reblog, favourite, etc) travels through multiple layers of code, carrying with it the position of the item in the list that the user operated on.
At some point the status is retrieved from the list using its position so that the correct status ID can be used in the network operation.
If this happens while the list is also refreshing there's a possible race condition, and the original status' position may have changed in the list. Looking up the status by position to determine which status to perform the action on may cause the action to happen on the wrong status.
Fix this by passing the status' viewdata to any actions instead of its position. This includes all the information necessary to make the API call, so there is no chance of a race.
This is quite an involved change because there are three types of viewdata:
StatusViewData
, used for regular timelinesNotificationViewData
, used for notifications, may wrap a status that can be operated onConversationViewData
, used for conversations, does wrap a statusThe previous code treated them all differently, which is probably why it operated by position instead of type.
The high level fix is to:
Create an interface,
IStatusViewData
, that contains the data exposed by any viewdata that contains a status.Implement the interface in
StatusViewData
,NotificationViewData
, andConversationViewData
.Change the code that operates on viewdata (
SFragment
,StatusActionListener
, etc) to be generic over anything that implementsIStatusViewData
.Change the code that handles actions to pass the viewdata instead of the position.
Fixes #370