You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(reader): use stable page IDs instead of indices for preloading (#654)
## Problem
When the DIVINA reader opens a book that belongs to a multi-segment
series, `preloadNextSegmentIfNeeded` may prepend the previous book's
pages to the `readerPages` array. This shifts all page indices, causing
background preload tasks that captured raw indices to load pages from
the wrong book. The cleanup pass then evicts the correctly-loaded
visible pages, leaving the UI stuck on a loading spinner — most
noticeable in dual-page and cover modes.
## Approach
Replace every external index-based preload path with stable
`ReaderPageID` lookups that resolve the index at call time, so stale
captures are impossible. Additionally, track the set of currently
visible page IDs in the scheduler so cleanup never evicts pages the user
is looking at.
For CoverPageView (pure SwiftUI → `PageScrollView` UIViewRepresentable),
images were loaded but the UI never refreshed because the image cache
lives outside `@Observable`. Fixed by having `PageScrollView`'s
Coordinator register a `pagePresentationInvalidationObserver` — the same
pattern the scroll reader already uses via
`NativePagedPagePresentationCoordinator`.
## Scope
- **ReaderPageLoadScheduler**: merge `preloadImageForPage(at:)` into
`preloadImage(for:)` as single entry point; simplify `preloadPages` from
task-group to sequential loop (tasks were serialising on MainActor
anyway); add `visiblePageIDs` protection in cleanup; remove dead
`setPreloadedImage(forPageIndex:)` overload
- **ReaderViewModel**: remove public `preloadImageForPage(at:)` wrapper
- **ScrollPageView (iOS/macOS)**: switch `preloadVisiblePages` from
index-based to pageID-based loading
- **CoverPageView**: make `preloadPresentationWindow` async with
`prioritizeVisiblePageLoads`; collapse redundant guard block
- **NativeImagePageViewController**: use `preloadImage(for:)` instead of
capturing stale index
- **PageScrollView (iOS/macOS)**: register presentation invalidation
observer for automatic UIKit refresh
0 commit comments