diff --git a/client/components/app/LazyBookshelf.vue b/client/components/app/LazyBookshelf.vue index 76fba3016..f224cd0ee 100644 --- a/client/components/app/LazyBookshelf.vue +++ b/client/components/app/LazyBookshelf.vue @@ -51,6 +51,9 @@ export default { routeFullPath: null, initialized: false, paginationMode: 'offset', + deepScrollAllowed: true, + deepScrollBlocked: false, + maxOffsetPages: Infinity, nextCursor: null, isCountDeferred: false, pageCursors: {}, @@ -338,6 +341,9 @@ export default { }, resetPaginationState() { this.paginationMode = 'offset' + this.deepScrollAllowed = true + this.deepScrollBlocked = false + this.maxOffsetPages = Infinity this.nextCursor = null this.isCountDeferred = false this.pageCursors = { 0: null } @@ -387,6 +393,9 @@ export default { } 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.isCountDeferred = !!payload.isCountDeferred @@ -426,6 +435,10 @@ export default { } }, loadPage(page) { + if (this.deepScrollBlocked && page >= this.maxOffsetPages) { + return Promise.resolve() + } + if (this.pagesLoaded[page]) return this.pagesLoaded[page] if (this.paginationMode === 'keyset' && page > 0) { diff --git a/client/cypress/tests/components/app/LazyBookshelf.cy.js b/client/cypress/tests/components/app/LazyBookshelf.cy.js index cf699faf5..15d1ce777 100644 --- a/client/cypress/tests/components/app/LazyBookshelf.cy.js +++ b/client/cypress/tests/components/app/LazyBookshelf.cy.js @@ -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) + }) + }) + }) })