Komga: fixes, content filtering, and homepage settings - #6
Open
Exikle wants to merge 31 commits into
Open
Conversation
The sdk under src/Komga/sdk is regenerated by openapi-ts, so formatting it only creates churn on the next run.
Request.headers is optional, so the non-null assertions threw a TypeError on any request that arrived without headers.
The old prefix strip only matched the literal word "chapter" followed by a space, so abbreviated and volume-prefixed titles were left intact and shown twice, e.g. "Ch. 245 - Ch.245" or "Ch. 74.5 - Vol.13 Ch.074.5". Across the test library that was 1645 of 14633 books. parseChapterTitle peels leading volume/chapter/separator tokens in a loop, which also covers doubled prefixes like "Chapter 10 - Chapter 10", and pulls out the volume when the source recorded one. Volume placeholders (TBD, TBA) are stripped without setting a volume. Drops the hardcoded volume: 0 and the file size that was being passed as langCode.
contentRating was pinned to EVERYONE, so 18+ series were labelled safe. Komga exposes a minimum age in metadata.ageRating. alternateTitles and readingDirection were also available and unused; readingDirection is what the reader needs to pick long strip mode.
The comment above it already said this must not throw, but each of the four lookups threw on failure, so an unconfigured or offline server broke the homepage. They now fall back to empty option lists and run in parallel.
These go into a JSON body, not a query string, so a genre like "Science Fiction" was sent as "Science%20Fiction" and matched nothing. Any tag or genre containing a space or ampersand returned no results.
These files predated the prettier config and were never run through it. Formatting only, no behaviour change.
The workflow published to gh-pages without anything verifying the sources compiled.
contentRating was only set on the manga details page, so search results and every carousel item shipped it unset and the app had nothing to filter on. Komga libraries rarely populate ageRating — every series in the test library has it null — so the rating now falls back to genres when it is absent. Books carry no genres, which leaves On Deck unrated.
- both navigation rows shared the id 'authentication' - the password field rendered in plaintext, InputRow has isSecureEntry - only a 400 carries `violations`, so a 404 or an unreachable host threw a TypeError instead of reporting the real problem - "Hompage" typo in the section header
Adds a Content Settings form with a Hide Adult Content switch and an editable genre list, loaded from the server's own genres. Search and Continue Reading exclude them server-side through the search condition; Recently Added and Recently Updated have no condition parameter so they are filtered client-side. On Deck cannot be filtered as Komga exposes no genres on books. Recently Added and Recently Updated also get show/hide toggles, which the other two sections already had.
Reports the result inline with a styled label instead of requiring a blind submit, and reuses the same status messages as submission.
Row ids may only contain alphanumerics or `._-@()[]%?#+=/&:`, so genres with a space such as `martial arts` were rejected at render. Encoded with base64 the same way the search filters already build their genre and tag ids; the stored setting stays as plain genre names.
Komga records external links per series (AniList, MangaDex, MangaUpdates and others) but MangaInfo.shareUrl was left unset, so the app's share action had no target. Picks the first match from a preference order, falling back to whatever link exists. Also surfaces totalBookCount, which is the intended length of the series as opposed to the books actually present.
Search was pinned to a hardcoded sort behind a dead `orderResultsAlphabetically` local. That sort was also broken: Komga ignores an unrecognised sort field instead of erroring, and `titleSort` is one of them, so results were never actually ordered by title. The working field is `metadata.titleSort`. Every option was checked against a live server by confirming asc and desc return different results; `releaseDate` and `folderName` are ignored the same way and are deliberately left out.
Versions were major.minor; other Paperback extensions use full semver, so match that. Major stays at 3: nothing since the 3.0 tracker release breaks compatibility, the new settings keys are additive and no capability was dropped. Minor goes to 2 rather than 1 because several different builds already shipped as 3.1, and 3.1.0 could compare equal to those.
The app was calling getChapters once per tracked series on every update run, 86 requests for this library. Komga has no "changed since" search condition, but /series/updated is ordered by lastModified descending, so paging until the cutoff identifies everything that moved in one or two requests and the rest is marked skippable. A series' lastModified can trail its books' created time by a few seconds when both are written during a single library scan, so the cutoff looks an hour further back than the app's last check. Checked against every series in a 14.6k book library: a daily run drops from 86 requests to 27 with nothing missed. A failed request returns without setting any priority, since marking titles skipped on incomplete information would swallow real updates.
Adds a Genres section using DiscoverSectionType.genres, which was one of four section types the extension never used. Each tile carries a search query in the shape getSearchResults already reads, so tapping one runs a normal genre search. Hidden genres are left out of the grid when Hide Adult Content is on, and the section has a toggle like the others.
Uses the last two unused DiscoverSectionType values. Featured shows recently added series with cover, status, publisher, summary and book counts; the prominent carousel shows in-progress series with read progress. Both overlap sections that already exist, so they default to off rather than crowding the homepage on upgrade, and the toggle subtitles say so.
On Deck was the one section the content filter could not reach, since Komga puts genres on series and that endpoint returns books. Fetching the hidden series once and filtering by membership covers it in a single extra request, and only when the filter is enabled. The settings footer no longer claims the section is unfilterable. Chapter.creationDate now carries the book's created time, which is when it entered the library rather than when it was published.
"Featured" described the card style rather than what the section shows. The id and settings key stay as they are so existing toggle state survives.
Seven homepage sections were backed by five queries: Featured and Recently Added both called /series/new, and the prominent carousel and Continue Reading both called /series/list with the same condition and sort. Presentation is now a property of each section rather than a reason to duplicate it, chosen per section as Regular, Large or Hero, with Hidden replacing the old visibility toggles. Labels follow Komga's own dashboard vocabulary so they read the way users already know them from the web UI: Continue Reading becomes Keep Reading, and the two series sections name themselves as such. Existing settings migrate rather than reset. An old visibility boolean maps to Regular or Hidden, and a duplicate section that was switched on becomes its owner's style.
The status was only visible after pressing Test Connection a level down. The root settings screen now checks on appearance and shows the result, with the server URL as the Server Settings subtitle. The check moves into a shared helper that Test Connection and form submission both use, replacing two copies of the same error handling. It also no longer trusts a bare 200: Komga's SPA answers unknown paths with index.html, so a base URL with a stray path looked like a successful connection and reported "Connected as undefined".
Adds a library picker and a one-shot toggle to Content Settings, applied to browsing and search alike. The discover endpoints take them as query params while /series/list takes conditions, so both paths are covered. Nearly Finished orders series by how few unread books remain. Komga ignores booksUnreadCount as a sort field, so the ordering happens client side over the in-progress set, which is bounded by what the user is actually reading.
- npm ci rather than npm install, since a lockfile is committed - cache the npm download directory - set-output was disabled by GitHub in 2023; write to $GITHUB_OUTPUT - run on pull_request as well, with bundling and deployment guarded to pushes so a PR is checked without publishing
komga.ts had grown to 979 lines, most of it not the extension interface. Moves out discover section building, content rating, query scoping and the shared formatting helpers, leaving 668 lines of interface implementation. Also renames utils.ts to utils/operators.ts, since a file and a directory sharing the name made imports ambiguous. No behaviour change.
- types pointed at index.d.js rather than index.d.ts - fast-xml-parser was declared but imported nowhere - src/tests/suite.ts imports chai directly, but only @types/chai was declared; it was resolving by hoisting from @paperback/toolchain - lint and format only covered src, so the root .mjs config files were never checked, and openapi-ts.config.mjs had drifted out of style - dropped a commented-out import from the eslint config
Author
|
#4 this is done predating my changes. |
Author
|
#3 as well seems to be fixed with my changes on top of paper. shows up in my testing. |
getChapters sets an empty title for a chapter with no name of its own, which is the common case. The progress form fell back with ??, so it only caught null and undefined and showed blank rows for 92% of chapters.
Reverts the pull_request trigger; keeps npm ci, dependency caching and the $GITHUB_OUTPUT change.
config.ts repeated the same seven genres that content_rating.ts already defines, so the two could drift. The default hide list now derives from them.
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.
Komga extension: bug fixes, content filtering, and homepage/settings work.
Tested against a library of 86 series / 14,633 books.
Existing settings migrate rather than reset, and no declared capability
changes, so this stays on major 3.
3.1
Bug fixes, mostly long-standing:
word "chapter" plus a space, so
Ch.245andVol.13 Ch.074.5survived andshowed as
Ch. 245 - Ch.245. 1,645 of 14,633 books were affected.parseChapterTitlepeels volume/chapter/separator tokens in a loop andrecovers the volume when one was recorded.
Science Fictionwas sent asScience%20Fictionand matched nothing.getSearchFiltersthrew on failure despite the comment saying it mustnot, breaking Discover against an unconfigured or offline server.
Request.headersis optional and wasnon-null asserted.
TypeError instead of an error message on a 404 or unreachable host.
contentRatingwas pinned toEVERYONE;alternateTitles,readingDirectionandpublisherwent unused.sorting options for search,
shareUrl, and a connection test.published to gh-pages with nothing verifying the sources compiled.
3.2.0
Move to semver. No functional change.
3.3.0
processTitlesForUpdates: the app was callinggetChaptersonce per trackedseries. Komga has no "changed since" condition, but
/series/updatedisordered by
lastModifieddescending, so paging to a cutoff finds what moved inone request — a daily run goes from 86 requests to 1. The cutoff looks an hour
further back than the last check, since a series'
lastModifiedcan trail itsbooks'
createdtime by a few seconds during a library scan.3.4.0 – 3.6.1
Genres, featured and prominent discover sections; On Deck brought under the
content filter;
Chapter.creationDate.3.7.0
Seven homepage sections were backed by five queries — two pairs ran identical
requests and differed only in card size. Presentation became a per-section
setting (Regular / Large / Hero, with Hidden replacing the visibility toggles),
and the duplicates were removed.
Labels now follow Komga's own dashboard vocabulary: On Deck, Keep Reading,
Recently Added Series, Recently Updated Series.
3.8.0
Connection status on the settings screen, checked on appearance. It no longer
trusts a bare 200 — Komga's SPA answers unknown paths with
index.html, so abase URL with a stray path previously looked like a working connection.
3.9.0
Library scope and one-shot filtering in Content Settings, applied to browsing
and search. Adds a Nearly Finished section ordered by fewest unread books,
sorted client-side because Komga ignores
booksUnreadCountas a sort field.CI switched to
npm ci, caches dependencies, replaces the disabledset-output, and validates pull requests without publishing.3.9.1 – 3.9.2
komga.tssplit into focused modules (979 → 668 lines) andutils.tsrenamedto
utils/operators.ts, which had been colliding with theutils/directory.Root config fixes:
typespointed atindex.d.js,fast-xml-parserwasunused,
chaiwas imported by the test suite but only@types/chaiwasdeclared, and lint/format skipped the root
.mjsfiles.Notes
Komga silently ignores unrecognised sort fields and returns 200, so every sort
option here was verified by confirming asc and desc give different results.
titleSortis one of the ignored ones, which is why search had never actuallybeen sorted;
releaseDateandfolderNameare ignored too and are left out.Known limitations: Recently Updated Series includes metadata-only edits, as
/series/updatedtakes no parameter to narrow it; On Deck and Keep Readingoverlap by nature; and genre-based content rating reflects library metadata
quality rather than the content.