Commit Graph
41 Commits
Author SHA1 Message Date
patrick 9155129ccd fix: make the reader's typography, width and arrow keys work
Typography was in the stylesheet foliate prepends, which the book overrides;
moved to the appended one. The window keydown handler was never bound.

Also: wider reading area, page on a card, arrows moved onto it, spread gutter,
and the sidebar stays open on chapter clicks.
2026-08-11 22:45:14 -04:00
patrick 6318115380 fix: make the vendored slider track visible
shadcn-svelte generates the track with `data-horizontal:` / `data-vertical:`
variants, which Tailwind compiles to `[data-horizontal]` — an attribute
nothing sets, since the orientation is carried as data-orientation. The track
got no height, leaving only the thumb on screen. Use the `data-[orientation=…]`
form the rest of ui/ already uses.
2026-08-11 22:43:22 -04:00
patrick fe12f4be76 feat: add the reader settings panel
Typeface, size, weight, line height, letter spacing, justify and hyphenate,
plus flow, columns, line width, gap and margins — persisted in localStorage
and applied live.

Fixed-layout books hide the typography and column controls: they render
through foliate-fxl, which has no setStyles and ignores the paginator's
attributes, so those sliders would do nothing.
2026-08-11 22:27:04 -04:00
patrick 190e7af76d feat: replace the epub reader with foliate-js
Drops epub.js's 1600-location pre-pass and its localStorage cache: foliate
hands back a CFI and an overall fraction on every relocate, so first open no
longer freezes.

Also fixes resuming (pre-resolves the stored CFI, falling back to the stored
percentage rather than silently resetting to page one), progress saving
(missing Content-Type, and no flush on the way out), and arrow keys inside
the book iframe.
2026-08-11 22:21:15 -04:00
patrick 783f4d226d feat: add reader settings state and stylesheet generator
Settings are validated on read, not only on write: several go straight onto
foliate's renderer as custom-element attributes, where a bad value wedges the
layout silently rather than throwing. Unknown keys are stripped and missing
ones filled from the defaults, so settings added later do not invalidate what
a reader already has stored.

The stylesheet is built as foliate's [before, after] pair. The paginator
prepends the first to the section's <head> and appends the second, so the
book's own CSS overrides the first and loses to the second. Typography goes
in the first — a book that styles its own headings still gets to, and font
size lands on <html> without !important so rem/em headings scale rather than
being flattened. Colour goes in the second, because most EPUBs set a body
background and would otherwise leave the page white against a dark UI.

Font choices are reused from the app theme's FONT_STACKS rather than
duplicated, so the reader cannot drift from the rest of the UI.

Rename the ambient declaration to foliate-js.d.ts: as foliate.d.ts beside
foliate.ts, TypeScript takes it for that file's emitted declaration, drops it
from the program, and every $foliate import fails with TS2307.
2026-08-11 22:08:58 -04:00
patrick c946b6d71c chore: wire vendored foliate-js into the build
$foliate is a Vite-only alias, deliberately absent from kit.alias and
tsconfig paths: TypeScript cannot resolve it, so the ambient declaration in
src/lib/reader/foliate.d.ts is the only candidate and svelte-check never
walks the ~11k lines of untyped vendored JS. The generated tsconfig includes
src/**/*.js and checkJs is on, so src/lib/vendor is excluded as well —
`exclude` replaces rather than merges, hence the repeated service-worker
entries.

optimizeDeps.include for construct-style-sheets-polyfill: it sits behind a
dynamic import in fixed-layout.js, so Vite would otherwise discover it
mid-session and force a page reload on the first fixed-layout EPUB.

Verified with a temporary import that the graph resolves: view.js and
paginator.js are emitted as chunks, and the bundled pdf.js is our stub
rather than upstream's bare `import '@pdfjs/pdf.min.mjs'`.
2026-08-11 22:04:50 -04:00
patrick dd65e34869 chore: vendor foliate-js
foliate-js has no npm release and no build step; upstream recommends a git
submodule. Copy it instead: this repo has no submodules and already vendors
pdf.js the same way under static/pdfjs, and a submodule would pull in 231
files / 13 MB of which 191 files / 12 MB is a bundled pdf.js build that
Chitai does not use.

Only the import closure reachable from view.js is vendored — 15 files, 584K.
pdf.js is replaced by a stub that throws: view.js reaches it through a
static-string dynamic import inside makeBook, which Rollup resolves at build
time even though Chitai serves PDFs from static/pdfjs/web/viewer.html, and
upstream's version opens with a bare `import '@pdfjs/pdf.min.mjs'` that does
not resolve here.

scripts/vendor-foliate.sh pins the commit and makes the next update a one-line
change. fixed-layout.js needs construct-style-sheets-polyfill, so add it.
2026-08-11 21:59:33 -04:00
patrick a1281f129c chore: unbreak prettier by bumping prettier-plugin-tailwindcss
prettier-plugin-tailwindcss 0.6.14 is incompatible with prettier 3.8.1 and
threw "getVisitorKeys is not a function" on every .svelte file, so `pnpm
lint` could not run at all. 0.8.1 fixes it.

No reformatting here: the files prettier now reports are mostly vendored
shadcn components, and rewriting those is unrelated to any current work.
2026-08-11 21:54:17 -04:00
patrick ee46f5568c fix: resume epub progress from the fields the API returns
The load function read progress.epub_loc and progress.progress, neither of
which BookProgressRead carries, so resuming never worked and every open
started at page one. Read epub_cfi and percentage instead.

Fail loudly when the book cannot be fetched. The previous version caught
everything and returned {status, error} that nothing consumed, so a missing
book produced a reader sitting on its spinner forever. Check response.ok
before parsing too: fetch resolves on a 404, and arrayBuffer() happily
returns the error page, which only surfaced later as an opaque epub parse
error.

