By extracting:
```
SystemChrome.setEnabledSystemUIMode(
SystemUiMode.manual,
overlays: SystemUiOverlay.values,
);
```
to a file `system_ui.dart` and calling the method `restoreSystemUI()`
The horizontal layout (_buildHorizontalLayout) used FittedBox as a
shared scaffold for both vertical and horizontal reading modes.
FittedBox passes unbounded width constraints to its child, which caused
RenderFlex to throw "children have non-zero flex but incoming width
constraints are unbounded" when Row + Expanded children were used.
This cascaded into a chain of "RenderBox was not laid out" assertions
all the way up through IntrinsicHeight, ConstrainedBox, FittedBox,
LayoutBuilder, and into the ScrollablePositionedList in
image_view_webtoon.dart.
Fix: split the two layout paths before they reach a scaffold widget.
The vertical path keeps FittedBox (safe, maxWidth is capped at 480px).
The horizontal path uses SizedBox(width: MediaQuery screenWidth) so
Row/Expanded always receive a finite width constraint.
Fix an Exception:
```
════════ Exception caught by rendering library ═════════════════════════════════
A RenderFlex overflowed by 274 pixels on the bottom.
The relevant error-causing widget was:
Column Column:file:///lib/modules/manga/reader/widgets/chapter_transition_page.dart:28:18
════════════════════════════════════════════════════════════════════════════════
```
Improved: The UI adapts to the reading mode now
MangasListState previously stored selected manga IDs as List<int>.
Every visible library card called .contains() on that list once per
rebuild to determine its highlight state, making each check O(n) in
the number of selected items. The provider's own update/selectAll/
selectSome methods also used .contains() and .remove() on a List.
Change the state type to Set<int> throughout, making all membership
checks O(1). Updated all consumers: library_gridview_widget,
library_listview_widget, library_app_bar, library_dialogs, and
MangasSetIsReadState.
call `_processCropBorders()` once, from _initCurrentIndex and after new pages arrive.
Also make _processCropBorders idempotent by the existing _cropBorderCheckList guard
fix for the "jump back" bug that occurred when scrolling up in vertical continuous and webtoon reader modes.
- `ChapterPreloadManager` was maintaining its own `_currentIndex`.
- When prepending previous chapter pages, the index was being incremented
twice (once in the manager + once in `_handlePrevChapterPrepended`).
- This caused `itemScrollController.jumpTo()` to overshoot, resulting in
a visible jump forward (perceived as "jump back" while trying to scroll up).
- Removed all index management (`_currentIndex`, getter, setter, startIndex)
from `ChapterPreloadManager` and `ReaderMemoryManagement`.
- `ChapterPreloadManager` is now a pure data container (only manages `_pages`).
- `_handlePrevChapterPrepended` now captures the **current visible top index**
*before* prepending and adjusts the scroll position only once.
- `_readProgressListener` is now the single source of truth for `_currentIndex`.
- Removed stale `initialScrollIndex` logic from preload initialization.
Introduce a unique `ValueKey` for each page (chapter ID + page index) and wrap items in `KeyedSubtree`. This ensures Flutter can correctly preserve widget identity when the preload manager inserts or prepends pages.
Previously, every `setState` triggered by page preloading caused the entire list to rebuild, leading to visible lag. With stable keys, only newly added pages rebuild while existing ones retain their state.
This significantly reduces jank, improves scroll smoothness, and makes chapter transitions nearly seamless.
`ChapterPreloadManager.preloadPrevChapter` does `_currentIndex += prependCount` (internal manager index).
Then `_handlePrevChapterPrepended` in `reader_view.dart` does the exact same thing again to the UI’s `_currentIndex` before calling `jumpTo`.
The UI state already handles the adjustment + `jumpTo` correctly.
The manager’s internal `_currentIndex` is not needed for continuous mode (the `ItemPositionsListener` overrides it anyway).
- prevent stale settings overwrites by reloading settings inside Isar write txn before updating chapterPageUrlsList
- guard getPageLength() against missing chapter entries and empty urls to avoid No element crashes
- simplify read-threshold calculation in setPageIndex() via totalPages/pagesRemaining for continuous and paged modes
- map visible continuous double-page indices to actual page indices in _readProgressListener before persisting progress
- snapshot item positions and clamp indices during fast scrolling to avoid volatile first/last access races
- Added new localization strings for total, mean per title, completion rate, watching time, reading time, average chapters per title, read percentage, and entries in multiple languages.
- Enhanced the History model to include readingTimeSeconds.
- Updated AnimeStreamController and ReaderController to track reading time and save it to history.
- Implemented reading time tracking in Anime and Novel reader views.
- Introduced statistics calculations for total reading time across histories.
- Updated statistics screen to display total reading time and average reading time per title.