feat(media): pagination

This commit is contained in:
Florian Sylvain committed 2026-10-13 19:54:59 +02:00
1 parent 04dc151ed7
commit 63c1e7076e
65 files changed
+2960 -365

No files matched your search

@@ -115,11 +115,11 @@ describe('The library has images, so Library opens', () => {
expect(skeletonTiles()).toHaveLength(9)
})
it('asks for 24 images and nothing else', async () => {
it('asks for the first page of 25 images and nothing else', async () => {
await openLibrary()
expect(listCalls()).toHaveLength(1)
expect(listCalls()[0]!.toString()).toBe('limit=24')
expect(listCalls()[0]!.toString()).toBe('page=1&size=25')
})
})
@@ -197,7 +197,7 @@ describe('A search is active, so the count is not shown', () => {
})
describe('Load more is hidden on the last page', () => {
it('does not show "Load more" without a cursor', async () => {
it('does not show "Load more" once every matching image is loaded', async () => {
await openLibrary({ list: () => pageBody(fixture(), null) })
expect(findButton('Load more')).toBeUndefined()
@@ -373,7 +373,7 @@ describe('Insert', () => {
})
describe('Search', () => {
it('searches after a 120 ms debounce, with no cursor, and clears the selection', async () => {
it('searches after a 120 ms debounce, on page 1, and clears the selection', async () => {
await openWithFakeTimers()
tile('kitchen-after.webp').click()
await vi.advanceTimersByTimeAsync(0)
@@ -388,8 +388,8 @@ describe('Search', () => {
expect(listCalls()).toHaveLength(2)
expect(listCalls()[1]!.get('q')).toBe('wall')
expect(listCalls()[1]!.get('limit')).toBe('24')
expect(listCalls()[1]!.has('cursor')).toBe(false)
expect(listCalls()[1]!.get('size')).toBe('25')
expect(listCalls()[1]!.get('page')).toBe('1')
expect(findButton('Insert image')?.disabled).toBe(true)
})
@@ -419,7 +419,7 @@ describe('Search', () => {
expect(searchField().value).toBe('')
const last = listCalls().at(-1)!
expect(last.has('q')).toBe(false)
expect(last.get('limit')).toBe('24')
expect(last.get('size')).toBe('25')
})
it('shows the no results panel and "Clear search" empties the field', async () => {
@@ -447,7 +447,7 @@ describe('Load more', () => {
it('shows progress, appends the new tiles and moves focus to the first one', async () => {
const more = deferred<unknown>()
await openWithFakeTimers({
list: (query) => (query.get('cursor') ? more.promise : pageBody()),
list: (query) => (query.get('page') === '2' ? more.promise : pageBody()),
})
const button = findButton('Load more')!
button.focus()
@@ -456,8 +456,8 @@ describe('Load more', () => {
await vi.advanceTimersByTimeAsync(0)
const last = listCalls().at(-1)!
expect(last.get('cursor')).toBe('c24')
expect(last.get('limit')).toBe('24')
expect(last.get('page')).toBe('2')
expect(last.get('size')).toBe('25')
const loading = findButton('Loading…')!
expect(loading.getAttribute('aria-disabled')).toBe('true')
expect(document.activeElement).toBe(loading)
@@ -475,7 +475,10 @@ describe('Load more', () => {
it('draws a row of 3 skeleton tiles on mobile', async () => {
await openWithFakeTimers(
{ list: (query) => (query.get('cursor') ? new Promise(() => undefined) : pageBody()) },
{
list: (query) =>
query.get('page') === '2' ? new Promise(() => undefined) : pageBody(),
},
MOBILE_WIDTH,
)
@@ -485,9 +488,9 @@ describe('Load more', () => {
expect(skeletonTiles()).toHaveLength(3)
})
it('combines the cursor with the search', async () => {
it('combines the next page with the search', async () => {
await openLibrary({
list: (query) => pageBody(query.get('q') ? fixture([1, 2]) : fixture(), 'c24'),
list: (query) => pageBody(query.get('q') ? fixture([1, 2]) : fixture(), 48),
})
await searchFor('wall')
@@ -495,8 +498,8 @@ describe('Load more', () => {
const last = listCalls().at(-1)!
expect(last.get('q')).toBe('wall')
expect(last.get('limit')).toBe('24')
expect(last.get('cursor')).toBe('c24')
expect(last.get('size')).toBe('25')
expect(last.get('page')).toBe('2')
})
})