forked from cybrespace/mastodon
Fix older items possibly disappearing on timeline updates (#17980)
In some rare cases, when receiving statuses out of order from the streaming API then polling from the REST API, it was possible for the `expandNormalizedTimeline` function to remove older items from the timeline. This commit ensures that any item from the replaced slice that is older than the oldest item retrieved from the API gets added back to the replaced slice.
This commit is contained in:
parent
f382192862
commit
1b91359a45
|
@ -66,13 +66,22 @@ const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, is
|
||||||
|
|
||||||
// Then, try to find the furthest (if properly sorted, oldest) item in the timeline that
|
// Then, try to find the furthest (if properly sorted, oldest) item in the timeline that
|
||||||
// is newer than the most recent fetched one, as it delimits a section comprised of only
|
// is newer than the most recent fetched one, as it delimits a section comprised of only
|
||||||
// items present in `newIds` (or that were deleted from the server, so should be removed
|
// items older or within `newIds` (or that were deleted from the server, so should be removed
|
||||||
// anyway).
|
// anyway).
|
||||||
// Stop the gap *after* that item.
|
// Stop the gap *after* that item.
|
||||||
const firstIndex = oldIds.take(lastIndex).findLastIndex(id => id !== null && compareId(id, newIds.first()) > 0) + 1;
|
const firstIndex = oldIds.take(lastIndex).findLastIndex(id => id !== null && compareId(id, newIds.first()) > 0) + 1;
|
||||||
|
|
||||||
// Make sure we aren't inserting duplicates
|
let insertedIds = ImmutableOrderedSet(newIds).withMutations(insertedIds => {
|
||||||
let insertedIds = ImmutableOrderedSet(newIds).subtract(oldIds.take(firstIndex), oldIds.skip(lastIndex)).toList();
|
// It is possible, though unlikely, that the slice we are replacing contains items older
|
||||||
|
// than the elements we got from the API. Get them and add them back at the back of the
|
||||||
|
// slice.
|
||||||
|
const olderIds = oldIds.slice(firstIndex, lastIndex).filter(id => id !== null && compareId(id, newIds.last()) < 0);
|
||||||
|
insertedIds.union(olderIds);
|
||||||
|
|
||||||
|
// Make sure we aren't inserting duplicates
|
||||||
|
insertedIds.subtract(oldIds.take(firstIndex), oldIds.skip(lastIndex));
|
||||||
|
}).toList();
|
||||||
|
|
||||||
// Finally, insert a gap marker if the data is marked as partial by the server
|
// Finally, insert a gap marker if the data is marked as partial by the server
|
||||||
if (isPartial && (firstIndex === 0 || oldIds.get(firstIndex - 1) !== null)) {
|
if (isPartial && (firstIndex === 0 || oldIds.get(firstIndex - 1) !== null)) {
|
||||||
insertedIds = insertedIds.unshift(null);
|
insertedIds = insertedIds.unshift(null);
|
||||||
|
|
Loading…
Reference in New Issue