Swiping past the 50th item fetches the next ones (#383)

The item list is fetched 50 at a time, and only the list's Load more
button asked for more. A swipe or j stops at the last item loaded, so
after 50 items the reader bounced on every swipe until a reload brought
a fresh page of unread ones.

Turning to within five of the end now fetches the next page behind. Its
offset counts what is still unread on the Unread tab: the items read
here have left the server's unread list, and Load more's flat 50 a page
skipped as many unread items as had been read. A refresh (a return from
the background, a live update) always asks for the first page, as the
kept list it fills is one, where it used to ask for whatever page Load
more had last reached. A page appended after new items arrived no longer
repeats ones already loaded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-04 20:36:45 +00:00
parent c8cbb3047a
commit 385589ff77
3 changed files with 32 additions and 4 deletions

View File

@@ -262,3 +262,14 @@ test('a tap ended over a minute after its last request reports once, without rec
run('endTap()');
assert.equal(run(`sent.filter(([u, o]) => JSON.parse(o.body).ev === 'tap').length`), 1);
});
test('the next page starts after the unread ones on the Unread tab, after all of them elsewhere', () => {
run(`S.entries = [{guid:'a',read:true},{guid:'b',read:false},{guid:'c',read:true}]; S.total = 3`);
run(`S.filter = 'unread'`);
// Two read here are off the server's unread list: starting at 3 would skip two unread ones (#383).
assert.equal(run('nextOffset()'), 1);
assert.equal(run('hasMore()'), true);
run(`S.filter = 'all'`);
assert.equal(run('nextOffset()'), 3);
assert.equal(run('hasMore()'), false);
});