Give the reader a working sidebar, a theme that survives the book's own
CSS, and an error state with a retry. The theme is registered rather than
applied as bare overrides because most EPUBs ship their own body colours
and win otherwise, which is why the page stayed white against a dark UI.
2026-08-11 21:47:12 -04:00
patrick ac5a5c75aa fix: surface reader load failures instead of spinning forever
The PDF reader pointed an iframe at the vendored pdf.js viewer and had no
way to report a failure: the viewer renders its own errors inside the
frame, so a missing or unreadable file showed an empty grey panel. Probe
the file with a request first and render an error card with a retry when
that fails, matching the chrome the EPUB reader uses.

Add the missing +page.ts for the PDF route so the tab gets the book title
rather than a bare "Reader".

Drop chapter-sidebar.svelte and its import. It rendered a list of chapters
whose buttons had no click handler, and read/+layout@.svelte imported it
without ever rendering it. The reader's own sidebar replaces it.
2026-08-11 21:47:03 -04:00
patrick 49f94f9ee1 fix: mount ModeWatcher and Toaster at the root layout
The reader and login pages use +layout@ breakouts to escape the (root)
shell, so anything mounted in (root)/+layout.svelte never reaches them.
ModeWatcher was mounted there and duplicated in login/+layout@.svelte,
which left the reader's theme toggle inert: it flipped the store but
nothing wrote .dark onto <html>.

Mount both once at the top-level +layout.svelte instead, which every
route inherits regardless of breakouts.
2026-08-11 21:46:50 -04:00
patrick 2aba90f910 chore: clear epubjs type import and empty server load 2026-08-11 20:23:31 -04:00
patrick d2892353cb fix: reset the edit dialog when switching books 2026-08-11 20:23:31 -04:00
patrick 4ee127b6cb fix: remove duplicate separator in the shelves dropdown 2026-08-11 20:08:53 -04:00
patrick 6366582498 fix: silence state_referenced_locally in vendored ui components 2026-08-11 20:08:53 -04:00
patrick ef8e5e7fba fix: stop icons remounting and shelves collapsing into nothing 2026-08-11 20:08:53 -04:00
patrick c09b8365fa feat: put the library view mode in the url via shallow routing 2026-08-11 20:08:53 -04:00
patrick 0139f6f5eb feat: extract built-in view presets and add filter chips 2026-08-11 20:08:53 -04:00
patrick 4c3fd66a56 feat: rebuild the book page with the jacket layout 2026-08-11 20:08:53 -04:00
patrick f2b8f337f7 feat: rebuild the table view with sortable, toggleable columns 2026-08-11 20:08:53 -04:00
patrick 75360ff603 feat: add book cover component and detail-card list view 2026-08-11 20:08:53 -04:00
patrick 87fff20d72 feat: widen search and label the upload button 2026-08-11 20:08:53 -04:00
patrick adddcfeeed feat: add account menu to the sidebar footer 2026-08-11 20:08:53 -04:00
patrick cb070336c6 feat: replace the sidebar logo with a book mark 2026-08-11 20:08:53 -04:00
patrick f68a233dca refactor: replace hardcoded colours with semantic tokens 2026-08-11 20:08:53 -04:00
patrick f36aa14463 feat: add theme editor in settings 2026-08-11 20:08:53 -04:00
patrick d71b53b3c5 feat: add themeable design tokens with cookie-backed SSR 2026-08-11 20:08:53 -04:00
patrick dfeb4c3267 chore: remove unused book files accordion component 2026-08-11 00:32:44 -04:00
patrick e4ecfad5dd chore: regenerate OpenAPI types 2026-08-11 00:27:56 -04:00
patrick 23a12f7970 docs: add AGENTS.md for repo, backend and frontend 2026-08-10 23:58:42 -04:00
patrick c3e337de32 fix: correct book browser scroll area height 2026-08-10 23:58:42 -04:00
patrick 3ae3dcb0d0 fix: send correct field names when updating book progress 2026-08-10 23:58:42 -04:00
patrick 1415cb6244 fix: preserve directory structure when uploading books 2026-08-10 23:58:42 -04:00
patrick 9fe69641c5 feat: add library icons 2026-08-10 23:58:02 -04:00
patrick 0963ee85c2 chore: update nix dev shells and pnpm build settings 2026-08-10 23:58:02 -04:00
patrick 10eaf84329 refactor: simplify settings page layout 2026-03-09 14:19:59 -04:00
patrick a3e49dc918 regenerate OpenAPI schema with new KOSync models 2026-03-09 14:19:50 -04:00
patrick 3072f72958 feat: add device settings page
- Add device CRUD operations (create, delete, regenerate api keys)
- Add API key visibility toggle and copy button
2026-03-09 14:16:53 -04:00
patrick 930dbe9ba4 update dependencies
Migrate to the new SvelteKit invalid() API from the deprecated issue() api
for forms using remote functions.
2026-03-08 16:24:19 -04:00
hiperman 766fca2c39 Update BookProgress model and schemas
Updated book progress model in anticipation of the KOReader sync
feature.

Renamed properties:
 - renamed "progress" to "percentage"
 - renamed "pdf_loc" to "pdf_page"
 - renamed "epub_loc" to "epub_cfi"

New properties:
 - "epub_xpointer", marks the location of an epub in KOReader
 - "device", the device type that updated the progress
 - "device_id", the id of the device that updated the progress
2025-12-12 14:19:16 -05:00
hiperman 7ca0a21283 Initial commit 2025-12-04 00:33:37 -05:00