Skip to content

Keyoapp: fix genres, add type/status filters, exclude novels - #18250

Open
JochemKuipers wants to merge 3 commits into
keiyoushi:mainfrom
JochemKuipers:fix-keyoapp-filters
Open

Keyoapp: fix genres, add type/status filters, exclude novels#18250
JochemKuipers wants to merge 3 commits into
keiyoushi:mainfrom
JochemKuipers:fix-keyoapp-filters

Conversation

@JochemKuipers

@JochemKuipers JochemKuipers commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Genres are rendered from an inline initializeDropdownMenu({ type: "genre", items: [...] }) script payload rather than the old #series_tags_page markup, so parseGenres() always returned empty and the filter sheet only ever showed the "Press 'Reset'" placeholder. Parse the script payload, keeping a DOM fallback in case the shape changes.

The same payload carries the type and status dropdowns, so expose those as filter groups, send them as query params, and narrow the results client-side on each entry's data-type and data-status attributes. Fetching now runs off the main thread and guards against overlapping requests when the filter sheet is reopened.

Genre matching was also silently dropping hits across the theme: card tags are frequently padded (e.g. [" Fantasy", "Action "]), and the client-side compare used equals(ignoreCase = true), which tolerates case but not surrounding whitespace. Tags are trimmed before comparing in the theme and in TimelessToons' overridden searchMangaParse.

Most Keyoapp sites return every entry and filter client-side, so multi-select checkboxes are correct there. ArtLapsa and RitharScans filter server-side via single-value controls (a Livewire <select> and mutually-exclusive genre chips), so selecting more than one value sent a repeated query param of which the server keeps only the last — e.g. ?type=manhwa&type=manhua returned only manhua, and manhwa results disappeared. Those sources now use a shared SelectFilter / singleSelectFilterList() path that offers single-choice dropdowns instead.

Novels leaked into every listing. Matching on :not([data-type=novel]) only worked on pages that emit that attribute, so detection also checks the badge text and a "(Novel)" or "[ Novel ]" title marker, and is applied to popular, latest and search theme-wide. Sources can disable it via excludeNovels or adapt it by overriding isNovel(). ArtLapsa also strips Novel from its Type dropdown and derives hasNextPage from the pre-filter entry count so novel exclusion cannot truncate pagination.

Asmotoon drops its now-redundant selector overrides. ArtLapsa, RitharScans and TimelessToons override searchMangaParse, so they apply the novel filter explicitly. ArtLapsa also parses its Livewire <select> options instead of the script payload.

Checklist:

  • Updated versionCode value in build.gradle.kts
  • Updated baseVersionCode in build.gradle.kts (if updated multisrc theme code)
  • Referenced all related issues in the PR body (e.g. "Closes #xyz")
  • Set the contentWarning configuration in build.gradle.kts appropriately
  • Have not changed source names
  • Have explicitly kept the id if a source's name or language were changed
  • Have tested the modifications by compiling and running the extension through Android Studio
  • Have removed web_hi_res_512.png when adding a new extension
  • This PR is AI-assisted, I have reviewed the changes manually and confirmed they are not slop

🤖 This PR was opened with AI assistance. I was asked to fix the broken genre filter on Keyoapp sources, add the missing type and status filters, and stop novel entries from appearing in listings; the code changes were written by an AI agent and reviewed by the human opening this PR.

Genres are rendered from an inline initializeDropdownMenu({ type:
"genre", items: [...] }) script payload rather than the old
#series_tags_page markup, so parseGenres() always returned empty and the
filter sheet only ever showed the "Press 'Reset'" placeholder. Parse the
script payload, keeping a DOM fallback in case the shape changes.

The same payload carries the type and status dropdowns, so expose those
as filter groups, send them as query params, and narrow the results
client-side on each entry's data-type and data-status attributes.
Fetching now runs off the main thread and guards against overlapping
requests when the filter sheet is reopened.

Novels leaked into every listing. Matching on :not([data-type=novel])
only worked on pages that emit that attribute, so detection also checks
the badge text and a "(Novel)" or "[ Novel ]" title marker, and is
applied to popular, latest and search theme-wide. Sources can disable it
via excludeNovels or adapt it by overriding isNovel().

Asmotoon drops its now-redundant selector overrides. ArtLapsa,
RitharScans and TimelessToons override searchMangaParse, so they apply
the novel filter explicitly. ArtLapsa also renders its filters as
Livewire <select> elements instead of the script payload and overrides
the three parse methods accordingly.
Genre filtering silently dropped matches across the whole ecosystem:
card `tags` are frequently padded (e.g. `[" Fantasy", "Action "]`) and
the client-side match used `equals(ignoreCase = true)`, which tolerates
case but not surrounding whitespace. Trim tags before comparing, in the
theme and in TimelessToons' overridden searchMangaParse.

ArtLapsa and RitharScans filter server-side via single-value controls
(a `<select>` and mutually-exclusive genre chips), so selecting more
than one value sent a repeated query param of which the server keeps
only the last, e.g. `?type=manhwa&type=manhua` returned only manhua and
manhwa results silently disappeared. Model these as single-choice
dropdowns: add a shared SelectFilter plus singleSelectFilterList() and
HttpUrl.Builder.addSelectedTo() helpers, and have both sources opt in.
Sites that return every entry for client-side narrowing keep the
existing multi-select checkbox groups.

Expose genresList/typesList/statusesList as protected read-only so
sources can build their own filter lists off the fetched data.
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.

1 participant