Skip to content

Allow reader Retry after image decode failures - #3770

Open
rodrigdoliveira wants to merge 4 commits into
mihonapp:mainfrom
rodrigdoliveira:agent/retry-reader-decode-failure
Open

rodrigdoliveira wants to merge 4 commits into
mihonapp:mainfrom
rodrigdoliveira:agent/retry-reader-decode-failure

Conversation

@rodrigdoliveira

@rodrigdoliveira rodrigdoliveira commented Aug 15, 2026 •

Copy link
Copy Markdown

Summary

A page can download successfully and remain in Page.State.Ready even after its image fails to decode. Pressing Retry currently queues the page without changing that state, so the loader's Queue filter skips the request.

This change always sets the selected page to Page.State.Queue before enqueueing an explicit Retry. The existing retry priority still forces a fresh download, including when the failed image is cached.

Validation

Checked locally on October 8, 2026, with Mihon main at ab7ee00c48ba1d514ecf73bfeb1e35e1faf23fa3 merged into this branch:

  • ./gradlew spotlessCheck — passed.
  • ./gradlew :app:testDebugUnitTest — all 7 tests passed.
  • The focused regression test starts with a ready page, presses Retry, and verifies a new image request to the source.

Upstream CI currently requires maintainer approval before the workflow can run.

@rodrigdoliveira
rodrigdoliveira marked this pull request as ready for review August 15, 2026 13:53
unseensnick added a commit to unseensnick/Reikai that referenced this pull request Sep 15, 2026
A manga chapter picked from the reader's chapter list or reached with
the next and previous buttons now raises the failed-load dialog with
Retry, as a novel chapter does, instead of failing silently.

- The engine's wait on a pick ends on the failure, so the reader no
  longer jumps to the chapter once it finally loads
- Retry re-opens the chapter that failed, as a pick when it was one,
  so it still lands where that chapter resumes
- A relaunch naming the chapter the reader opened with is honoured
  after reading on, since the test is now the chapter on screen
- Retrying a failed page always re-queues it, from mihonapp/mihon#3770

A neighbour failing to preload keeps upstream's transition page retry.
Tests: provider, engine, intent and loader, each mutation-checked. The
ViewModel wiring has no harness; the offline dialog is owed a device
check.
unseensnick added a commit to unseensnick/Reikai that referenced this pull request Oct 1, 2026
With the high quality renderer on, a manga page now draws while it
downloads instead of waiting behind a progress ring, and a Retry after
a failed page fills in the same way. Ported from mihonapp/mihon#4023.

Reader:
- Pages decode as their bytes arrive: the loader feeds a DownloadStream
  that the viewer decodes from, and the whole-file decode takes over
  when streaming cannot.
- Retry goes through upstream's download path, keeping the forced
  refetch of mihonapp/mihon#3770, so the refetch renders progressively
  and a page turn can drop it like any other download.
- An error page that replaces a streaming preview drops the preview,
  and a stale wrapper the page-identity island removes takes its load
  and watch jobs with it.
- The cover dialog holds the decoded frame around its upload, for manga
  and novels alike, through the shared EntryCoverDialog.

Under the hood:
- Verbatim: ImageUtil, data/coil/ImageDecoder, ReaderPage and the new
  DownloadStream. Three-way merged: WebGpuViewer, ChapterCache and
  HttpPageLoader, every RK island kept; the drift against upstream is
  RK-attributable only.
- Catalog: image-decoder 15 (libvips removed), SSIV 1b283e2bc4,
  webgpuviewer 49.
- Off-path: MangaCoverDialog (manifested) reconciled into
  EntryCoverDialog.
- The new rules live in WebGpuRetryRules.kt and WebGpuPageCache.kt;
  the content-layer Reader row describes the adapted islands, and the
  RK count under ui/reader/viewer stays 57.
- Novels have no half by mechanism: novel pictures load through Coil
  in NovelImageGetter, never through a PageLoader.

Tests: requeueForRetry, previewAfterError and cancelPageJobs, each seen
red on a stub and under a per-clause mutation.
@rodrigdoliveira

Copy link
Copy Markdown
Author

Updated this branch to current main (ab7ee00c4) and checked the newer reader code. The ready-page decode-failure case is still present: the error UI does not change the page's Ready state, while retryPage() only requeues Error pages.

Fresh local validation passed: spotlessCheck and all 7 app unit tests, including the ready-page Retry regression test. The diff remains limited to the loader fix and its test.

Could a maintainer review this and approve the pending CI workflow? Thanks!

@AntsyLich

Copy link
Copy Markdown
Member

drop the test class and rebase again

@rodrigdoliveira
rodrigdoliveira force-pushed the agent/retry-reader-decode-failure branch from 759c4a2 to 265dbcc Compare October 11, 2026 22:15
unseensnick added a commit to unseensnick/Reikai that referenced this pull request Oct 12, 2026
Manga chapters from a source now load several pages at once, and on
Wi-Fi the whole chapter and then the next one, from upstream's rewritten
page loader (mihonapp/mihon#2986). A new Load ahead only on Wi-Fi switch,
on by default, keeps mobile data to the pages near the one being read.

Reader:
- HttpPageLoader taken verbatim, with one RK change: off Wi-Fi it loads
  the user's Pages to load ahead off Wi-Fi (the old Pages to preload,
  clamped to ReaderRanges.preloadPages) where upstream fixes 4
- The row moves beside the new switch on Settings -> Manga reader and
  shows only while the switch is on, since otherwise the whole chapter
  loads
- ReaderViewModel preloads the next chapter once the current one has
  loaded, through preload, so ChapterRetryCooldown and the userAsked
  Retry path still apply; the call sits after the overtaken page-switch
  check so a stale switch cannot cancel the live chapter's preload
- canLoadAhead reaches every source of a merged series through
  MergedChapterLoader
- The mihonapp/mihon#3770 retryPage island and its divergence row are
  deleted: upstream's new retryPage cancels any load in flight and forces
  a fresh one whatever the page's state, which covers that case

Novels: owner ruling, the novel reader keeps warming its neighbours on
open whatever the network, since one chapter is a single text request,
already the size of the limited manga window. Recorded in reader.md
Decisions and the SettingsMangaReaderScreen KDoc.

Under the hood:
- Off-path: SettingsReaderScreen's upstream row reconciled into
  SettingsMangaReaderScreen, check stamped through 3e5d593e2
- dup-check baseline gains the switch rows' declarative clone of
  SettingsRecommendationsScreen's switch list: data, not a rule

Tests: HttpPageLoaderTest (limited window honours the count, whole
chapter when allowed, retry of a ready page), ReaderLoadAheadTest (eager
preload on Wi-Fi, held off Wi-Fi, setting off, failure cooldown); each
seen red by mutation.
@rodrigdoliveira
rodrigdoliveira force-pushed the agent/retry-reader-decode-failure branch 2 times, most recently from 3a27293 to 9bd899b Compare October 13, 2026 23:08
@rodrigdoliveira
rodrigdoliveira force-pushed the agent/retry-reader-decode-failure branch from 9bd899b to 9305420 Compare October 18, 2026 04:39
@rodrigdoliveira

Copy link
Copy Markdown
Author

@AntsyLich, I've removed the test class and rebased onto the latest main (deeb9b258), as requested. The PR is still one commit with only the unconditional Queue reset in HttpPageLoader.retryPage().

Fresh local checks passed:

  • ./gradlew spotlessCheck
  • ./gradlew testDebugUnitTest — all 125 tests passed
  • ./gradlew verifySqlDelightMigration

The new CI run is awaiting maintainer approval. Could you approve it and take another look when you have a chance? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants