If the load result is contiguous with the already loaded items, we append
rather than replace.
background:
We have 4 load flavors:
- load older (scrolling up)
- load more recent (scrolling down after unload)
- load most recent (initial page load or scroll down button)
- load around (arbitrary jump from search results or tapping quoted reply)
Previously only "load earlier" and "load later" would append their results to
the existing loaded items, trimming if necessary.
"load most recent" and "load around" would not append, instead they'd replace
the existing loaded items, since the loaded items might not be contiguous with
the existing loaded items.
An optimization we have is that when given a load request, we compare to the
already-loaded items to determine which "unfetched" items from the request
actually need to be fetched.
The error: we consulted the already-loaded items for "load most recent" and
"load around" modes, which discard the previously-loaded items to avoid
introducing a discontinuity in case the fetched items are far away in message
history.
Pseudo code example:
// given these already loaded items
alreadyLoaded = [1, 2, 3, 4, 5]
// if we have a search result for message 5, we'll request to "load around" 5
requestLoadedAround(5) ->
// we'll generate a request set around 5
requestSet = (3..<8)
// The problem is here, when we remove already-loaded items
unfetched = requestSet - alreadyLoaded // == [6, 7, 8]
// Since "load around" replaced the loaded set, rather than appending to
// it, we inadverently lost some important items (3, 4, 5) from our
// request set.
alreadyLoaded = unfetched
A simple solution would be to not consider alreadyLoaded when replacing rather than appending -
for "load around" or "load most recent" but not for "load older" and "load more recent".
alreadyLoaded = [1, 2, 3, 4, 5]
requestLoadedAround(5) ->
requestSet = (3..<8)
// fetch everything rather than worry about removing the
// already-fetched-items
unfetched = requestSet
alreadyLoaded = unfetched
When we're making large discontiguous jumps in the conversation history this
behavior of replacing rather than appending is unavoidable, but when doing
short hops it's wasteful to lose the already loaded items.
So now, whether the load be via "load older", "load more recent", "load most
recent", or "load around" - whenever the fetched items are contiguous with the
already loaded items, we append rather than replace.