Problem
- Genz Updates could still return 403/Cloudflare in extension requests even when the same site worked in WebView.
- The extension HTTP path primarily used cached cookies from settings instead of reliably using the current WebView cookie jar.
- Cloudflare challenge detection was too narrow (mostly English markers) and could misclassify localized challenge pages as resolved.
Solution
- Prefer live WebView cookies for outgoing extension HTTP requests, with settings cookies as fallback.
- Sync cookie + user-agent from embedded WebView on onLoadStop in addition to history updates.
- Expand challenge detection with additional multilingual and platform markers.
Implementation Details
- Updated `MCookieManager.interceptRequest` to read cookies from `CookieManager.getCookies()` and use them as the request `Cookie` header when available.
- Added `_syncCookieAndUaFromWebView()` in `MangaWebView` and invoked it from both `onLoadStop` and `onUpdateVisitedHistory` to persist fresh clearance cookies immediately.
- Introduced a centralized `_cloudflareChallengePattern` in `m_client.dart` and reused it in `_containsCloudflareChallengeHtml` and `_isCloudflareChallengePage` for consistent challenge detection.
- 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
This commit improves memory management, reduces redundant interpreter
instantiation, and standardizes service usage patterns.
- Add `dispose()` to `ExtensionService` interface and implement it across
Dart, JS, LNReader, and Mihon services.
- Replace repeated interpreter creation in `DartExtensionService` with a
persistent `_interpreter` instance initialized once in the constructor.
- Add disposal logic for JS DOM selector and Cheerio instances to prevent
memory leaks.
- Introduce `withExtensionService()` helper to ensure services are always
disposed after use.
- Update call sites across the codebase to use `withExtensionService()`
or manual try/finally disposal.
- Improve isolate service message handling by extracting `responsePort`
earlier.
- Ensure safer defaults (e.g., returning empty lists, const lists) when
service calls fail.
- Add StreamSubscription to manage ReceivePort listener lifecycle
- Introduce handshake timeout when waiting for isolate SendPort to prevent hangs
- Add response timeout in get<T>() to avoid indefinitely waiting for isolate replies
- Replace direct ReceivePort.listen with tracked subscription for safer cleanup
- Improve error handling for invalid or missing isolate responses
- Strengthen isolate startup reliability and shutdown consistency
- Use the logger to log failed updates
- After the update-botToast another botToast is being spawned to show exactly which manga(s) couldn't be updated.
- Remove the doWhile loop because it is unnecessary. The condition of mangaList.length == numbers is always true, meaning it only runs once.
- Removed the NovelAutoScrollState provider and its associated logic.
- Introduced autoScrollValues and setAutoScroll methods in NovelReaderController to manage auto-scroll settings.
- Updated NovelReaderView to handle auto-scroll state and page offset dynamically.
- Added UI elements in GeneralSettingsTab to control auto-scroll settings with a slider for page offset.
- Enhanced the auto-scroll feature to allow for play/pause functionality within the novel reader view.