Repository navigation
Conversation
LNReader 2.1.4 loads a stored novel's chapters from its database and, when the current page has none, asks the plugin's parsePage for them. Royal Road had no parsePage, so a novel saved without its chapters failed with "Could not fetch chapters for page 1" every time it was opened. parsePage now returns the chapters from the fiction page, and the chapter JSON parsing is shared with parseNovel. Fixes lnreader#2659
|
LNReader asks parsePage for page "1" when a stored novel has no chapter pages at all. With volume view on, a novel that mixes chapters outside any volume with volume chapters (e.g. Pale Lights, 1 + 196) got only the one unvolumed chapter. Page "1" now returns every chapter; any other page returns that volume's chapters.
Contributor
Author
|
Plugin Check cant pass CF |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Work on #2659 and include screenshots of the working fix in the PR.
Issue 2659, "[RoyalRoad] Some(stubbed?) novels don't load." (plugin: English, Royal Road; plugin version 2.3.1; LNReader 2.1.4, Android 14): searching for and opening "A Practical Guide to Sorcery" (not Evil) or "Mother of Learning", the chapter list does not load at all; expected the list of chapters to load. The reporter suspects these are stubbed novels.
What Changed
window.chapters/window.volumesextraction out of theparseNovelHTML parser callback into a reusableparseChapters(scriptContent)method on the Royal Road plugin.parseNovelnow calls it, and chapter output (names, paths, release times, order, volume titles) is unchanged.parsePage(novelPath, page)method that fetches the fiction page and returns its chapters. Novels saved without a chapter list (e.g. "A Practical Guide to Sorcery", "Mother of Learning") can now get their list from the app. Page"1", which the app requests when it has no stored pages, returns the full list. Any other page returns only the chapters whose volume title matches.Fixes #2659
🤖 Generated with Claude Code
Root cause
The current plugin (2.3.1) parses both reported novels correctly the first time they are opened. Fetched through curl from the live site, Mother of Learning gives 109 chapters and A Practical Guide to Sorcery gives 18. The same counts come out under Node, under Hermes 0.12 with the plugin compiled to ES5, and in this repo's playground. A Practical Guide to Sorcery is a real stub (status label
STUB, 18 chapters still published). Mother of Learning is not a stub; all 109 chapters are published.The failure is in how LNReader 2.1.4 opens a novel it has already stored (
src/hooks/persisted/useNovel/store-helper/bootstrapService.ts):"1"for Royal Road), the app callsplugin.parsePage(path, "1").parsePage, sofetchPagethrewCould not fetch chapters for page 1.novelis never set on that failure, so pull-to-refresh (useNovelRefresh) returns early and can't repair it.Once a novel is stored without its chapters, that novel stays broken while every other novel keeps working, which matches "some novels don't load".
Limit: I couldn't observe which event left the reporter's two novels stored without chapters. That would need their device or database. One way it can happen:
insertNovelAndChapterssaves the novel row, then waits for the cover download, and only then inserts the chapters.Ruled out:
window.chaptersregex). Every runtime above parses both pages completely. Pages served to an Android WebView or Android Chrome User-Agent contain the same chapter data.window.volumes = []and every chapter withvolumeId: null.fiction/21220andfiction/34009.Risk Assessment
Testing
This was not tested in the LNReader app. The Android toolchain isn't installed on the machine that made this change.
All live-site evidence below comes from Royal Road pages fetched through curl. Node's own
fetch, and the no-mistakes validation pipeline, get a Cloudflare 403 from royalroad.com. The screenshots are from this repo's plugin playground, running in headless Chromium with the playground proxy in curl mode. Everything was run on head02a493d.Scenario 1: Mother of Learning and A Practical Guide to Sorcery show their chapter list
Playground, end to end: the Latest listing, search (both reported novels appear), novel detail, chapter list and chapter text. Mother of Learning lists 109 chapters, A Practical Guide to Sorcery lists 18, and Super Supportive (a normal novel) lists 312.
App path that failed (regression check): a harness runs LNReader v2.1.4's real
bootstrapService.tsagainst the real plugin, with an in-memory stand-in for the app database. "Stored, no chapters" means the novel row exists with no chapters, which is the state that sends the app toparsePage. Results with volume view off (the default):Could not fetch chapters for page 1The same matrix with volume view on gives the same results: 2.3.1 fails every "stored, no chapters" case, and 2.3.2 loads the full list for each novel.
Scenario 2: with volume view on,
parsePagereturns each volume's chapters for its own pageMother of Learning has no volumes, so this used two Royal Road fictions that do:
With the plugin's "Enable Pagination / Volume view" setting on:
parsePage("Lost Things")/("Good Treasons")/("Borrowed Trouble")parsePage("1")parsePage("Spring")/("Summer")/("Autumn")/("Winter")parsePage("1")parsePage("A Conjuring of Ravens")/("A Pact of Stars")/("1")Each volume page matched the chapters
parseNovellabels with that volume.This testing found a bug, which commit
02a493dfixes. In the first version,parsePage("1")returned only the chapters labelled"1"when any existed. For Pale Lights that was a single chapter ("Maps") out of 197. Page"1"now always returns the whole list.Other checks
parseNovelandparsePage("1")return 109 / 18 / 197 with volume view off and on.npm run build:compilepasses, and Prettier and ESLint are clean forplugins/english/royalroad.ts.popularNovelsreturned no novels:popularNovelsorparseNovels.fetch, which gets HTTP 403 withcf-mitigated: challenge.fetchApidoesn't throw on a status code, so a challenge page parses to an empty list. The checker then reports FAIL rather than INCONCLUSIVE, because its root-URL probe passed on the runner.npm run check:plugin -- plugins/english/royalroad.tsis INCONCLUSIVE (HTTP 403 from Cloudflare).Screenshots
These come from this repo's plugin playground, not from the LNReader app. Cover images that go through the playground proxy in curl mode don't display (a playground limitation); covers in the listing and search load directly.
The playground only calls
parsePagefor plugins that reporttotalPages, so the last two screenshots call it from DevTools on the playground page, with the output printed on the page.Latest listing
Search for "A Practical Guide to Sorcery" (both reported novels in the results)
Mother of Learning: details and chapter list (109)
Mother of Learning: chapter 1 text
A Practical Guide to Sorcery: chapter list (18, a stub)
Super Supportive, a normal novel: chapter list (312)
parsePage(path, "1"), the call LNReader makes for a novel stored with no chapters (volume view off)parsePageper volume with volume view on (Pale Lights and The Elf)This PR was written by an AI agent (Claude Code), and no human has reviewed it. Please review it with that in mind.
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ No issues found.
npm cinpm run check:plugin -- plugins/english/royalroad.ts(INCONCLUSIVE, HTTP 403)✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.