fix(reader): keep oversized comic pages within scroll bounds

Use safe flex alignment so pages stay centered when they fit and fall back to the scroll origin when they overflow.

Closes #1610
This commit is contained in:
neon
2026-09-30 19:35:10 +00:00
parent 951f3b702d
commit 85927fb118
2 changed files with 25 additions and 3 deletions
@@ -202,11 +202,33 @@ describe('CbzReaderView', () => {
expect(wrapper.get('[data-testid="cbz-paginated-pages"]').attributes('style')).toContain(`column-gap: ${spreadGap}px`)
expect(wrapper.get('[data-spread-side="left"]').classes()).toContain('justify-end')
expect(wrapper.get('[data-spread-side="right"]').classes()).toContain('justify-start')
expect(wrapper.get('[data-spread-side="left"]').classes()).toContain('items-center-safe')
expect(wrapper.get('[data-spread-side="right"]').classes()).toContain('items-center-safe')
expect(wrapper.findAll('[data-spread-side] img')).toHaveLength(2)
wrapper.unmount()
})
it('safely centers a paginated page without putting oversized content before the scroll origin', async () => {
mocks.savedMode = 'paginated'
mocks.savedViewMode = 'single'
mocks.pageCount = 6
mocks.savedPageNumber = 2
const wrapper = shallowMount(CbzReaderView, {
props: { bookId: 11, fileId: 22 },
})
await flushPromises()
await nextTick()
const pages = wrapper.get('[data-testid="cbz-paginated-pages"]')
expect(pages.classes()).toContain('items-center-safe')
expect(pages.classes()).toContain('justify-center-safe')
wrapper.unmount()
})
it('routes settings panel updates and reset through the per-book settings store', async () => {
mocks.savedMode = 'paginated'
const wrapper = shallowMount(CbzReaderView, {
@@ -920,11 +920,11 @@ onUnmounted(() => {
<div class="flex min-h-full min-w-full items-center justify-center" :style="paginatedStageStyle">
<div
data-testid="cbz-paginated-pages"
class="flex shrink-0 items-center justify-center px-1 origin-center"
class="flex shrink-0 items-center-safe justify-center-safe px-1 origin-center"
:style="[paginatedContentStyle, renderSpread ? spreadContainerStyle : undefined]"
>
<template v-if="renderSpread">
<div data-spread-side="left" class="flex h-full min-w-0 flex-1 items-center justify-end">
<div data-spread-side="left" class="flex h-full min-w-0 flex-1 items-center-safe justify-end">
<img
v-if="renderLeftPage !== null"
:src="pageUrl(renderLeftPage)"
@@ -936,7 +936,7 @@ onUnmounted(() => {
/>
<div v-else aria-hidden="true" class="h-[92%] w-[92%] rounded-sm border border-border/60 bg-background/30" />
</div>
<div data-spread-side="right" class="flex h-full min-w-0 flex-1 items-center justify-start">
<div data-spread-side="right" class="flex h-full min-w-0 flex-1 items-center-safe justify-start">
<img
v-if="renderRightPage !== null"
:src="pageUrl(renderRightPage)"