feat: surface offset fallback browse behavior

This commit is contained in:
Jonathan Finley 2026-03-13 23:32:05 -04:00
parent f1fe40c3c7
commit 93aa854855
2 changed files with 46 additions and 0 deletions

View file

@ -51,6 +51,9 @@ export default {
routeFullPath: null, routeFullPath: null,
initialized: false, initialized: false,
paginationMode: 'offset', paginationMode: 'offset',
deepScrollAllowed: true,
deepScrollBlocked: false,
maxOffsetPages: Infinity,
nextCursor: null, nextCursor: null,
isCountDeferred: false, isCountDeferred: false,
pageCursors: {}, pageCursors: {},
@ -338,6 +341,9 @@ export default {
}, },
resetPaginationState() { resetPaginationState() {
this.paginationMode = 'offset' this.paginationMode = 'offset'
this.deepScrollAllowed = true
this.deepScrollBlocked = false
this.maxOffsetPages = Infinity
this.nextCursor = null this.nextCursor = null
this.isCountDeferred = false this.isCountDeferred = false
this.pageCursors = { 0: null } this.pageCursors = { 0: null }
@ -387,6 +393,9 @@ export default {
} }
this.paginationMode = payload.paginationMode || this.paginationMode this.paginationMode = payload.paginationMode || this.paginationMode
this.deepScrollAllowed = payload.deepScrollAllowed !== false
this.deepScrollBlocked = this.paginationMode === 'offset' && !this.deepScrollAllowed
this.maxOffsetPages = this.deepScrollBlocked ? 3 : Infinity
this.nextCursor = payload.nextCursor || null this.nextCursor = payload.nextCursor || null
this.isCountDeferred = !!payload.isCountDeferred this.isCountDeferred = !!payload.isCountDeferred
@ -426,6 +435,10 @@ export default {
} }
}, },
loadPage(page) { loadPage(page) {
if (this.deepScrollBlocked && page >= this.maxOffsetPages) {
return Promise.resolve()
}
if (this.pagesLoaded[page]) return this.pagesLoaded[page] if (this.pagesLoaded[page]) return this.pagesLoaded[page]
if (this.paginationMode === 'keyset' && page > 0) { if (this.paginationMode === 'keyset' && page > 0) {

View file

@ -165,4 +165,37 @@ describe('LazyBookshelf', () => {
}) })
}) })
}) })
it('keeps offset fallback mode explicit and caps deep endless scroll', () => {
const requestUrls = []
const getStub = cy.stub().callsFake((url) => {
requestUrls.push(url)
return Promise.resolve({
results: [{ id: `item-${requestUrls.length}`, mediaType: 'book', media: { metadata: { title: `Item ${requestUrls.length}` } } }],
total: 10,
nextCursor: null,
paginationMode: 'offset',
deepScrollAllowed: false
})
})
mountBookshelf(getStub).then(({ wrapper }) => {
cy.wrap(null)
.then(() => wrapper.vm.loadPage(1))
.then(() => wrapper.vm.loadPage(2))
.then(() => wrapper.vm.loadPage(3))
.then(() => {
expect(wrapper.vm.paginationMode).to.equal('offset')
expect(wrapper.vm.deepScrollBlocked).to.equal(true)
expect(wrapper.vm.maxOffsetPages).to.equal(3)
expect(requestUrls).to.have.length(3)
expect(requestUrls.some((url) => url.includes('page=0'))).to.equal(true)
expect(requestUrls.some((url) => url.includes('page=1'))).to.equal(true)
expect(requestUrls.some((url) => url.includes('page=2'))).to.equal(true)
expect(requestUrls.some((url) => url.includes('page=3'))).to.equal(false)
expect(requestUrls.every((url) => !url.includes('cursor='))).to.equal(true)
})
})
})
}) })