diff --git a/web/src/reader/core/reader-context.ts b/web/src/reader/core/reader-context.ts index f6fecdf..9ee3ee7 100644 --- a/web/src/reader/core/reader-context.ts +++ b/web/src/reader/core/reader-context.ts @@ -28,7 +28,11 @@ interface MangaReader { readingDirection: "rtl" | "vertical"; } -type CurrentReader = UniversalReader | PDFReader | ComicReader | MangaReader; +export type CurrentReader = + | UniversalReader + | PDFReader + | ComicReader + | MangaReader; export interface ReaderContext { getState: () => { diff --git a/web/src/reader/core/reader-navigation.ts b/web/src/reader/core/reader-navigation.ts index 13ac6ed..9bd44a7 100644 --- a/web/src/reader/core/reader-navigation.ts +++ b/web/src/reader/core/reader-navigation.ts @@ -279,6 +279,7 @@ export async function renderSpineItem() { if (!container || !spineItem) return; // Get the actual content from resources using the href const resources = state.currentReader.cif.resources; + console.log("ALL resource keys:", Array.from(resources.keys())); const contentBlob = resources?.get(spineItem.content); if (!contentBlob) { // Fallback: try to fetch directly if not in resources @@ -326,16 +327,11 @@ export async function renderSpineItem() { // Rewrite image src paths to use blob URLs from resources const modifiedContent = rewriteImageUrls(contentText, resources); - const images = modifiedContent.match(/]+>/g); - console.log("Found images in content:", images); - // Test resource lookup - console.log("Trying to find image:", { - direct: resources.get("image/1.png"), - withoutFolder: resources.get("1.png"), - allImageKeys: Array.from(resources.keys()).filter( - (k: string) => k.includes("image") || k.includes("png"), - ), - }); + const htmlImages = modifiedContent.match(/]+>/g); + const svgImages = + modifiedContent.match(/]+xlink:href="([^"]+)"[^>]*>/gi) || []; + const allImages = [...htmlImages, ...svgImages]; + console.log("Found images in content:", allImages); // Parse HTML and process images BEFORE setting innerHTML const parser = new DOMParser(); @@ -354,6 +350,20 @@ export async function renderSpineItem() { img.setAttribute("src", blobUrl); } } + + // Process SVG elements with xlink:href + const svgImgElements = Array.from(doc.querySelectorAll("image")); + for (const img of svgImgElements) { + const src = img.getAttribute("xlink:href"); + if (!src) continue; + + let blob = findImageInResources(resources, src); + if (blob) { + const blobUrl = URL.createObjectURL(blob); + img.setAttribute("xlink:href", blobUrl); + } + } + container.innerHTML = doc.body.innerHTML; // Apply reader styling applyReaderTheme(); @@ -498,7 +508,7 @@ function sendProgressUpdate() { if (!state.currentReader || !state.readerMetadata) return; const mediaItemId = - state.readerMetadata.media_item_id || + state.readerMetadata.id || document.body.dataset.mediaItemId || window.location.pathname.split("/").pop(); @@ -541,7 +551,7 @@ function sendProgressUpdate() { const percentage = totalPages > 0 ? (currentPage / totalPages) * 100 : 0; updateReadingProgress( - state.readerMetadata.media_item_id, + state.readerMetadata.id, { current_page: currentPage, total_pages: totalPages, diff --git a/web/src/reader/core/reader-state.ts b/web/src/reader/core/reader-state.ts index fad3e9c..8f1fa39 100644 --- a/web/src/reader/core/reader-state.ts +++ b/web/src/reader/core/reader-state.ts @@ -1,4 +1,4 @@ -import type { ReaderMetadata, ReaderState } from "./reader-context"; +import type { ReaderState } from "./reader-context"; type CurrentReader = import("./reader-context").CurrentReader; diff --git a/web/src/types/reader.d.ts b/web/src/types/reader.d.ts index c1e6ab7..77389b4 100644 --- a/web/src/types/reader.d.ts +++ b/web/src/types/reader.d.ts @@ -72,7 +72,7 @@ interface ParserCapabilities { // ============================================================ interface ReaderMetadata { - media_item_id: string; + id: string; title: string; author: string; cover_image_path: string;