diff --git a/enjoy/package.json b/enjoy/package.json index fe909144..2fe5d272 100644 --- a/enjoy/package.json +++ b/enjoy/package.json @@ -85,7 +85,7 @@ "@types/mark.js": "^8.11.12", "@types/mime-types": "^2.1.4", "@types/mustache": "^4.2.5", - "@types/node": "^22.10.0", + "@types/node": "^22.10.1", "@types/prop-types": "^15.7.13", "@types/rails__actioncable": "^6.1.11", "@types/react": "^18.3.12", @@ -106,13 +106,13 @@ "axios": "^1.7.8", "camelcase": "^8.0.0", "camelcase-keys": "^9.1.3", - "chart.js": "^4.4.6", + "chart.js": "^4.4.7", "cheerio": "^1.0.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.0.4", "command-exists": "^1.2.9", - "compromise": "^14.14.2", + "compromise": "^14.14.3", "compromise-paragraphs": "^0.1.0", "compromise-stats": "^0.1.0", "dayjs": "^1.11.13", @@ -127,7 +127,7 @@ "electron-playwright-helpers": "^1.7.1", "electron-squirrel-startup": "^1.0.1", "electron-unhandled": "^5.0.0", - "eslint": "^9.15.0", + "eslint": "^9.16.0", "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-import": "^2.31.0", "flora-colossus": "^2.0.0", @@ -136,7 +136,7 @@ "https-proxy-agent": "^7.0.5", "i18next": "^24.0.2", "input-otp": "^1.4.1", - "intl-tel-input": "^24.7.0", + "intl-tel-input": "^24.8.1", "js-md5": "^0.8.3", "langchain": "^0.3.6", "lodash": "^4.17.21", @@ -164,7 +164,7 @@ "react-frame-component": "^5.2.7", "react-hook-form": "^7.53.2", "react-hotkeys-hook": "^4.6.1", - "react-i18next": "^15.1.2", + "react-i18next": "^15.1.3", "react-markdown": "^9.0.1", "react-resizable-panels": "^2.1.7", "react-router-dom": "^7.0.1", @@ -189,7 +189,7 @@ "wavesurfer.js": "^7.8.9", "zod": "^3.23.8", "zod-to-json-schema": "^3.23.5", - "zx": "^8.2.2" + "zx": "^8.2.4" }, "dependencies": { "@andrkrn/ffprobe-static": "^5.2.0", diff --git a/enjoy/src/renderer/components/documents/document-actions-button.tsx b/enjoy/src/renderer/components/documents/document-actions-button.tsx new file mode 100644 index 00000000..0c722721 --- /dev/null +++ b/enjoy/src/renderer/components/documents/document-actions-button.tsx @@ -0,0 +1,69 @@ +import { + Button, + DropdownMenu, + DropdownMenuItem, + DropdownMenuContent, + DropdownMenuTrigger, + toast, +} from "@renderer/components/ui"; +import { MoreVerticalIcon } from "lucide-react"; +import { t } from "i18next"; +import { useContext } from "react"; +import { + AppSettingsProviderContext, + DocumentProviderContext, +} from "@renderer/context"; +import template from "./document.template.html?raw"; + +export const DocumentActionsButton = (props: { document: DocumentEType }) => { + const { document } = props; + const { EnjoyApp } = useContext(AppSettingsProviderContext); + const { ref, section } = useContext(DocumentProviderContext); + + const handlePrint = async () => { + if (!ref.current) return; + + const content = template.replace("$title", document.title).replace( + "$content", + Array.from(ref.current.querySelectorAll(".segment, .translation")) + .map((segment) => { + const tagName = segment.tagName.toLowerCase(); + if (segment.classList.contains("translation")) { + return `<${tagName}>${segment.textContent}`; + } + return `<${tagName}>${ + segment.querySelector(".segment-content")?.textContent + }`; + }) + .join("") + ); + + try { + const savePath = await EnjoyApp.dialog.showSaveDialog({ + title: t("print"), + defaultPath: `${document.title}(S${section}).pdf`, + }); + + if (!savePath) return; + + await EnjoyApp.download.printAsPdf(content, savePath); + + toast.success(t("downloadedSuccessfully")); + } catch (err) { + toast.error(`${t("downloadFailed")}: ${err.message}`); + } + }; + + return ( + + + + + + {t("print")} + + + ); +}; diff --git a/enjoy/src/renderer/components/documents/document-epub-renderer.tsx b/enjoy/src/renderer/components/documents/document-epub-renderer.tsx index 99ef4a22..d472636c 100644 --- a/enjoy/src/renderer/components/documents/document-epub-renderer.tsx +++ b/enjoy/src/renderer/components/documents/document-epub-renderer.tsx @@ -1,5 +1,6 @@ import { useCallback, useContext, useEffect, useState } from "react"; import { + DocumentActionsButton, DocumentConfigButton, LoaderSpin, MarkdownWrapper, @@ -16,7 +17,12 @@ import { Button, toast, } from "@renderer/components/ui"; -import { ChevronLeftIcon, ChevronRightIcon, MenuIcon } from "lucide-react"; +import { + ChevronLeftIcon, + ChevronRightIcon, + MenuIcon, + TableOfContentsIcon, +} from "lucide-react"; import { AppSettingsProviderContext, DocumentProviderContext, @@ -145,7 +151,7 @@ export const DocumentEpubRenderer = () => { { +
{title}
@@ -202,7 +209,7 @@ export const DocumentEpubRenderer = () => { ) : ( {
+
{title} @@ -71,7 +73,7 @@ export const DocumentHtmlRenderer = () => {
{
+
{document.title} @@ -53,7 +55,7 @@ export const DocumentTextRenderer = () => {
+ + + + + $title + + + +
$content
+ + diff --git a/enjoy/src/renderer/components/documents/index.ts b/enjoy/src/renderer/components/documents/index.ts index a96ae7b7..94172937 100644 --- a/enjoy/src/renderer/components/documents/index.ts +++ b/enjoy/src/renderer/components/documents/index.ts @@ -7,3 +7,4 @@ export * from "./document-config-form"; export * from "./document-add-button"; export * from "./document-config-button"; export * from "./documents-segment"; +export * from "./document-actions-button"; diff --git a/enjoy/src/renderer/components/misc/markdown-wrapper.tsx b/enjoy/src/renderer/components/misc/markdown-wrapper.tsx index da4a1503..50930330 100644 --- a/enjoy/src/renderer/components/misc/markdown-wrapper.tsx +++ b/enjoy/src/renderer/components/misc/markdown-wrapper.tsx @@ -171,7 +171,7 @@ const Segment = memo( {children} {translation && ( - + {translation}