diff --git a/templates/book_detail_modals.templ b/templates/book_detail_modals.templ index ad1b0b3..1e4242e 100644 --- a/templates/book_detail_modals.templ +++ b/templates/book_detail_modals.templ @@ -290,25 +290,6 @@ templ MetadataEditorModal(book handlers.MediaDetail) {
- -
-
-
- - -
-
- - -
+
+
+ +
+
+ + +
+
diff --git a/templates/book_detail_modals_templ.go b/templates/book_detail_modals_templ.go index 21437c4..ef95d6d 100644 --- a/templates/book_detail_modals_templ.go +++ b/templates/book_detail_modals_templ.go @@ -689,23 +689,7 @@ func MetadataEditorModal(book handlers.MediaDetail) templ.Component { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "
Click to upload
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, tag := range book.Tags { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "\" class=\"hidden\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "
Vertical
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "Save") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/web/src/book-detail.ts b/web/src/book-detail.ts index faaeeeb..aae5cb1 100644 --- a/web/src/book-detail.ts +++ b/web/src/book-detail.ts @@ -1,6 +1,5 @@ import { Alpine } from "./alpine"; import { showToast } from "./toast"; -import { generateCoverBlob } from "./cover-generator"; import { searchTagSuggestions, type TagSuggestion } from "./tag-dropdown"; function getMediaId(): string { @@ -91,7 +90,6 @@ export { interface MetadataEditorState { openSections: Record; - coverGenerating: boolean; hasExistingCover: boolean; newCoverPreview: string; coverFile: Blob | null; @@ -108,7 +106,6 @@ interface MetadataEditorState { showMetadataEditor(): void; hideMetadataEditor(): void; handleCoverUpload(event: Event): void; - generateCover(): Promise; removeCover(): void; saveMetadata(): Promise; rescanBook(): Promise; @@ -130,12 +127,6 @@ Alpine.data("bookDetail", () => { coverImg?.src && !coverImg.src.includes("placeholder-book.svg"); - const coverPreviewEl = document.querySelector( - ".aspect-\\[2\\/3\\] img", - ) as HTMLImageElement | null; - const coverSrc = coverPreviewEl?.src || ""; - const fileUrl = coverSrc && !coverSrc.includes("placeholder") ? coverSrc : ""; - const initialTags: string[] = []; const tagBadges = document.querySelectorAll("#metadata-editor-modal [data-editor-tag]"); tagBadges.forEach((el) => { @@ -145,7 +136,6 @@ Alpine.data("bookDetail", () => { return { openSections: { basic: true } as Record, - coverGenerating: false, hasExistingCover: !!hasCover, newCoverPreview: "", coverFile: null as Blob | null, @@ -462,33 +452,6 @@ Alpine.data("bookDetail", () => { reader.readAsDataURL(file); }, - async generateCover() { - this.coverGenerating = true; - try { - const formatGroup = - document - .querySelector('[data-format-group]') - ?.getAttribute("data-format-group") || "reflowable"; - - const blob = await generateCoverBlob(fileUrl, formatGroup); - if (!blob) return; - - this.coverFile = blob; - this.coverAction = "upload"; - - const preview = document.getElementById( - "metadata-cover-preview", - ) as HTMLImageElement; - if (preview) { - preview.src = URL.createObjectURL(blob); - } - this.newCoverPreview = URL.createObjectURL(blob); - showToast("Cover generated successfully", "success"); - } finally { - this.coverGenerating = false; - } - }, - removeCover() { this.coverAction = "remove"; this.coverFile = null; diff --git a/web/src/cover-generator.ts b/web/src/cover-generator.ts deleted file mode 100644 index 4955680..0000000 --- a/web/src/cover-generator.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { showToast } from "./toast"; - -function getToken(): string { - return localStorage.getItem("token") || ""; -} - -export async function generateCoverBlob( - fileUrl: string, - formatGroup: string, -): Promise { - try { - const View = (await import("foliate-js/view.js")).default; - const view = new View(); - - const resp = await fetch(fileUrl, { - headers: { Authorization: `Bearer ${getToken()}` }, - }); - if (!resp.ok) { - showToast("Failed to fetch book file for cover generation", "error"); - return null; - } - - const blob = await resp.blob(); - const file = new File([blob], "book", { type: blob.type }); - - const pdfOptions = - formatGroup === "fixed_layout" - ? { - pdf: { - cMapUrl: "/static/vendor/pdfjs/cmaps/", - standardFontDataUrl: "/static/vendor/pdfjs/standard_fonts/", - }, - } - : {}; - - await view.open(file, pdfOptions); - - if (!view.book?.sections?.length) { - showToast("Could not read book sections", "error"); - return null; - } - - if (formatGroup === "fixed_layout") { - const canvas = document.createElement("canvas"); - await view.renderer?.renderPage(view.book.sections[0], canvas); - return new Promise((resolve) => { - canvas.toBlob( - (b) => resolve(b), - "image/jpeg", - 0.85, - ); - }); - } - - const coverHref = view.book.cover; - if (coverHref) { - const coverBlob = await coverHref.blob(); - if (coverBlob.type.startsWith("image/")) { - return coverBlob; - } - return new Promise((resolve) => { - const img = new Image(); - img.onload = () => { - const c = document.createElement("canvas"); - c.width = img.naturalWidth; - c.height = img.naturalHeight; - c.getContext("2d")?.drawImage(img, 0, 0); - c.toBlob((b) => resolve(b), "image/jpeg", 0.85); - }; - img.onerror = () => resolve(null); - img.src = URL.createObjectURL(coverBlob); - }); - } - - showToast("No cover found in book file", "error"); - return null; - } catch (e) { - console.error("Cover generation failed:", e); - showToast("Cover generation failed", "error"); - return null; - } -}