Commit Graph

901 Commits

Author SHA1 Message Date
dependabot[bot] c0e342fb74 chore(deps): bump typescript from 6.0.3 to 7.0.2
Bumps [typescript](https://github.com/microsoft/TypeScript) from 6.0.3 to 7.0.2.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](https://github.com/microsoft/TypeScript/compare/v6.0.3...v7.0.2)

---
updated-dependencies:
- dependency-name: typescript
  dependency-version: 7.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-28 02:56:49 +00:00
neon f2a7a11188 build(deps): update minor and patch dependencies
Refresh workspace manifests, resolution overrides, and the lockfile while keeping all packages on their current major versions.
2026-10-28 02:49:03 +00:00
neon 0b89e5a4a1 fix(series): count duplicate formats as one volume
Preserve raw book counts for compatibility while reporting logical ownership and reading progress for duplicate series positions.

Closes #1871
2026-10-27 03:55:23 +00:00
neon 1c27e5dd05 fix(koreader): keep manual links to a different copy matched and suggest links
Report a linked copy whose bytes differ from the library file as positionIncompatible instead of
unmatched, so the plugin keeps the match, skips highlights without a failure and still syncs progress.
Treat a position-less place within a page as the same place and jump to the nearest page.
Suggest library books with the same title and authors for books to review, with bulk linking.
See docs/KOREADER_HASH_MATCHING.md.

Closes #1872
Closes #1919
2026-10-26 15:06:04 +00:00
neon 834da8c954 fix(client): keep the sidebar dock inside a narrow sidebar
The dock's six 32px controls need 13.25rem, but the sidebar can be dragged
down to 224px, so the language and settings buttons spilled past its edge.
Below that width the buttons now shrink to 28px with a 2px gap. The spacer
that added a stray gap is replaced by a right-aligned group; the rail and
phone sheet are unchanged.

Closes #1873
2026-10-25 21:24:18 +00:00
neon cf09a71be6 fix(cover): keep a cover staged in a slot that is locked again before save
A cover staged after unlocking a locked slot, then re-locked before saving,
was silently dropped. The save now leaves that slot open, writes the cover,
then locks it again, and holds the page refetch until the locks are final.

Closes #1915
2026-10-24 23:11:40 +00:00
neon b9e5fe3a29 fix(koreader): keep the configured file name on downloads
Plugins from 1.7.0 request a delivery variant, and every such download had
" - bo-<id>-<variant>" added to its name. Only copies that would share a path are
renamed now: a narrated EPUB's text-only copy and later same-format files. A new
<a|b|c> chained default also stops the default pattern naming authorless
standalone books "Standalone/ - <title>". See docs/READ_ALOUD_DELIVERY.md.

Closes #1893
2026-10-24 21:06:09 +00:00
neon 946855cd30 feat(library): read series from folders for comics and manga
Offer the one-folder-per-series layout Komga and Kavita use as a File as Book path-rule preset
rather than a new organization mode, so released iOS builds and both existing modes are unaffected.
Add a job that applies saved rules to books already in a library, and keep a run year such as
"Batman (2016)" when ComicInfo or a provider names the series without it.

Ref #1167
Ref #1918
Ref #839
2026-10-24 04:43:17 +00:00
neon faee78370d feat(library): rebuild the folder picker as a tree with a live plan
Pick folders from a lazily loaded tree with find-by-name and typed paths, beside a plan showing
the books each organization mode would import, overlaps with other libraries, and folders no
library reads yet. New ManageLibraries /path routes walk folders within entry and time bounds.
Fix the scanner filing a disc-named library folder such as /mnt/disk1 under the folder above it,
and move books already filed there onto their primary file on the next scan.
2026-10-24 04:04:00 +00:00
neon d29b06c6e8 fix(auth): restore metadata editing lost to the 3.5.0 library roles
Promote Viewer grants to Editor on book libraries for non-superusers who hold Edit metadata but
can edit nowhere, which is how every such account was left after the upgrade. Accounts with any
Editor or Owner role are left alone. The Users drawer now says where Edit metadata takes effect,
read from a new GET /users/:id/library-access route.

Closes #1902
2026-10-24 03:56:25 +00:00
neon b50b8da56c feat(metadata): add external HTTP metadata providers
Register book-metadata-provider services by address, with no code change per
provider; Settings lists ready-made ones to install. Ranking prefers a record of
the book's own medium. LubimyCzytac moves out to its own provider and Aladin,
whose API closes, is retired; their ids stay. Adds migrations 0129 and 0130.
See docs/METADATA_PROVIDERS.md.

Ref #1405
2026-10-23 06:11:04 +00:00
neon 9e49f496f1 feat(reader): add grouped reading progress routes
Add GET and PUT /reading-progress and DELETE /reading-progress/:fileId: positions grouped by
kind, up to 25 files saved in one request, and an optional editedAt so the server keeps the newer
of two saves. Move the web reader and book page to them, and list reading-progress in
SERVER_FEATURES for the iOS and Android apps, which adopt the routes in the same release.
2026-10-22 17:28:07 +00:00
neon 1c593d7403 feat(stats): add a reading history of every finished read
Add a History page listing every read newest first, rereads included, as a
virtualized ledger or month cover walls, with period totals, per-read ratings,
export and a share image. Deleting a book keeps its finished reads under a
title and author snapshot (migration 0128).

Closes #1630
2026-10-22 14:45:09 +00:00
neon d21c68d13c feat(books): add an audiobook chapter editor
Add a Chapters tab to edit chapter timing and titles, look chapters up on Audible or in the ebook,
snap starts to pauses, keep a version history and write chapters into M4B, M4A and MP3 files. Add a
chapter health tool with a bulk Audible lookup queue. Editing needs Editor access to the book's
library. Chapter edits keep released iOS playback working by accepting a stale manifest revision
while the track layout is unchanged.

Ref #1120
2026-10-22 04:36:49 +00:00
neon 5ba5352e3e fix(books): stop the Files tab header overlapping its stats
Stack the hero bar when one row would leave the title under 12rem,
measured from the stats and actions rather than a fixed container
breakpoint, and let the folder crumb truncate once its ancestors are
spent instead of painting over the stats.
2026-10-22 00:42:23 +00:00
neon 8810d47658 feat(books): remember a default read-aloud narration language
Resolve book languages stated as names ("English") to a code, so the
dialog and the server's fallback stop calling English unsupported. The
dialog groups the ebook and audiobook in a Sources card, shows
Highlighting without the Advanced disclosure, and saves a per-user
default under /user-preferences/read-aloud for books it cannot match.
2026-10-22 00:42:06 +00:00
neon 0320210767 fix: say which download client is not responding
Show one notice above the release picker naming the client, with a
Try again that resends the same release, instead of a chip on every
row. Grab failures carry the client name in errorMeta, and transport
errors read "connection refused" rather than "fetch failed".
2026-10-22 00:05:10 +00:00
neon 992224f2e8 feat(books): add read-aloud generation
Generate a synced read-aloud EPUB from a book's EPUB and audiobook through an
optional STAlign worker (Docker on CPU, or native with MLX on Apple Silicon),
with review, re-sync, replace in place, restart recovery and live progress on
the Files tab. Book details also stack the ebook and audiobook covers when
both exist. See docs/READ_ALOUD.md.
2026-10-21 23:44:37 +00:00
neon fbd7a2e125 feat(metadata): clean pasted identifiers instead of truncating them
ISBNs copied from Amazon carry hyphens, and copied ASINs often start with a zero-width space.
The edit tab cut a hyphenated ISBN at its maxlength, Book Dock sent it on for the server to
reject, and an invisible character left an ID that looked right but never matched.

Clean ISBN, ASIN and provider id input as it is typed or pasted, and apply the same shared
rule in the book metadata and Book Dock DTOs so every client, including released iOS builds,
gets it. Provider ids keep their punctuation because Google ids and slugs use it, and an
over-long value is kept whole so validation still names the field.

Closes #1624
2026-10-21 05:47:03 +00:00
neon edc5e41105 feat(books): filter read-along titles
Expose read-along EPUBs as an additive format filter while preserving ordinary EPUB matching and existing client compatibility.

Closes #1583
2026-10-21 05:18:37 +00:00
neon d1cc18dc51 feat(smart-scope): add rolling older-than date filters
Allow users to build bounded historical windows without hard-coded calendar dates. Keep the API additive and advertise support for independently released clients.

Closes #1751
2026-10-21 03:59:41 +00:00
neon c59dd0118f i18n(client): sync translations from Crowdin (#1844)
Keep sparse translated catalogs synchronized with reviewed Crowdin content.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-20 17:07:14 -06:00
neon 2b8917afb6 feat(authors): allow correcting metadata matches
Let users edit author facts, choose and pin a provider record, and keep later refreshes tied to that record. Preserve compatibility for older clients through additive API fields and a discoverable server feature.

Keep server typechecking deterministic by breaking circular Drizzle inference and correcting the nullability mismatches it previously hid.

Closes #1464
2026-10-20 16:05:32 -06:00
neon 0d695a7ea0 feat(metadata): expand book request discovery
Allow request searches to browse broader provider result sets, rerun queries by exact author, and submit unmatched titles for approval. Advertise the optional limit so older clients retain their existing contract.

Closes #1363
2026-10-20 16:05:32 -06:00
neon b95a285c1b feat(koreader): hide audiobook-only books from the KOReader plugin
Add a per-login setting, on by default, that leaves books whose content files are all audio out
of the plugin catalog, its counts and bulk downloads, and drops a library holding nothing else.
The plugin detail page also names the first file the device can open as the main file.

Closes #1345
2026-10-20 16:05:32 -06:00
neon a728bf293b feat(book-requests): link releases to their source page and hold imports for review
Torznab and Newznab read the feed's details page, plugins may send infoUrl, and the
search drops any link that could carry a credential. A grab can ask to be held for
review whatever its score, and the held review shows the file's own edition facts,
its cover and the release page. Torznab guids are now digested like Newznab's.

Refs #1438
2026-10-20 16:05:31 -06:00
neon 3c87418416 feat(client): let users hide and reorder sidebar rows and groups
Add a Customize sidebar mode, opened from any section menu or Cmd+K, that hides rows and groups
and reorders them by drag or keyboard, with reset and undo. The layout saves to a new
sidebarLayout setting; a hidden Book Dock or Requests row returns while work is waiting.
Also line up the Rows shown menu labels, which sat 3px apart.

Closes #1434
2026-10-20 16:05:31 -06:00
neon 192c205299 fix(email): pick the only recipient when none is starred
Creating a recipient never makes it the default, so a single-Kindle setup
opened the send sheet with nobody ticked and Send disabled. Tick the lone
recipient in that case; a starred default still wins.

Ref #1443
2026-10-20 16:05:30 -06:00
neon 8762c4e628 fix(book-requests): show the book's cover on a request made from its page
Asking for a book's missing format sends no cover, so the request list, drawer and release
picker drew a blank placeholder. Fall back to the cover of the book the request joins or
became, in the requested format's slot when it has one. The request's own art still wins.
2026-10-20 16:05:30 -06:00
neon 435a60288d fix(books): show read-aloud sync as a compact pill only when it applies
Show the sync control only for a read-along EPUB with audio files or another
EPUB copy, so lone read-along EPUBs and plain audiobooks no longer show an
Unavailable card. Fold the card into a pill in the format row whose two-track
meter shows the state, with the details and toggle in a popover. Your Reading
now lists three recent sessions.

Fixes #1845
2026-10-20 16:05:29 -06:00
neon 58f258a5fc fix(reader): reopen a PDF at its saved page instead of the first
The PDF reader restored the saved page with a smooth scroll, which Chrome
starts about a second after it is asked. With Fit page, Fit width or
Automatic zoom, the first viewport resize refits the page from the
current offset with an instant scroll, and a classic scrollbar appearing
as the document loads is such a resize. The refit cancelled the restore
before it moved, so the reader stayed on page 1 while the toolbar showed
the saved page, and the next scroll saved page 1 or 2 over the position.

Restore the opening page with an instant scroll, so the refit starts from
the saved page and keeps it. Page turns still scroll smoothly.

Fixes #1857
2026-10-20 16:05:29 -06:00
neon 1214152bd5 fix(series): group books by media from content files only
Count only primary and content files when profiling a book's media, so a
side image, cover or .nfo in an audiobook folder no longer adds it to the
Books group on the series page.

Fixes #1862
2026-10-20 16:05:29 -06:00
neon 5878c96254 fix(books): fit series card covers to the grid instead of cropping them
First volume, Latest volume and First unread series cards drew their cover
with a cropping img, so a square audiobook cover in a 2:3 grid lost a third
of its width. They now render through BookCoverArtwork like single tiles and
follow the cover display setting, while the grid keeps one tile shape.

Fixes #1863
2026-10-20 16:05:29 -06:00
neon c01022aeb2 chore(client): default new users to Nostalgia and teal
Give users without stored appearance choices the Nostalgia style and teal accent while preserving saved selections and BookOrbit styling on standalone pages.
2026-10-20 16:05:28 -06:00
neon 80244ea4e2 feat(koreader): rebuild the plugin interface and fix four-way annotation sync
Squash of feat/koreader-widget-board. KOReader plugin 2.0.0 gets the widget-board dashboard, redesigned
book details, menus, lists and dialogs, Decor page and reading companions. Highlights, notes and bookmarks
now stay in step across web, Kobo, KOReader and the phones (defects D-00 to D-20, migration 0121), and
reading progress and narration hand off cleanly between devices.
2026-10-20 16:05:27 -06:00
neon 7202a59afc fix(auth): wait for an unreachable server instead of signing out
A page load during a server restart read the failed session refresh as
signed out and stranded the reader on /login. Boot now holds the first
navigation behind a reconnect screen and retries until the server
answers, and api() keeps the session when a refresh gets a 5xx or no
connection.
2026-10-20 16:05:27 -06:00
neon ce118e3890 i18n(client): sync translations from Crowdin (#1843)
Keep sparse translated catalogs synchronized with reviewed Crowdin content.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-16 23:47:46 -06:00
neon 2dca4bc85c fix(kobo): send Kobo covers at the device's screen size
A Kobo asks for each cover at its screen size but always got the
400x600 grid thumbnail, so sleep screens and full-screen covers were
blurry. Scale the full cover to fit the requested box instead, behind a
new Full-size covers setting that is on by default. Drop the stale
UserStorage entries from the authorization matrix gap baseline.

Fixes #924
2026-10-17 03:34:18 +00:00
neon abb44aa47a fix(kobo): refuse a replacement with the bytes the device already has
A replacement byte-identical to the device's copy was never downloaded, so
it stayed offered and every bookmark the device pushed was discarded.
Keep the current delivery instead, and tell the user in the replacement
panel that the device already has this copy.

Ref #1786
2026-10-17 00:10:32 +00:00
neon e070460876 fix(kobo): replace a stale delivery instead of failing its download forever
When a book's file changed after it was offered to a Kobo, every download
returned 409 because the offer could no longer be rebuilt. A device download
now retires that offer and serves a fresh one from the current file, and the
device bookmark adopts the copy it downloaded. Log the conflict code when a
sync defers a delivery. Also drop a dev-only relocate log from the reader.

Fixes #1816
2026-10-16 23:34:28 +00:00
neon d0da80e751 i18n(client): sync translations from Crowdin (#1755)
Keep sparse translated catalogs synchronized with reviewed Crowdin content.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-16 16:35:14 -06:00
Dennis 428aefe8d1 feat(scanner): regex metadata extraction (#1669)
feat(metadata): extract metadata from file paths with regex rules (#1669)

Let libraries define ordered regex rules that read title, authors, series,
series number and dates from each book's path relative to its library folder.
Run rules in a bounded worker pool, honour source precedence and field locks,
and apply them on scans, uploads and watcher moves. Also retry unprobed M4B
tag writes with the mp4 muxer.

Closes #1351

Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-10-16 16:24:11 -06:00
neon fd10f89586 fix(books): stop the details column from scrolling sideways
Clip the hidden genre measuring strip so its full single-line width no
longer widens the scrollable middle column, and let the rating row and
reading activity stats wrap in narrow columns.
2026-10-16 20:24:11 +00:00
neon a72179ad4d feat(auth): rebuild the sign-in pages as a bookplate on an endpaper
Put every auth page on a shared Ex Libris plate with signature-line fields, a show-password toggle and a Caps Lock hint.
Show sign-in messages outside the password form, with Retry, a reset link on lockout and a reset confirmation.
Add language and endpaper pickers (eight repeats) to the auth toolbar, replacing the background and corner controls.
2026-10-16 20:11:55 +00:00
neon 7d823039b0 feat(metadata): rebuild book auto-fetch as library scopes with counts
Show the global rule and each library's own rule on Field Rules-style tabs, with live counts per
condition, the score histogram and the books a run would take. Store only what a library changes,
run every library with its own rule, and record each library's run. Also fix the DjVu queue test
that assumed which request waits, and inventory the DjVu reader routes.
2026-10-16 19:05:32 +00:00
neon c378354dac feat(settings): rebuild reader fonts on the shared font ledger
Reader › Fonts now uses the Server Fonts ledger, family sheet and upload tray for a reader's own
fonts, and lists the server's fonts with a show/hide switch and a preview sheet. The shared pieces
move to features/settings/fonts and the ledger columns narrow to give the specimen room.
Server: additive GET /fonts/usage and PATCH /fonts/families, upload error codes, and a 409 instead
of a 500 when a reader uploads a second file for the same face.
2026-10-16 18:54:38 +00:00
neon 096bcea5cf feat(audit): rebuild the audit log as a grouped ledger with a drawer
Changes, Sign-ins, Security and All views replace the filter form. Repeats fold into one row,
sign-ins fold per person, day and network, and rows name their targets; events now snapshot
the target's name so deleted ones keep it. The drawer adds the event's facts, the target's
history, what the same person did around it, and one-click scoping. New additive routes:
/audit-log/summary, /sign-ins and /export; retention is editable from the page.
2026-10-16 16:38:08 +00:00
neon e21a92b8a4 feat(settings): rebuild server fonts as a specimen ledger with a family sheet
Each family is a row with its specimen, a weight grid of the styles readers get and how readers
use it; its sheet previews the face on reader pages and inside the reader's own font list. Uploads
answer per file in one tray, removing a family confirms with its cost, and a rename is one request.
Server: additive GET /server-fonts/usage (counts only), PATCH /server-fonts/families, upload error codes.
2026-10-16 16:27:42 +00:00
neon f89ae86d69 feat(metadata): rebuild custom fields as a roster with an editor sheet
Show each custom field on one row with its type, libraries and how many
books are filled, and edit, create, archive and delete it in the settings
sheet. Order Edit Metadata and card values by the order set on this page,
and add usageByLibrary to the admin field list, an additive field.
2026-10-16 16:15:44 +00:00
neon 83f17d6ff8 feat(achievements): rebuild the page as a trophy cabinet with hints
Replace the card grid with medals, a showcase, category shelves, a record book and a
detail sheet. Add GET /achievements/hints, which explains how to unlock what is still
locked from the user's own library and reading history, backed by a new page-count
index. Year-Round Reader now reports its months read as progress.
2026-10-16 15:44:16 +00:00