@burdenoff/microfe-files 2026.802.1 → 2026.830.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/files/FilesRoot.d.ts.map +1 -1
- package/dist/files/FilesRoot.js +42 -37
- package/dist/files/FilesRoot.js.map +1 -1
- package/dist/files/components/StorageBanner.d.ts.map +1 -1
- package/dist/files/components/StorageBanner.js +50 -41
- package/dist/files/components/StorageBanner.js.map +1 -1
- package/dist/files/components/viewers/AudioPlayer.d.ts.map +1 -1
- package/dist/files/components/viewers/AudioPlayer.js +59 -58
- package/dist/files/components/viewers/AudioPlayer.js.map +1 -1
- package/dist/files/components/viewers/CodeViewer.d.ts.map +1 -1
- package/dist/files/components/viewers/CodeViewer.js +49 -44
- package/dist/files/components/viewers/CodeViewer.js.map +1 -1
- package/dist/files/components/viewers/ImageViewer.d.ts.map +1 -1
- package/dist/files/components/viewers/ImageViewer.js +75 -74
- package/dist/files/components/viewers/ImageViewer.js.map +1 -1
- package/dist/files/components/viewers/PDFViewer.d.ts.map +1 -1
- package/dist/files/components/viewers/PDFViewer.js +44 -41
- package/dist/files/components/viewers/PDFViewer.js.map +1 -1
- package/dist/files/components/viewers/TextViewer.d.ts.map +1 -1
- package/dist/files/components/viewers/TextViewer.js +77 -72
- package/dist/files/components/viewers/TextViewer.js.map +1 -1
- package/dist/files/components/viewers/VideoPlayer.d.ts.map +1 -1
- package/dist/files/components/viewers/VideoPlayer.js +75 -74
- package/dist/files/components/viewers/VideoPlayer.js.map +1 -1
- package/dist/shared/hooks/useTr.d.ts +17 -0
- package/dist/shared/hooks/useTr.d.ts.map +1 -0
- package/dist/shared/hooks/useTr.js +14 -0
- package/dist/shared/hooks/useTr.js.map +1 -0
- package/dist/translations/en.d.ts +85 -0
- package/dist/translations/en.d.ts.map +1 -1
- package/dist/translations/en.js +84 -1
- package/dist/translations/en.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,86 +1,91 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useTr as e } from "../../../shared/hooks/useTr.js";
|
|
2
|
+
import { useEffect as t, useState as n } from "react";
|
|
3
|
+
import { Check as r, Copy as i, WrapText as a } from "lucide-react";
|
|
4
|
+
import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
4
5
|
//#region src/files/components/viewers/CodeViewer.tsx
|
|
5
|
-
function
|
|
6
|
-
let [
|
|
7
|
-
return
|
|
8
|
-
fetch(
|
|
9
|
-
|
|
6
|
+
function l({ file: l, url: d, language: f }) {
|
|
7
|
+
let p = e(), [m, h] = n(""), [g, _] = n(!0), [v, y] = n(!1), [b, x] = n(!1), S = f || u(l.name);
|
|
8
|
+
return t(() => {
|
|
9
|
+
fetch(d).then((e) => e.text()).then((e) => {
|
|
10
|
+
h(e), _(!1);
|
|
10
11
|
}).catch(() => {
|
|
11
|
-
|
|
12
|
+
_(!1);
|
|
12
13
|
});
|
|
13
|
-
}, [
|
|
14
|
-
if (
|
|
15
|
-
let e = setTimeout(() =>
|
|
14
|
+
}, [d]), t(() => {
|
|
15
|
+
if (b) {
|
|
16
|
+
let e = setTimeout(() => x(!1), 2e3);
|
|
16
17
|
return () => clearTimeout(e);
|
|
17
18
|
}
|
|
18
|
-
}, [
|
|
19
|
+
}, [b]), g ? /* @__PURE__ */ s("div", {
|
|
19
20
|
className: "flex items-center justify-center h-full bg-bg-canvas",
|
|
20
|
-
children: /* @__PURE__ */
|
|
21
|
+
children: /* @__PURE__ */ s("span", {
|
|
21
22
|
className: "text-text-secondary",
|
|
22
|
-
children: "Loading code..."
|
|
23
|
+
children: p("files.preview.code.loading", "Loading code...")
|
|
23
24
|
})
|
|
24
|
-
}) : /* @__PURE__ */
|
|
25
|
+
}) : /* @__PURE__ */ c("div", {
|
|
25
26
|
className: "flex flex-col h-full bg-bg-canvas",
|
|
26
27
|
children: [
|
|
27
|
-
/* @__PURE__ */
|
|
28
|
+
/* @__PURE__ */ c("div", {
|
|
28
29
|
className: "flex items-center justify-between p-3 bg-bg-surface border-b border-border-default",
|
|
29
|
-
children: [/* @__PURE__ */
|
|
30
|
+
children: [/* @__PURE__ */ c("div", {
|
|
30
31
|
className: "flex items-center gap-2",
|
|
31
|
-
children: [/* @__PURE__ */
|
|
32
|
+
children: [/* @__PURE__ */ s("span", {
|
|
32
33
|
className: "px-2 py-1 text-xs font-medium text-text-link bg-bg-accent rounded",
|
|
33
|
-
children:
|
|
34
|
-
}), /* @__PURE__ */
|
|
34
|
+
children: S || p("files.preview.code.text", "Text")
|
|
35
|
+
}), /* @__PURE__ */ s("span", {
|
|
35
36
|
className: "text-sm text-text-secondary",
|
|
36
|
-
children:
|
|
37
|
+
children: l.name
|
|
37
38
|
})]
|
|
38
|
-
}), /* @__PURE__ */
|
|
39
|
+
}), /* @__PURE__ */ c("div", {
|
|
39
40
|
className: "flex items-center gap-2",
|
|
40
|
-
children: [/* @__PURE__ */
|
|
41
|
+
children: [/* @__PURE__ */ s("button", {
|
|
41
42
|
type: "button",
|
|
42
|
-
onClick: () =>
|
|
43
|
-
className: `p-2 rounded transition-colors duration-200 ${
|
|
44
|
-
title:
|
|
45
|
-
"aria-label":
|
|
46
|
-
children: /* @__PURE__ */
|
|
47
|
-
}), /* @__PURE__ */
|
|
43
|
+
onClick: () => y(!v),
|
|
44
|
+
className: `p-2 rounded transition-colors duration-200 ${v ? "text-text-link bg-bg-accent" : "text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover"}`,
|
|
45
|
+
title: v ? p("files.preview.code.disableWordWrap", "Disable word wrap") : p("files.preview.code.enableWordWrap", "Enable word wrap"),
|
|
46
|
+
"aria-label": v ? p("files.preview.code.disableWordWrap", "Disable word wrap") : p("files.preview.code.enableWordWrap", "Enable word wrap"),
|
|
47
|
+
children: /* @__PURE__ */ s(a, { className: "size-4" })
|
|
48
|
+
}), /* @__PURE__ */ s("button", {
|
|
48
49
|
type: "button",
|
|
49
50
|
onClick: () => {
|
|
50
|
-
navigator.clipboard.writeText(
|
|
51
|
+
navigator.clipboard.writeText(m), x(!0);
|
|
51
52
|
},
|
|
52
53
|
className: "flex items-center gap-1.5 rounded px-3 py-1.5 text-sm font-medium text-text-inverse bg-action-primary-bg transition-colors duration-200 hover:bg-action-primary-bg-hover",
|
|
53
|
-
title: "Copy code",
|
|
54
|
-
"aria-label": "Copy code content",
|
|
55
|
-
children:
|
|
54
|
+
title: p("files.preview.code.copyCode", "Copy code"),
|
|
55
|
+
"aria-label": p("files.preview.code.copyCodeContent", "Copy code content"),
|
|
56
|
+
children: b ? /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(r, { className: "size-4" }), p("files.preview.code.copied", "Copied!")] }) : /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(i, { className: "size-4" }), p("files.preview.code.copy", "Copy")] })
|
|
56
57
|
})]
|
|
57
58
|
})]
|
|
58
59
|
}),
|
|
59
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ s("div", {
|
|
60
61
|
className: "flex-1 overflow-auto",
|
|
61
|
-
children: /* @__PURE__ */
|
|
62
|
-
className: `p-4 text-sm font-mono leading-relaxed ${
|
|
62
|
+
children: /* @__PURE__ */ s("pre", {
|
|
63
|
+
className: `p-4 text-sm font-mono leading-relaxed ${v ? "whitespace-pre-wrap" : "whitespace-pre"}`,
|
|
63
64
|
style: { tabSize: 2 },
|
|
64
|
-
children:
|
|
65
|
+
children: m.split("\n").map((e, t) => /* @__PURE__ */ c("div", {
|
|
65
66
|
className: "flex",
|
|
66
|
-
children: [/* @__PURE__ */
|
|
67
|
+
children: [/* @__PURE__ */ s("span", {
|
|
67
68
|
className: "inline-block w-12 text-right pr-4 text-text-tertiary select-none",
|
|
68
69
|
children: t + 1
|
|
69
|
-
}), /* @__PURE__ */
|
|
70
|
+
}), /* @__PURE__ */ s("span", {
|
|
70
71
|
className: "text-text-primary",
|
|
71
72
|
children: e || " "
|
|
72
73
|
})]
|
|
73
74
|
}, t))
|
|
74
75
|
})
|
|
75
76
|
}),
|
|
76
|
-
/* @__PURE__ */
|
|
77
|
+
/* @__PURE__ */ c("div", {
|
|
77
78
|
className: "flex items-center justify-between p-3 bg-bg-surface border-t border-border-default text-xs text-text-secondary",
|
|
78
|
-
children: [/* @__PURE__ */
|
|
79
|
+
children: [/* @__PURE__ */ c("span", { children: [
|
|
80
|
+
m.split("\n").length,
|
|
81
|
+
" ",
|
|
82
|
+
p("files.preview.code.lines", "lines")
|
|
83
|
+
] }), /* @__PURE__ */ c("span", { children: [(l.size / 1024).toFixed(2), " KB"] })]
|
|
79
84
|
})
|
|
80
85
|
]
|
|
81
86
|
});
|
|
82
87
|
}
|
|
83
|
-
function
|
|
88
|
+
function u(e) {
|
|
84
89
|
return {
|
|
85
90
|
js: "JavaScript",
|
|
86
91
|
jsx: "React JSX",
|
|
@@ -115,6 +120,6 @@ function l(e) {
|
|
|
115
120
|
}[e.split(".").pop()?.toLowerCase() || ""] || "Text";
|
|
116
121
|
}
|
|
117
122
|
//#endregion
|
|
118
|
-
export {
|
|
123
|
+
export { l as CodeViewer };
|
|
119
124
|
|
|
120
125
|
//# sourceMappingURL=CodeViewer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeViewer.js","names":[],"sources":["../../../../src/files/components/viewers/CodeViewer.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { Copy, Check, WrapText } from \"lucide-react\";\nimport type { FileItem } from \"../../types\";\n\ninterface CodeViewerProps {\n file: FileItem;\n url: string;\n language?: string;\n}\n\n/**\n * CodeViewer - Displays code files with syntax highlighting\n *\n * Note: This is a simplified implementation with basic highlighting.\n * For full syntax highlighting, install prism-react-renderer:\n * bun add prism-react-renderer\n */\nexport function CodeViewer({ file, url, language }: CodeViewerProps) {\n const [code, setCode] = useState(\"\");\n const [loading, setLoading] = useState(true);\n const [wordWrap, setWordWrap] = useState(false);\n const [copied, setCopied] = useState(false);\n\n const detectedLanguage = language || detectLanguage(file.name);\n\n useEffect(() => {\n fetch(url)\n .then((res) => res.text())\n .then((text) => {\n setCode(text);\n setLoading(false);\n })\n .catch(() => {\n setLoading(false);\n });\n }, [url]);\n\n const handleCopy = () => {\n navigator.clipboard.writeText(code);\n setCopied(true);\n };\n\n // Cleanup timeout on unmount to prevent React state update warning\n useEffect(() => {\n if (copied) {\n const timer = setTimeout(() => setCopied(false), 2000);\n return () => clearTimeout(timer);\n }\n return undefined;\n }, [copied]);\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center h-full bg-bg-canvas\">\n <span className=\"text-text-secondary\"
|
|
1
|
+
{"version":3,"file":"CodeViewer.js","names":[],"sources":["../../../../src/files/components/viewers/CodeViewer.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { Copy, Check, WrapText } from \"lucide-react\";\nimport type { FileItem } from \"../../types\";\nimport { useTr } from \"../../../shared/hooks/useTr\";\n\ninterface CodeViewerProps {\n file: FileItem;\n url: string;\n language?: string;\n}\n\n/**\n * CodeViewer - Displays code files with syntax highlighting\n *\n * Note: This is a simplified implementation with basic highlighting.\n * For full syntax highlighting, install prism-react-renderer:\n * bun add prism-react-renderer\n */\nexport function CodeViewer({ file, url, language }: CodeViewerProps) {\n const tr = useTr();\n const [code, setCode] = useState(\"\");\n const [loading, setLoading] = useState(true);\n const [wordWrap, setWordWrap] = useState(false);\n const [copied, setCopied] = useState(false);\n\n const detectedLanguage = language || detectLanguage(file.name);\n\n useEffect(() => {\n fetch(url)\n .then((res) => res.text())\n .then((text) => {\n setCode(text);\n setLoading(false);\n })\n .catch(() => {\n setLoading(false);\n });\n }, [url]);\n\n const handleCopy = () => {\n navigator.clipboard.writeText(code);\n setCopied(true);\n };\n\n // Cleanup timeout on unmount to prevent React state update warning\n useEffect(() => {\n if (copied) {\n const timer = setTimeout(() => setCopied(false), 2000);\n return () => clearTimeout(timer);\n }\n return undefined;\n }, [copied]);\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center h-full bg-bg-canvas\">\n <span className=\"text-text-secondary\">\n {tr(\"files.preview.code.loading\", \"Loading code...\")}\n </span>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full bg-bg-canvas\">\n {/* Toolbar */}\n <div className=\"flex items-center justify-between p-3 bg-bg-surface border-b border-border-default\">\n <div className=\"flex items-center gap-2\">\n <span className=\"px-2 py-1 text-xs font-medium text-text-link bg-bg-accent rounded\">\n {detectedLanguage || tr(\"files.preview.code.text\", \"Text\")}\n </span>\n <span className=\"text-sm text-text-secondary\">{file.name}</span>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setWordWrap(!wordWrap)}\n className={`p-2 rounded transition-colors duration-200 ${\n wordWrap\n ? \"text-text-link bg-bg-accent\"\n : \"text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover\"\n }`}\n title={\n wordWrap\n ? tr(\"files.preview.code.disableWordWrap\", \"Disable word wrap\")\n : tr(\"files.preview.code.enableWordWrap\", \"Enable word wrap\")\n }\n aria-label={\n wordWrap\n ? tr(\"files.preview.code.disableWordWrap\", \"Disable word wrap\")\n : tr(\"files.preview.code.enableWordWrap\", \"Enable word wrap\")\n }\n >\n <WrapText className=\"size-4\" />\n </button>\n\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"flex items-center gap-1.5 rounded px-3 py-1.5 text-sm font-medium text-text-inverse bg-action-primary-bg transition-colors duration-200 hover:bg-action-primary-bg-hover\"\n title={tr(\"files.preview.code.copyCode\", \"Copy code\")}\n aria-label={tr(\n \"files.preview.code.copyCodeContent\",\n \"Copy code content\",\n )}\n >\n {copied ? (\n <>\n <Check className=\"size-4\" />\n {tr(\"files.preview.code.copied\", \"Copied!\")}\n </>\n ) : (\n <>\n <Copy className=\"size-4\" />\n {tr(\"files.preview.code.copy\", \"Copy\")}\n </>\n )}\n </button>\n </div>\n </div>\n\n {/* Code Content */}\n <div className=\"flex-1 overflow-auto\">\n <pre\n className={`p-4 text-sm font-mono leading-relaxed ${\n wordWrap ? \"whitespace-pre-wrap\" : \"whitespace-pre\"\n }`}\n style={{ tabSize: 2 }}\n >\n {code.split(\"\\n\").map((line, i) => (\n <div key={i} className=\"flex\">\n <span className=\"inline-block w-12 text-right pr-4 text-text-tertiary select-none\">\n {i + 1}\n </span>\n <span className=\"text-text-primary\">{line || \" \"}</span>\n </div>\n ))}\n </pre>\n </div>\n\n {/* Footer */}\n <div className=\"flex items-center justify-between p-3 bg-bg-surface border-t border-border-default text-xs text-text-secondary\">\n <span>\n {code.split(\"\\n\").length} {tr(\"files.preview.code.lines\", \"lines\")}\n </span>\n <span>{(file.size / 1024).toFixed(2)} KB</span>\n </div>\n </div>\n );\n}\n\nfunction detectLanguage(filename: string): string {\n const ext = filename.split(\".\").pop()?.toLowerCase();\n const languageMap: Record<string, string> = {\n js: \"JavaScript\",\n jsx: \"React JSX\",\n ts: \"TypeScript\",\n tsx: \"React TSX\",\n py: \"Python\",\n java: \"Java\",\n cpp: \"C++\",\n c: \"C\",\n cs: \"C#\",\n rb: \"Ruby\",\n go: \"Go\",\n rs: \"Rust\",\n php: \"PHP\",\n html: \"HTML\",\n css: \"CSS\",\n scss: \"SCSS\",\n json: \"JSON\",\n md: \"Markdown\",\n yaml: \"YAML\",\n yml: \"YAML\",\n xml: \"XML\",\n sql: \"SQL\",\n sh: \"Shell\",\n bash: \"Bash\",\n vue: \"Vue\",\n swift: \"Swift\",\n kt: \"Kotlin\",\n r: \"R\",\n dart: \"Dart\",\n lua: \"Lua\",\n };\n return languageMap[ext || \"\"] || \"Text\";\n}\n"],"mappings":";;;;;AAkBA,SAAgB,EAAW,EAAE,SAAM,QAAK,eAA6B;CACnE,IAAM,IAAK,GAAO,EACZ,CAAC,GAAM,KAAW,EAAS,GAAG,EAC9B,CAAC,GAAS,KAAc,EAAS,GAAK,EACtC,CAAC,GAAU,KAAe,EAAS,GAAM,EACzC,CAAC,GAAQ,KAAa,EAAS,GAAM,EAErC,IAAmB,KAAY,EAAe,EAAK,KAAK;AAsC9D,QApCA,QAAgB;AACd,QAAM,EAAI,CACP,MAAM,MAAQ,EAAI,MAAM,CAAC,CACzB,MAAM,MAAS;AAEd,GADA,EAAQ,EAAK,EACb,EAAW,GAAM;IACjB,CACD,YAAY;AACX,KAAW,GAAM;IACjB;IACH,CAAC,EAAI,CAAC,EAQT,QAAgB;AACd,MAAI,GAAQ;GACV,IAAM,IAAQ,iBAAiB,EAAU,GAAM,EAAE,IAAK;AACtD,gBAAa,aAAa,EAAM;;IAGjC,CAAC,EAAO,CAAC,EAER,IAEA,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,QAAD;GAAM,WAAU;aACb,EAAG,8BAA8B,kBAAkB;GAC/C,CAAA;EACH,CAAA,GAKR,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD;MAAM,WAAU;gBACb,KAAoB,EAAG,2BAA2B,OAAO;MACrD,CAAA,EACP,kBAAC,QAAD;MAAM,WAAU;gBAA+B,EAAK;MAAY,CAAA,CAC5D;QAEN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAY,CAAC,EAAS;MACrC,WAAW,8CACT,IACI,gCACA;MAEN,OACE,IACI,EAAG,sCAAsC,oBAAoB,GAC7D,EAAG,qCAAqC,mBAAmB;MAEjE,cACE,IACI,EAAG,sCAAsC,oBAAoB,GAC7D,EAAG,qCAAqC,mBAAmB;gBAGjE,kBAAC,GAAD,EAAU,WAAU,UAAW,CAAA;MACxB,CAAA,EAET,kBAAC,UAAD;MACE,MAAK;MACL,eA5De;AAEvB,OADA,UAAU,UAAU,UAAU,EAAK,EACnC,EAAU,GAAK;;MA2DP,WAAU;MACV,OAAO,EAAG,+BAA+B,YAAY;MACrD,cAAY,EACV,sCACA,oBACD;gBAEA,IACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA,EAC3B,EAAG,6BAA6B,UAAU,CAC1C,EAAA,CAAA,GAEH,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,EAC1B,EAAG,2BAA2B,OAAO,CACrC,EAAA,CAAA;MAEE,CAAA,CACL;OACF;;GAGN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KACE,WAAW,yCACT,IAAW,wBAAwB;KAErC,OAAO,EAAE,SAAS,GAAG;eAEpB,EAAK,MAAM,KAAK,CAAC,KAAK,GAAM,MAC3B,kBAAC,OAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,QAAD;OAAM,WAAU;iBACb,IAAI;OACA,CAAA,EACP,kBAAC,QAAD;OAAM,WAAU;iBAAqB,KAAQ;OAAW,CAAA,CACpD;QALI,EAKJ,CACN;KACE,CAAA;IACF,CAAA;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD,EAAA,UAAA;KACG,EAAK,MAAM,KAAK,CAAC;KAAO;KAAE,EAAG,4BAA4B,QAAQ;KAC7D,EAAA,CAAA,EACP,kBAAC,QAAD,EAAA,UAAA,EAAQ,EAAK,OAAO,MAAM,QAAQ,EAAE,EAAC,MAAU,EAAA,CAAA,CAC3C;;GACF;;;AAIV,SAAS,EAAe,GAA0B;AAkChD,QAhC4C;EAC1C,IAAI;EACJ,KAAK;EACL,IAAI;EACJ,KAAK;EACL,IAAI;EACJ,MAAM;EACN,KAAK;EACL,GAAG;EACH,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,KAAK;EACL,MAAM;EACN,KAAK;EACL,MAAM;EACN,MAAM;EACN,IAAI;EACJ,MAAM;EACN,KAAK;EACL,KAAK;EACL,KAAK;EACL,IAAI;EACJ,MAAM;EACN,KAAK;EACL,OAAO;EACP,IAAI;EACJ,GAAG;EACH,MAAM;EACN,KAAK;EACN,CAhCW,EAAS,MAAM,IAAI,CAAC,KAAK,EAAE,aAAa,IAiC1B,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageViewer.d.ts","sourceRoot":"","sources":["../../../../src/files/components/viewers/ImageViewer.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ImageViewer.d.ts","sourceRoot":"","sources":["../../../../src/files/components/viewers/ImageViewer.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,UAAU,gBAAgB;IACxB,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,gBAAgB,+BAoK1D"}
|
|
@@ -1,142 +1,143 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useTr as e } from "../../../shared/hooks/useTr.js";
|
|
2
|
+
import { useRef as t, useState as n } from "react";
|
|
3
|
+
import { AlertCircle as r, Minimize2 as i, RotateCw as a, ZoomIn as o, ZoomOut as s } from "lucide-react";
|
|
4
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
4
5
|
//#region src/files/components/viewers/ImageViewer.tsx
|
|
5
|
-
function
|
|
6
|
-
let [
|
|
6
|
+
function u({ file: u, url: d }) {
|
|
7
|
+
let f = e(), [p, m] = n(1), [h, g] = n(0), [_, v] = n({
|
|
7
8
|
x: 0,
|
|
8
9
|
y: 0
|
|
9
|
-
}), [
|
|
10
|
+
}), [y, b] = n(!1), [x, S] = n({
|
|
10
11
|
x: 0,
|
|
11
12
|
y: 0
|
|
12
|
-
}), [
|
|
13
|
+
}), [C, w] = n(null), T = t(null), [E, D] = n({
|
|
13
14
|
width: 0,
|
|
14
15
|
height: 0
|
|
15
|
-
}),
|
|
16
|
-
|
|
16
|
+
}), O = () => m((e) => Math.min(e + .25, 4)), k = () => m((e) => Math.max(e - .25, .25)), A = () => {
|
|
17
|
+
m(1), v({
|
|
17
18
|
x: 0,
|
|
18
19
|
y: 0
|
|
19
|
-
}),
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
x: e.clientX -
|
|
23
|
-
y: e.clientY -
|
|
20
|
+
}), g(0);
|
|
21
|
+
}, j = () => g((e) => (e + 90) % 360), M = (e) => {
|
|
22
|
+
p > 1 && (b(!0), S({
|
|
23
|
+
x: e.clientX - _.x,
|
|
24
|
+
y: e.clientY - _.y
|
|
24
25
|
}));
|
|
25
|
-
},
|
|
26
|
-
|
|
27
|
-
x: e.clientX -
|
|
28
|
-
y: e.clientY -
|
|
26
|
+
}, N = (e) => {
|
|
27
|
+
y && p > 1 && v({
|
|
28
|
+
x: e.clientX - x.x,
|
|
29
|
+
y: e.clientY - x.y
|
|
29
30
|
});
|
|
30
|
-
},
|
|
31
|
-
|
|
31
|
+
}, P = () => {
|
|
32
|
+
b(!1);
|
|
32
33
|
};
|
|
33
|
-
return /* @__PURE__ */
|
|
34
|
+
return /* @__PURE__ */ l("div", {
|
|
34
35
|
className: "flex flex-col h-full bg-bg-canvas",
|
|
35
36
|
children: [
|
|
36
|
-
/* @__PURE__ */
|
|
37
|
+
/* @__PURE__ */ l("div", {
|
|
37
38
|
className: "flex items-center justify-center gap-2 p-4 bg-bg-surface border-b border-border-default",
|
|
38
39
|
children: [
|
|
39
|
-
/* @__PURE__ */
|
|
40
|
+
/* @__PURE__ */ c("button", {
|
|
40
41
|
type: "button",
|
|
41
|
-
onClick:
|
|
42
|
-
disabled:
|
|
42
|
+
onClick: k,
|
|
43
|
+
disabled: p <= .25,
|
|
43
44
|
className: "p-2 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
44
|
-
title: "Zoom out",
|
|
45
|
-
children: /* @__PURE__ */ s
|
|
45
|
+
title: f("files.preview.image.zoomOut", "Zoom out"),
|
|
46
|
+
children: /* @__PURE__ */ c(s, { className: "size-5" })
|
|
46
47
|
}),
|
|
47
|
-
/* @__PURE__ */
|
|
48
|
+
/* @__PURE__ */ l("span", {
|
|
48
49
|
className: "min-w-16 text-center text-sm font-medium text-text-primary",
|
|
49
|
-
children: [Math.round(
|
|
50
|
+
children: [Math.round(p * 100), "%"]
|
|
50
51
|
}),
|
|
51
|
-
/* @__PURE__ */
|
|
52
|
+
/* @__PURE__ */ c("button", {
|
|
52
53
|
type: "button",
|
|
53
|
-
onClick:
|
|
54
|
-
disabled:
|
|
54
|
+
onClick: O,
|
|
55
|
+
disabled: p >= 4,
|
|
55
56
|
className: "p-2 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
56
|
-
title: "Zoom in",
|
|
57
|
-
children: /* @__PURE__ */
|
|
57
|
+
title: f("files.preview.image.zoomIn", "Zoom in"),
|
|
58
|
+
children: /* @__PURE__ */ c(o, { className: "size-5" })
|
|
58
59
|
}),
|
|
59
|
-
/* @__PURE__ */
|
|
60
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ c("div", { className: "w-px h-6 bg-border-default mx-2" }),
|
|
61
|
+
/* @__PURE__ */ c("button", {
|
|
61
62
|
type: "button",
|
|
62
|
-
onClick:
|
|
63
|
+
onClick: A,
|
|
63
64
|
className: "p-2 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200",
|
|
64
|
-
title: "Fit to screen",
|
|
65
|
-
children: /* @__PURE__ */
|
|
65
|
+
title: f("files.preview.image.fitToScreen", "Fit to screen"),
|
|
66
|
+
children: /* @__PURE__ */ c(i, { className: "size-5" })
|
|
66
67
|
}),
|
|
67
|
-
/* @__PURE__ */
|
|
68
|
+
/* @__PURE__ */ c("button", {
|
|
68
69
|
type: "button",
|
|
69
|
-
onClick:
|
|
70
|
+
onClick: j,
|
|
70
71
|
className: "p-2 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200",
|
|
71
|
-
title: "Rotate 90°",
|
|
72
|
-
children: /* @__PURE__ */
|
|
72
|
+
title: f("files.preview.image.rotate", "Rotate 90°"),
|
|
73
|
+
children: /* @__PURE__ */ c(a, { className: "size-5" })
|
|
73
74
|
})
|
|
74
75
|
]
|
|
75
76
|
}),
|
|
76
|
-
/* @__PURE__ */
|
|
77
|
+
/* @__PURE__ */ l("div", {
|
|
77
78
|
className: "flex-1 overflow-hidden flex items-center justify-center relative",
|
|
78
|
-
onMouseDown:
|
|
79
|
-
onMouseMove:
|
|
80
|
-
onMouseUp:
|
|
81
|
-
onMouseLeave:
|
|
82
|
-
style: { cursor:
|
|
83
|
-
children: [/* @__PURE__ */
|
|
84
|
-
ref:
|
|
85
|
-
src:
|
|
86
|
-
alt:
|
|
79
|
+
onMouseDown: M,
|
|
80
|
+
onMouseMove: N,
|
|
81
|
+
onMouseUp: P,
|
|
82
|
+
onMouseLeave: P,
|
|
83
|
+
style: { cursor: p > 1 ? y ? "grabbing" : "grab" : "default" },
|
|
84
|
+
children: [/* @__PURE__ */ c("img", {
|
|
85
|
+
ref: T,
|
|
86
|
+
src: d,
|
|
87
|
+
alt: u.name,
|
|
87
88
|
onLoad: () => {
|
|
88
|
-
|
|
89
|
-
width:
|
|
90
|
-
height:
|
|
89
|
+
T.current && D({
|
|
90
|
+
width: T.current.naturalWidth,
|
|
91
|
+
height: T.current.naturalHeight
|
|
91
92
|
});
|
|
92
93
|
},
|
|
93
94
|
onError: () => {
|
|
94
|
-
|
|
95
|
+
w(f("files.preview.image.loadError", "Failed to load image from URL"));
|
|
95
96
|
},
|
|
96
97
|
draggable: !1,
|
|
97
98
|
className: "max-w-full max-h-full object-contain transition-transform duration-200",
|
|
98
99
|
style: {
|
|
99
|
-
transform: `scale(${
|
|
100
|
+
transform: `scale(${p}) rotate(${h}deg) translate(${_.x / p}px, ${_.y / p}px)`,
|
|
100
101
|
userSelect: "none"
|
|
101
102
|
}
|
|
102
|
-
}),
|
|
103
|
+
}), C && /* @__PURE__ */ l("div", {
|
|
103
104
|
className: "absolute inset-0 flex flex-col items-center justify-center bg-bg-canvas/90 z-10",
|
|
104
105
|
children: [
|
|
105
|
-
/* @__PURE__ */
|
|
106
|
-
/* @__PURE__ */
|
|
106
|
+
/* @__PURE__ */ c(r, { className: "size-12 text-status-error-text mb-4" }),
|
|
107
|
+
/* @__PURE__ */ c("p", {
|
|
107
108
|
className: "text-text-primary font-medium mb-2",
|
|
108
|
-
children: "Failed to load image"
|
|
109
|
+
children: f("files.preview.image.failedToLoad", "Failed to load image")
|
|
109
110
|
}),
|
|
110
|
-
/* @__PURE__ */
|
|
111
|
+
/* @__PURE__ */ c("p", {
|
|
111
112
|
className: "text-text-secondary text-sm max-w-md text-center px-4",
|
|
112
|
-
children:
|
|
113
|
+
children: C
|
|
113
114
|
}),
|
|
114
|
-
/* @__PURE__ */
|
|
115
|
-
href:
|
|
115
|
+
/* @__PURE__ */ c("a", {
|
|
116
|
+
href: d,
|
|
116
117
|
target: "_blank",
|
|
117
118
|
rel: "noopener noreferrer",
|
|
118
119
|
className: "mt-4 px-4 py-2 bg-action-primary-bg text-text-inverse rounded-lg hover:bg-action-primary-bg-hover",
|
|
119
|
-
children: "Open in new tab"
|
|
120
|
+
children: f("files.preview.image.openInNewTab", "Open in new tab")
|
|
120
121
|
})
|
|
121
122
|
]
|
|
122
123
|
})]
|
|
123
124
|
}),
|
|
124
|
-
/* @__PURE__ */
|
|
125
|
+
/* @__PURE__ */ l("div", {
|
|
125
126
|
className: "flex items-center justify-center gap-6 p-3 bg-bg-surface border-t border-border-default text-xs text-text-secondary",
|
|
126
127
|
children: [
|
|
127
|
-
/* @__PURE__ */
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
/* @__PURE__ */ c("span", { children: u.name }),
|
|
129
|
+
E.width > 0 && /* @__PURE__ */ l("span", { children: [
|
|
130
|
+
E.width,
|
|
130
131
|
" × ",
|
|
131
|
-
|
|
132
|
+
E.height
|
|
132
133
|
] }),
|
|
133
|
-
/* @__PURE__ */
|
|
134
|
+
/* @__PURE__ */ l("span", { children: [(u.size / 1024 / 1024).toFixed(2), " MB"] })
|
|
134
135
|
]
|
|
135
136
|
})
|
|
136
137
|
]
|
|
137
138
|
});
|
|
138
139
|
}
|
|
139
140
|
//#endregion
|
|
140
|
-
export {
|
|
141
|
+
export { u as ImageViewer };
|
|
141
142
|
|
|
142
143
|
//# sourceMappingURL=ImageViewer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageViewer.js","names":[],"sources":["../../../../src/files/components/viewers/ImageViewer.tsx"],"sourcesContent":["import { useState, useRef } from \"react\";\nimport {\n ZoomIn,\n ZoomOut,\n RotateCw,\n Maximize2,\n Minimize2,\n AlertCircle,\n} from \"lucide-react\";\nimport type { FileItem } from \"../../types\";\n\ninterface ImageViewerProps {\n file: FileItem;\n url: string;\n}\n\nexport function ImageViewer({ file, url }: ImageViewerProps) {\n const [zoom, setZoom] = useState(1);\n const [rotation, setRotation] = useState(0);\n const [position, setPosition] = useState({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [imageError, setImageError] = useState<string | null>(null);\n const imageRef = useRef<HTMLImageElement>(null);\n const [imageDimensions, setImageDimensions] = useState({\n width: 0,\n height: 0,\n });\n\n const handleZoomIn = () => setZoom((prev) => Math.min(prev + 0.25, 4));\n const handleZoomOut = () => setZoom((prev) => Math.max(prev - 0.25, 0.25));\n const handleResetZoom = () => {\n setZoom(1);\n setPosition({ x: 0, y: 0 });\n setRotation(0);\n };\n const handleRotate = () => setRotation((prev) => (prev + 90) % 360);\n\n const handleMouseDown = (e: React.MouseEvent) => {\n if (zoom > 1) {\n setIsDragging(true);\n setDragStart({ x: e.clientX - position.x, y: e.clientY - position.y });\n }\n };\n\n const handleMouseMove = (e: React.MouseEvent) => {\n if (isDragging && zoom > 1) {\n setPosition({\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n });\n }\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n };\n\n const handleImageLoad = () => {\n if (imageRef.current) {\n setImageDimensions({\n width: imageRef.current.naturalWidth,\n height: imageRef.current.naturalHeight,\n });\n }\n };\n\n const handleImageError = () => {\n setImageError(
|
|
1
|
+
{"version":3,"file":"ImageViewer.js","names":[],"sources":["../../../../src/files/components/viewers/ImageViewer.tsx"],"sourcesContent":["import { useState, useRef } from \"react\";\nimport {\n ZoomIn,\n ZoomOut,\n RotateCw,\n Maximize2,\n Minimize2,\n AlertCircle,\n} from \"lucide-react\";\nimport type { FileItem } from \"../../types\";\nimport { useTr } from \"../../../shared/hooks/useTr\";\n\ninterface ImageViewerProps {\n file: FileItem;\n url: string;\n}\n\nexport function ImageViewer({ file, url }: ImageViewerProps) {\n const tr = useTr();\n const [zoom, setZoom] = useState(1);\n const [rotation, setRotation] = useState(0);\n const [position, setPosition] = useState({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [imageError, setImageError] = useState<string | null>(null);\n const imageRef = useRef<HTMLImageElement>(null);\n const [imageDimensions, setImageDimensions] = useState({\n width: 0,\n height: 0,\n });\n\n const handleZoomIn = () => setZoom((prev) => Math.min(prev + 0.25, 4));\n const handleZoomOut = () => setZoom((prev) => Math.max(prev - 0.25, 0.25));\n const handleResetZoom = () => {\n setZoom(1);\n setPosition({ x: 0, y: 0 });\n setRotation(0);\n };\n const handleRotate = () => setRotation((prev) => (prev + 90) % 360);\n\n const handleMouseDown = (e: React.MouseEvent) => {\n if (zoom > 1) {\n setIsDragging(true);\n setDragStart({ x: e.clientX - position.x, y: e.clientY - position.y });\n }\n };\n\n const handleMouseMove = (e: React.MouseEvent) => {\n if (isDragging && zoom > 1) {\n setPosition({\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n });\n }\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n };\n\n const handleImageLoad = () => {\n if (imageRef.current) {\n setImageDimensions({\n width: imageRef.current.naturalWidth,\n height: imageRef.current.naturalHeight,\n });\n }\n };\n\n const handleImageError = () => {\n setImageError(\n tr(\"files.preview.image.loadError\", \"Failed to load image from URL\"),\n );\n };\n\n return (\n <div className=\"flex flex-col h-full bg-bg-canvas\">\n {/* Toolbar */}\n <div className=\"flex items-center justify-center gap-2 p-4 bg-bg-surface border-b border-border-default\">\n <button\n type=\"button\"\n onClick={handleZoomOut}\n disabled={zoom <= 0.25}\n className=\"p-2 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed\"\n title={tr(\"files.preview.image.zoomOut\", \"Zoom out\")}\n >\n <ZoomOut className=\"size-5\" />\n </button>\n\n <span className=\"min-w-16 text-center text-sm font-medium text-text-primary\">\n {Math.round(zoom * 100)}%\n </span>\n\n <button\n type=\"button\"\n onClick={handleZoomIn}\n disabled={zoom >= 4}\n className=\"p-2 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed\"\n title={tr(\"files.preview.image.zoomIn\", \"Zoom in\")}\n >\n <ZoomIn className=\"size-5\" />\n </button>\n\n <div className=\"w-px h-6 bg-border-default mx-2\" />\n\n <button\n type=\"button\"\n onClick={handleResetZoom}\n className=\"p-2 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200\"\n title={tr(\"files.preview.image.fitToScreen\", \"Fit to screen\")}\n >\n <Minimize2 className=\"size-5\" />\n </button>\n\n <button\n type=\"button\"\n onClick={handleRotate}\n className=\"p-2 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200\"\n title={tr(\"files.preview.image.rotate\", \"Rotate 90°\")}\n >\n <RotateCw className=\"size-5\" />\n </button>\n </div>\n\n {/* Image Container */}\n <div\n className=\"flex-1 overflow-hidden flex items-center justify-center relative\"\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n style={{\n cursor: zoom > 1 ? (isDragging ? \"grabbing\" : \"grab\") : \"default\",\n }}\n >\n <img\n ref={imageRef}\n src={url}\n alt={file.name}\n onLoad={handleImageLoad}\n onError={handleImageError}\n draggable={false}\n className=\"max-w-full max-h-full object-contain transition-transform duration-200\"\n style={{\n transform: `scale(${zoom}) rotate(${rotation}deg) translate(${position.x / zoom}px, ${position.y / zoom}px)`,\n userSelect: \"none\",\n }}\n />\n {imageError && (\n <div className=\"absolute inset-0 flex flex-col items-center justify-center bg-bg-canvas/90 z-10\">\n <AlertCircle className=\"size-12 text-status-error-text mb-4\" />\n <p className=\"text-text-primary font-medium mb-2\">\n {tr(\"files.preview.image.failedToLoad\", \"Failed to load image\")}\n </p>\n <p className=\"text-text-secondary text-sm max-w-md text-center px-4\">\n {imageError}\n </p>\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"mt-4 px-4 py-2 bg-action-primary-bg text-text-inverse rounded-lg hover:bg-action-primary-bg-hover\"\n >\n {tr(\"files.preview.image.openInNewTab\", \"Open in new tab\")}\n </a>\n </div>\n )}\n </div>\n\n {/* Metadata */}\n <div className=\"flex items-center justify-center gap-6 p-3 bg-bg-surface border-t border-border-default text-xs text-text-secondary\">\n <span>{file.name}</span>\n {imageDimensions.width > 0 && (\n <span>\n {imageDimensions.width} × {imageDimensions.height}\n </span>\n )}\n <span>{(file.size / 1024 / 1024).toFixed(2)} MB</span>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PDFViewer.d.ts","sourceRoot":"","sources":["../../../../src/files/components/viewers/PDFViewer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"PDFViewer.d.ts","sourceRoot":"","sources":["../../../../src/files/components/viewers/PDFViewer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,UAAU,cAAc;IACtB,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,cAAc,+BAuFtD"}
|
|
@@ -1,75 +1,78 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useTr as e } from "../../../shared/hooks/useTr.js";
|
|
2
|
+
import { useState as t } from "react";
|
|
3
|
+
import { ZoomIn as n, ZoomOut as r } from "lucide-react";
|
|
4
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
4
5
|
//#region src/files/components/viewers/PDFViewer.tsx
|
|
5
|
-
function
|
|
6
|
-
let [
|
|
7
|
-
return /* @__PURE__ */
|
|
6
|
+
function o({ file: o, url: s }) {
|
|
7
|
+
let c = e(), [l, u] = t(100), d = () => u((e) => Math.min(e + 25, 200)), f = () => u((e) => Math.max(e - 25, 50)), p = `${s}#view=FitH&zoom=${l}`;
|
|
8
|
+
return /* @__PURE__ */ a("div", {
|
|
8
9
|
className: "flex flex-col h-full bg-bg-canvas",
|
|
9
10
|
children: [
|
|
10
|
-
/* @__PURE__ */
|
|
11
|
+
/* @__PURE__ */ a("div", {
|
|
11
12
|
className: "flex items-center justify-between p-4 bg-bg-surface border-b border-border-default",
|
|
12
|
-
children: [/* @__PURE__ */
|
|
13
|
+
children: [/* @__PURE__ */ a("div", {
|
|
13
14
|
className: "flex items-center gap-2",
|
|
14
15
|
children: [
|
|
15
|
-
/* @__PURE__ */
|
|
16
|
+
/* @__PURE__ */ i("button", {
|
|
16
17
|
type: "button",
|
|
17
|
-
onClick:
|
|
18
|
-
disabled:
|
|
18
|
+
onClick: f,
|
|
19
|
+
disabled: l <= 50,
|
|
19
20
|
className: "p-2 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
20
|
-
title: "Zoom out",
|
|
21
|
-
children: /* @__PURE__ */ r
|
|
21
|
+
title: c("files.preview.pdf.zoomOut", "Zoom out"),
|
|
22
|
+
children: /* @__PURE__ */ i(r, { className: "size-5" })
|
|
22
23
|
}),
|
|
23
|
-
/* @__PURE__ */
|
|
24
|
+
/* @__PURE__ */ a("span", {
|
|
24
25
|
className: "min-w-16 text-center text-sm font-medium text-text-primary",
|
|
25
|
-
children: [
|
|
26
|
+
children: [l, "%"]
|
|
26
27
|
}),
|
|
27
|
-
/* @__PURE__ */
|
|
28
|
+
/* @__PURE__ */ i("button", {
|
|
28
29
|
type: "button",
|
|
29
|
-
onClick:
|
|
30
|
-
disabled:
|
|
30
|
+
onClick: d,
|
|
31
|
+
disabled: l >= 200,
|
|
31
32
|
className: "p-2 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
32
|
-
title: "Zoom in",
|
|
33
|
-
children: /* @__PURE__ */
|
|
33
|
+
title: c("files.preview.pdf.zoomIn", "Zoom in"),
|
|
34
|
+
children: /* @__PURE__ */ i(n, { className: "size-5" })
|
|
34
35
|
})
|
|
35
36
|
]
|
|
36
|
-
}), /* @__PURE__ */
|
|
37
|
+
}), /* @__PURE__ */ i("span", {
|
|
37
38
|
className: "text-sm text-text-secondary",
|
|
38
|
-
children:
|
|
39
|
+
children: o.name
|
|
39
40
|
})]
|
|
40
41
|
}),
|
|
41
|
-
/* @__PURE__ */
|
|
42
|
+
/* @__PURE__ */ i("div", {
|
|
42
43
|
className: "flex-1 overflow-hidden",
|
|
43
|
-
children: /* @__PURE__ */
|
|
44
|
-
data:
|
|
44
|
+
children: /* @__PURE__ */ i("object", {
|
|
45
|
+
data: p,
|
|
45
46
|
type: "application/pdf",
|
|
46
47
|
className: "w-full h-full",
|
|
47
|
-
title:
|
|
48
|
-
children: /* @__PURE__ */
|
|
48
|
+
title: o.name,
|
|
49
|
+
children: /* @__PURE__ */ a("div", {
|
|
49
50
|
className: "flex flex-col items-center justify-center h-full gap-4 p-8",
|
|
50
|
-
children: [/* @__PURE__ */
|
|
51
|
+
children: [/* @__PURE__ */ a("div", {
|
|
51
52
|
className: "text-text-secondary text-center",
|
|
52
|
-
children: [/* @__PURE__ */
|
|
53
|
+
children: [/* @__PURE__ */ i("p", {
|
|
53
54
|
className: "font-text-lg font-weight-medium mb-2",
|
|
54
|
-
children: "Unable to display PDF"
|
|
55
|
-
}), /* @__PURE__ */
|
|
55
|
+
children: c("files.preview.pdf.unableToDisplay", "Unable to display PDF")
|
|
56
|
+
}), /* @__PURE__ */ i("p", {
|
|
56
57
|
className: "font-text-sm",
|
|
57
|
-
children: "Your browser may not support embedded PDF viewing."
|
|
58
|
+
children: c("files.preview.pdf.browserUnsupported", "Your browser may not support embedded PDF viewing.")
|
|
58
59
|
})]
|
|
59
|
-
}), /* @__PURE__ */
|
|
60
|
-
href:
|
|
61
|
-
download:
|
|
60
|
+
}), /* @__PURE__ */ i("a", {
|
|
61
|
+
href: s,
|
|
62
|
+
download: o.name,
|
|
62
63
|
className: "px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-btn hover:bg-action-primary-bg-hover transition-colors",
|
|
63
|
-
children: "Download PDF"
|
|
64
|
+
children: c("files.preview.pdf.download", "Download PDF")
|
|
64
65
|
})]
|
|
65
66
|
})
|
|
66
67
|
})
|
|
67
68
|
}),
|
|
68
|
-
/* @__PURE__ */
|
|
69
|
+
/* @__PURE__ */ i("div", {
|
|
69
70
|
className: "flex items-center justify-center p-3 bg-bg-surface border-t border-border-default text-xs text-text-secondary",
|
|
70
|
-
children: /* @__PURE__ */
|
|
71
|
-
"PDF Document
|
|
72
|
-
|
|
71
|
+
children: /* @__PURE__ */ a("span", { children: [
|
|
72
|
+
c("files.preview.pdf.documentLabel", "PDF Document"),
|
|
73
|
+
" ·",
|
|
74
|
+
" ",
|
|
75
|
+
(o.size / 1024 / 1024).toFixed(2),
|
|
73
76
|
" MB"
|
|
74
77
|
] })
|
|
75
78
|
})
|
|
@@ -77,6 +80,6 @@ function a({ file: a, url: o }) {
|
|
|
77
80
|
});
|
|
78
81
|
}
|
|
79
82
|
//#endregion
|
|
80
|
-
export {
|
|
83
|
+
export { o as PDFViewer };
|
|
81
84
|
|
|
82
85
|
//# sourceMappingURL=PDFViewer.js.map
|