From ac5a5c75aaadfa43a444df15ab3c8b7dc546ea40 Mon Sep 17 00:00:00 2001 From: patrick Date: Tue, 11 Aug 2026 21:47:03 -0400 Subject: [PATCH] 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. --- .../components/reader/chapter-sidebar.svelte | 27 ---- .../book/[bookId]/read/+layout@.svelte | 3 - .../[bookId]/read/pdf/[fileId]/+page.svelte | 115 +++++++++++++----- .../book/[bookId]/read/pdf/[fileId]/+page.ts | 13 ++ 4 files changed, 99 insertions(+), 59 deletions(-) delete mode 100644 frontend/src/lib/components/reader/chapter-sidebar.svelte create mode 100644 frontend/src/routes/(root)/(library)/book/[bookId]/read/pdf/[fileId]/+page.ts diff --git a/frontend/src/lib/components/reader/chapter-sidebar.svelte b/frontend/src/lib/components/reader/chapter-sidebar.svelte deleted file mode 100644 index 809c91b..0000000 --- a/frontend/src/lib/components/reader/chapter-sidebar.svelte +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - Chapters - - - {#each chapters as chapter} - - - {#snippet child({ props })} - {chapter.label} - {/snippet} - - - {/each} - - - - - - diff --git a/frontend/src/routes/(root)/(library)/book/[bookId]/read/+layout@.svelte b/frontend/src/routes/(root)/(library)/book/[bookId]/read/+layout@.svelte index 01e30c7..914b4c5 100644 --- a/frontend/src/routes/(root)/(library)/book/[bookId]/read/+layout@.svelte +++ b/frontend/src/routes/(root)/(library)/book/[bookId]/read/+layout@.svelte @@ -1,7 +1,4 @@ diff --git a/frontend/src/routes/(root)/(library)/book/[bookId]/read/pdf/[fileId]/+page.svelte b/frontend/src/routes/(root)/(library)/book/[bookId]/read/pdf/[fileId]/+page.svelte index c3c1b27..635dbc0 100644 --- a/frontend/src/routes/(root)/(library)/book/[bookId]/read/pdf/[fileId]/+page.svelte +++ b/frontend/src/routes/(root)/(library)/book/[bookId]/read/pdf/[fileId]/+page.svelte @@ -1,42 +1,99 @@ -
- -
+ + {data?.title ? `${data.title} — Chitai` : 'Reader — Chitai'} + - +
+ {#if loadError} +
+
+ +

This file wouldn't open

+

{loadError}

+
+ + + Back to book + +
+
+
+ {:else if loading} +
+ + Opening… +
+ {/if} + + +
+ diff --git a/frontend/src/routes/(root)/(library)/book/[bookId]/read/pdf/[fileId]/+page.ts b/frontend/src/routes/(root)/(library)/book/[bookId]/read/pdf/[fileId]/+page.ts new file mode 100644 index 0000000..055de42 --- /dev/null +++ b/frontend/src/routes/(root)/(library)/book/[bookId]/read/pdf/[fileId]/+page.ts @@ -0,0 +1,13 @@ +import { error } from '@sveltejs/kit'; + +export async function load({ fetch, params }) { + const response = await fetch(`/api/books/${params.bookId}`); + + if (!response.ok) { + error(response.status, 'This book could not be loaded.'); + } + + const book = await response.json(); + + return { title: book.title }; +}