@eternalheart/react-file-preview 1.4.0 → 1.5.1
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/README.md +437 -60
- package/README.zh-CN.md +437 -60
- package/lib/FilePreviewContent.d.ts +1 -0
- package/lib/FilePreviewContent.d.ts.map +1 -1
- package/lib/FilePreviewEmbed.d.ts +2 -0
- package/lib/FilePreviewEmbed.d.ts.map +1 -1
- package/lib/FilePreviewModal.d.ts +2 -0
- package/lib/FilePreviewModal.d.ts.map +1 -1
- package/lib/chunks/index-BBYKNNLb.mjs +329 -0
- package/lib/chunks/index-BBYKNNLb.mjs.map +1 -0
- package/lib/chunks/index-BFh22D_W.mjs +78 -0
- package/lib/chunks/index-BFh22D_W.mjs.map +1 -0
- package/lib/chunks/{index-DoFsoBKL.mjs → index-BKXvtJh5.mjs} +27 -25
- package/lib/chunks/index-BKXvtJh5.mjs.map +1 -0
- package/lib/chunks/index-Bw3Fh4b5.mjs +116 -0
- package/lib/chunks/index-Bw3Fh4b5.mjs.map +1 -0
- package/lib/chunks/{index-kALp0tqz.mjs → index-CEC_DHgr.mjs} +22 -20
- package/lib/chunks/index-CEC_DHgr.mjs.map +1 -0
- package/lib/chunks/{index-CzM2mxrD.mjs → index-COOUxB5e.mjs} +130 -128
- package/lib/chunks/{index-CzM2mxrD.mjs.map → index-COOUxB5e.mjs.map} +1 -1
- package/lib/chunks/index-CU1Lc3lV.mjs +120 -0
- package/lib/chunks/index-CU1Lc3lV.mjs.map +1 -0
- package/lib/chunks/index-CgFv7B_G.mjs +359 -0
- package/lib/chunks/index-CgFv7B_G.mjs.map +1 -0
- package/lib/chunks/index-Cn4ZyhGM.mjs +587 -0
- package/lib/chunks/index-Cn4ZyhGM.mjs.map +1 -0
- package/lib/chunks/{index-DaAXRBWL.mjs → index-DGNNEnWE.mjs} +864 -862
- package/lib/chunks/{index-DaAXRBWL.mjs.map → index-DGNNEnWE.mjs.map} +1 -1
- package/lib/chunks/index-DLk08ylq.mjs +313 -0
- package/lib/chunks/index-DLk08ylq.mjs.map +1 -0
- package/lib/chunks/index-DVtPyN-s.mjs +200 -0
- package/lib/chunks/index-DVtPyN-s.mjs.map +1 -0
- package/lib/chunks/index-DreA69iU.mjs +2409 -0
- package/lib/chunks/index-DreA69iU.mjs.map +1 -0
- package/lib/chunks/{index-Cp68OevR.mjs → index-Dta7iGov.mjs} +1299 -1297
- package/lib/chunks/{index-Cp68OevR.mjs.map → index-Dta7iGov.mjs.map} +1 -1
- package/lib/chunks/index-fQGAUFAX.mjs +275 -0
- package/lib/chunks/index-fQGAUFAX.mjs.map +1 -0
- package/lib/chunks/{index-C_BJatqr.mjs → index-fSw6Hl5e.mjs} +42 -40
- package/lib/chunks/index-fSw6Hl5e.mjs.map +1 -0
- package/lib/chunks/index-jvNrkVkp.mjs +291 -0
- package/lib/chunks/index-jvNrkVkp.mjs.map +1 -0
- package/lib/chunks/index-oVJyD-FV.mjs +107 -0
- package/lib/chunks/index-oVJyD-FV.mjs.map +1 -0
- package/lib/chunks/{index-DuP0Tlpo.mjs → index-vRLKumL8.mjs} +43 -41
- package/lib/chunks/index-vRLKumL8.mjs.map +1 -0
- package/lib/chunks/useShikiHighlight-C6nJcETW.mjs +36 -0
- package/lib/chunks/useShikiHighlight-C6nJcETW.mjs.map +1 -0
- package/lib/components/preview/FilePreviewToolbar.d.ts +1 -0
- package/lib/components/preview/FilePreviewToolbar.d.ts.map +1 -1
- package/lib/components/preview/ToolbarButton.d.ts +3 -1
- package/lib/components/preview/ToolbarButton.d.ts.map +1 -1
- package/lib/hooks/index.d.ts +0 -6
- package/lib/hooks/index.d.ts.map +1 -1
- package/lib/hooks/useShikiHighlight.d.ts +3 -1
- package/lib/hooks/useShikiHighlight.d.ts.map +1 -1
- package/lib/index.cjs +32 -30
- package/lib/index.cjs.map +1 -1
- package/lib/index.css +1 -1
- package/lib/index.mjs +1 -1
- package/lib/renderers/Audio/index.d.ts +2 -1
- package/lib/renderers/Audio/index.d.ts.map +1 -1
- package/lib/renderers/Csv/index.d.ts +2 -1
- package/lib/renderers/Csv/index.d.ts.map +1 -1
- package/lib/renderers/Docx/index.d.ts +2 -1
- package/lib/renderers/Docx/index.d.ts.map +1 -1
- package/lib/renderers/Epub/index.d.ts +2 -3
- package/lib/renderers/Epub/index.d.ts.map +1 -1
- package/lib/renderers/Font/index.d.ts +2 -1
- package/lib/renderers/Font/index.d.ts.map +1 -1
- package/lib/renderers/Image/index.d.ts +6 -7
- package/lib/renderers/Image/index.d.ts.map +1 -1
- package/lib/renderers/Json/index.d.ts +2 -1
- package/lib/renderers/Json/index.d.ts.map +1 -1
- package/lib/renderers/Markdown/index.d.ts +2 -2
- package/lib/renderers/Markdown/index.d.ts.map +1 -1
- package/lib/renderers/Mobi/index.d.ts +2 -3
- package/lib/renderers/Mobi/index.d.ts.map +1 -1
- package/lib/renderers/Msg/index.d.ts +2 -1
- package/lib/renderers/Msg/index.d.ts.map +1 -1
- package/lib/renderers/Pdf/index.d.ts +4 -8
- package/lib/renderers/Pdf/index.d.ts.map +1 -1
- package/lib/renderers/Pptx/index.d.ts +2 -1
- package/lib/renderers/Pptx/index.d.ts.map +1 -1
- package/lib/renderers/Subtitle/index.d.ts +2 -1
- package/lib/renderers/Subtitle/index.d.ts.map +1 -1
- package/lib/renderers/Text/index.d.ts +2 -3
- package/lib/renderers/Text/index.d.ts.map +1 -1
- package/lib/renderers/Video/index.d.ts +2 -1
- package/lib/renderers/Video/index.d.ts.map +1 -1
- package/lib/renderers/Xlsx/index.d.ts +2 -1
- package/lib/renderers/Xlsx/index.d.ts.map +1 -1
- package/lib/renderers/Xml/index.d.ts +2 -1
- package/lib/renderers/Xml/index.d.ts.map +1 -1
- package/lib/renderers/Zip/index.d.ts +7 -2
- package/lib/renderers/Zip/index.d.ts.map +1 -1
- package/lib/renderers/base.types.d.ts +38 -0
- package/lib/renderers/base.types.d.ts.map +1 -0
- package/lib/renderers/registry.d.ts +36 -0
- package/lib/renderers/registry.d.ts.map +1 -0
- package/lib/renderers/toolbar.types.d.ts +2 -0
- package/lib/renderers/toolbar.types.d.ts.map +1 -1
- package/lib/toolbar/renderItems.d.ts.map +1 -1
- package/package.json +3 -3
- package/lib/chunks/index-0v5STX5f.mjs +0 -105
- package/lib/chunks/index-0v5STX5f.mjs.map +0 -1
- package/lib/chunks/index-10O8tfTH.mjs +0 -529
- package/lib/chunks/index-10O8tfTH.mjs.map +0 -1
- package/lib/chunks/index-BCyv1HM9.mjs +0 -175
- package/lib/chunks/index-BCyv1HM9.mjs.map +0 -1
- package/lib/chunks/index-Bo90aGhy.mjs +0 -114
- package/lib/chunks/index-Bo90aGhy.mjs.map +0 -1
- package/lib/chunks/index-CEeKt7L3.mjs +0 -2808
- package/lib/chunks/index-CEeKt7L3.mjs.map +0 -1
- package/lib/chunks/index-CWKbnvW6.mjs +0 -270
- package/lib/chunks/index-CWKbnvW6.mjs.map +0 -1
- package/lib/chunks/index-C_BJatqr.mjs.map +0 -1
- package/lib/chunks/index-Cbz5Z6ZK.mjs +0 -263
- package/lib/chunks/index-Cbz5Z6ZK.mjs.map +0 -1
- package/lib/chunks/index-DTYBFuAH.mjs +0 -357
- package/lib/chunks/index-DTYBFuAH.mjs.map +0 -1
- package/lib/chunks/index-DoFsoBKL.mjs.map +0 -1
- package/lib/chunks/index-DuP0Tlpo.mjs.map +0 -1
- package/lib/chunks/index-Dv3RQz86.mjs +0 -270
- package/lib/chunks/index-Dv3RQz86.mjs.map +0 -1
- package/lib/chunks/index-QfpHck8N.mjs +0 -55
- package/lib/chunks/index-QfpHck8N.mjs.map +0 -1
- package/lib/chunks/index-gjSQeou7.mjs +0 -194
- package/lib/chunks/index-gjSQeou7.mjs.map +0 -1
- package/lib/chunks/index-kALp0tqz.mjs.map +0 -1
- package/lib/chunks/index-kCeSnFs-.mjs +0 -54
- package/lib/chunks/index-kCeSnFs-.mjs.map +0 -1
- package/lib/chunks/useShikiHighlight-BA9qgdGA.mjs +0 -23
- package/lib/chunks/useShikiHighlight-BA9qgdGA.mjs.map +0 -1
- package/lib/hooks/rendererReducer.d.ts +0 -10
- package/lib/hooks/rendererReducer.d.ts.map +0 -1
- package/lib/hooks/types.d.ts +0 -152
- package/lib/hooks/types.d.ts.map +0 -1
- package/lib/hooks/useBookRenderer.d.ts +0 -14
- package/lib/hooks/useBookRenderer.d.ts.map +0 -1
- package/lib/hooks/useFilePreviewState.d.ts +0 -10
- package/lib/hooks/useFilePreviewState.d.ts.map +0 -1
- package/lib/hooks/useImageAutoFit.d.ts +0 -13
- package/lib/hooks/useImageAutoFit.d.ts.map +0 -1
- package/lib/hooks/useToolbarConfig.d.ts +0 -25
- package/lib/hooks/useToolbarConfig.d.ts.map +0 -1
- package/lib/renderers/Epub/toolbar.d.ts +0 -13
- package/lib/renderers/Epub/toolbar.d.ts.map +0 -1
- package/lib/renderers/Image/toolbar.d.ts +0 -15
- package/lib/renderers/Image/toolbar.d.ts.map +0 -1
- package/lib/renderers/Markdown/toolbar.d.ts +0 -9
- package/lib/renderers/Markdown/toolbar.d.ts.map +0 -1
- package/lib/renderers/Mobi/toolbar.d.ts +0 -13
- package/lib/renderers/Mobi/toolbar.d.ts.map +0 -1
- package/lib/renderers/Pdf/toolbar.d.ts +0 -16
- package/lib/renderers/Pdf/toolbar.d.ts.map +0 -1
- package/lib/renderers/Text/toolbar.d.ts +0 -12
- package/lib/renderers/Text/toolbar.d.ts.map +0 -1
- package/lib/renderers/Zip/toolbar.d.ts +0 -13
- package/lib/renderers/Zip/toolbar.d.ts.map +0 -1
- package/lib/toolbar/registry.d.ts +0 -51
- package/lib/toolbar/registry.d.ts.map +0 -1
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
import { jsxs as X, jsx as m } from "react/jsx-runtime";
|
|
2
|
-
import { useState as i, useRef as d, useEffect as j, useCallback as x } from "react";
|
|
3
|
-
import { motion as Le } from "framer-motion";
|
|
4
|
-
import { Loader2 as Me } from "lucide-react";
|
|
5
|
-
import { u as Re, G as Ee, q as Ue } from "./index-CEeKt7L3.mjs";
|
|
6
|
-
import { R as pe } from "./RendererError-D5i8eSpN.mjs";
|
|
7
|
-
const Be = ({
|
|
8
|
-
url: F,
|
|
9
|
-
zoom: Z,
|
|
10
|
-
rotation: he,
|
|
11
|
-
resetKey: ee,
|
|
12
|
-
fileSize: L,
|
|
13
|
-
file: P,
|
|
14
|
-
onZoomChange: o,
|
|
15
|
-
onNaturalWidthChange: A,
|
|
16
|
-
onNaturalHeightChange: H
|
|
17
|
-
}) => {
|
|
18
|
-
const te = Re(), [q, K] = i(!1), [M, re] = i(null), [G, y] = i(!1), [ne, ce] = i(0), [k, Q] = i(null), [se, R] = i(""), [B, z] = i(1), [T, ae] = i(1), [p, b] = i({ x: 0, y: 0 }), [E, $] = i(!1), [U, oe] = i({ x: 0, y: 0 }), [v, D] = i(1), [g, me] = i({ width: 0, height: 0 }), be = d(null), N = d(null), Y = d(null), O = d(null), S = d(null), f = d(/* @__PURE__ */ new Map()), W = d(!1), _ = d(0), ie = d(1), J = d({ x: 0, y: 0 }), le = d(0);
|
|
19
|
-
j(() => {
|
|
20
|
-
let e = !1;
|
|
21
|
-
return (async () => {
|
|
22
|
-
if (R(""), K(!1), re(null), y(!1), Q(null), ce(0), b({ x: 0, y: 0 }), D(1), z(1), ae(1), Y.current && (URL.revokeObjectURL(Y.current), Y.current = null), f.current.forEach((r) => URL.revokeObjectURL(r)), f.current.clear(), O.current = null, S.current = null, !P) {
|
|
23
|
-
e || R(F);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
try {
|
|
27
|
-
const r = await Ee(P), n = await Ue(r);
|
|
28
|
-
if (!n || !await n.needsDecode(r)) {
|
|
29
|
-
e || R(F);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
y(!0);
|
|
33
|
-
let c;
|
|
34
|
-
if (P instanceof Blob)
|
|
35
|
-
c = P;
|
|
36
|
-
else {
|
|
37
|
-
const s = await fetch(F);
|
|
38
|
-
if (!s.ok) throw new Error("Failed to fetch file");
|
|
39
|
-
c = await s.blob();
|
|
40
|
-
}
|
|
41
|
-
if (e) return;
|
|
42
|
-
if (O.current = c, S.current = n, O.current = c, S.current = n, n.getMetadata)
|
|
43
|
-
try {
|
|
44
|
-
const s = await n.getMetadata(c);
|
|
45
|
-
!e && s.pageCount && s.pageCount > 1 && ae(s.pageCount);
|
|
46
|
-
} catch {
|
|
47
|
-
}
|
|
48
|
-
const a = await n.decode(c, {
|
|
49
|
-
page: 1,
|
|
50
|
-
fullQuality: !1,
|
|
51
|
-
onProgress: (s) => {
|
|
52
|
-
e || ce(s);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
if (e) return;
|
|
56
|
-
const l = typeof a == "string" ? a : URL.createObjectURL(a);
|
|
57
|
-
Y.current = l, f.current.set(1, l), R(l), y(!1);
|
|
58
|
-
} catch (r) {
|
|
59
|
-
e || (Q((r == null ? void 0 : r.message) || "解码失败"), y(!1));
|
|
60
|
-
}
|
|
61
|
-
})(), () => {
|
|
62
|
-
e = !0;
|
|
63
|
-
};
|
|
64
|
-
}, [F, P]);
|
|
65
|
-
const fe = x(async (e) => {
|
|
66
|
-
if (!O.current || !S.current || e < 1 || e > T) return;
|
|
67
|
-
const t = f.current.get(e);
|
|
68
|
-
if (t) {
|
|
69
|
-
z(e), R(t);
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
y(!0);
|
|
73
|
-
try {
|
|
74
|
-
const r = await S.current.decode(O.current, { page: e }), n = typeof r == "string" ? r : URL.createObjectURL(r);
|
|
75
|
-
if (f.current.size >= 10) {
|
|
76
|
-
const c = f.current.keys().next().value;
|
|
77
|
-
if (c !== void 0) {
|
|
78
|
-
const a = f.current.get(c);
|
|
79
|
-
a && URL.revokeObjectURL(a), f.current.delete(c);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
f.current.set(e, n), z(e), R(n), y(!1);
|
|
83
|
-
} catch (r) {
|
|
84
|
-
Q((r == null ? void 0 : r.message) || "翻页解码失败"), y(!1);
|
|
85
|
-
}
|
|
86
|
-
}, [T]);
|
|
87
|
-
j(() => () => {
|
|
88
|
-
Y.current && URL.revokeObjectURL(Y.current), f.current.forEach((e) => URL.revokeObjectURL(e)), f.current.clear();
|
|
89
|
-
}, []), j(() => {
|
|
90
|
-
D(Z);
|
|
91
|
-
}, [Z]), j(() => {
|
|
92
|
-
ee !== void 0 && b({ x: 0, y: 0 });
|
|
93
|
-
}, [ee]);
|
|
94
|
-
const ve = (e) => {
|
|
95
|
-
K(!0);
|
|
96
|
-
const t = e.currentTarget;
|
|
97
|
-
me({ width: t.naturalWidth, height: t.naturalHeight }), A == null || A(t.naturalWidth), H == null || H(t.naturalHeight);
|
|
98
|
-
}, w = x((e, t) => {
|
|
99
|
-
const r = N.current;
|
|
100
|
-
if (!r || g.width === 0) return e;
|
|
101
|
-
const n = r.clientWidth, c = r.clientHeight, a = g.width * t, l = g.height * t, s = Math.min(80, n * 0.15, c * 0.15), u = (n + a) / 2 - s, h = (c + l) / 2 - s;
|
|
102
|
-
return {
|
|
103
|
-
x: u > 0 ? Math.max(-u, Math.min(u, e.x)) : 0,
|
|
104
|
-
y: h > 0 ? Math.max(-h, Math.min(h, e.y)) : 0
|
|
105
|
-
};
|
|
106
|
-
}, [g]), xe = () => {
|
|
107
|
-
re(te("image.load_failed")), K(!0);
|
|
108
|
-
}, ye = () => {
|
|
109
|
-
b({ x: 0, y: 0 }), D(1), o == null || o(1);
|
|
110
|
-
}, V = x((e) => {
|
|
111
|
-
W.current = !0, e.preventDefault();
|
|
112
|
-
const t = e.touches;
|
|
113
|
-
if (t.length === 1) {
|
|
114
|
-
$(!0), oe({
|
|
115
|
-
x: t[0].clientX - p.x,
|
|
116
|
-
y: t[0].clientY - p.y
|
|
117
|
-
});
|
|
118
|
-
const r = Date.now();
|
|
119
|
-
r - le.current < 300 && (b({ x: 0, y: 0 }), D(1), o == null || o(1)), le.current = r;
|
|
120
|
-
} else if (t.length === 2) {
|
|
121
|
-
$(!1);
|
|
122
|
-
const r = Math.hypot(
|
|
123
|
-
t[1].clientX - t[0].clientX,
|
|
124
|
-
t[1].clientY - t[0].clientY
|
|
125
|
-
);
|
|
126
|
-
_.current = r, ie.current = v, J.current = { ...p };
|
|
127
|
-
}
|
|
128
|
-
}, [p, v, o]), C = x((e) => {
|
|
129
|
-
e.preventDefault();
|
|
130
|
-
const t = e.touches;
|
|
131
|
-
if (t.length === 1 && E)
|
|
132
|
-
b(w({
|
|
133
|
-
x: t[0].clientX - U.x,
|
|
134
|
-
y: t[0].clientY - U.y
|
|
135
|
-
}, v));
|
|
136
|
-
else if (t.length === 2) {
|
|
137
|
-
const r = N.current;
|
|
138
|
-
if (!r) return;
|
|
139
|
-
const n = Math.hypot(
|
|
140
|
-
t[1].clientX - t[0].clientX,
|
|
141
|
-
t[1].clientY - t[0].clientY
|
|
142
|
-
);
|
|
143
|
-
if (Math.abs(n - _.current) < 5) return;
|
|
144
|
-
const c = n / _.current, a = Math.max(0.01, Math.min(10, ie.current * c)), l = r.getBoundingClientRect(), s = (t[0].clientX + t[1].clientX) / 2 - l.left - l.width / 2, u = (t[0].clientY + t[1].clientY) / 2 - l.top - l.height / 2, h = a / v;
|
|
145
|
-
b(w({
|
|
146
|
-
x: s - h * (s - J.current.x),
|
|
147
|
-
y: u - h * (u - J.current.y)
|
|
148
|
-
}, a)), D(a), o == null || o(a);
|
|
149
|
-
}
|
|
150
|
-
}, [E, U, v, w, o]), I = x(() => {
|
|
151
|
-
$(!1), _.current = 0;
|
|
152
|
-
}, []);
|
|
153
|
-
j(() => {
|
|
154
|
-
const e = N.current;
|
|
155
|
-
if (!e) return;
|
|
156
|
-
const t = (r) => {
|
|
157
|
-
r.preventDefault(), r.stopPropagation();
|
|
158
|
-
const n = e.getBoundingClientRect(), c = r.clientX - n.left - n.width / 2, a = r.clientY - n.top - n.height / 2, l = r.deltaY > 0 ? -0.05 : 0.05;
|
|
159
|
-
D((s) => {
|
|
160
|
-
const u = Math.max(0.01, Math.min(10, s + l)), h = u / s;
|
|
161
|
-
return b((de) => w({
|
|
162
|
-
x: c - h * (c - de.x),
|
|
163
|
-
y: a - h * (a - de.y)
|
|
164
|
-
}, u)), o == null || o(u), u;
|
|
165
|
-
});
|
|
166
|
-
};
|
|
167
|
-
return e.addEventListener("wheel", t, { passive: !1 }), () => e.removeEventListener("wheel", t);
|
|
168
|
-
}, [o, w]), j(() => {
|
|
169
|
-
const e = N.current;
|
|
170
|
-
if (e)
|
|
171
|
-
return e.addEventListener("touchstart", V, { passive: !1 }), e.addEventListener("touchmove", C, { passive: !1 }), e.addEventListener("touchend", I), e.addEventListener("touchcancel", I), () => {
|
|
172
|
-
e.removeEventListener("touchstart", V), e.removeEventListener("touchmove", C), e.removeEventListener("touchend", I), e.removeEventListener("touchcancel", I);
|
|
173
|
-
};
|
|
174
|
-
}, [V, C, I]);
|
|
175
|
-
const ge = x((e) => {
|
|
176
|
-
W.current || e.button === 0 && ($(!0), oe({
|
|
177
|
-
x: e.clientX - p.x,
|
|
178
|
-
y: e.clientY - p.y
|
|
179
|
-
}));
|
|
180
|
-
}, [p]), we = x((e) => {
|
|
181
|
-
W.current || E && b(w({
|
|
182
|
-
x: e.clientX - U.x,
|
|
183
|
-
y: e.clientY - U.y
|
|
184
|
-
}, v));
|
|
185
|
-
}, [E, U, v, w]), ue = x(() => {
|
|
186
|
-
W.current || $(!1);
|
|
187
|
-
}, []);
|
|
188
|
-
return /* @__PURE__ */ X(
|
|
189
|
-
"div",
|
|
190
|
-
{
|
|
191
|
-
ref: N,
|
|
192
|
-
className: "rfp-relative rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-overflow-hidden",
|
|
193
|
-
onMouseDown: ge,
|
|
194
|
-
onMouseMove: we,
|
|
195
|
-
onMouseUp: ue,
|
|
196
|
-
onMouseLeave: ue,
|
|
197
|
-
style: { cursor: E ? "grabbing" : "grab", touchAction: "none" },
|
|
198
|
-
children: [
|
|
199
|
-
G && /* @__PURE__ */ X("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-flex-col rfp-items-center rfp-justify-center rfp-bg-surface-1/80 rfp-z-10", children: [
|
|
200
|
-
/* @__PURE__ */ m(Me, { className: "rfp-w-12 rfp-h-12 rfp-text-fg-primary rfp-animate-spin" }),
|
|
201
|
-
/* @__PURE__ */ X("p", { className: "rfp-mt-4 rfp-text-fg-secondary", children: [
|
|
202
|
-
"正在解码... ",
|
|
203
|
-
ne > 0 && `${Math.round(ne)}%`
|
|
204
|
-
] })
|
|
205
|
-
] }),
|
|
206
|
-
k && /* @__PURE__ */ m("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-1/80 rfp-z-10", children: /* @__PURE__ */ m(pe, { message: te("image.decode_failed"), detail: k }) }),
|
|
207
|
-
!q && !M && !G && !k && /* @__PURE__ */ m("div", { className: "rfp-flex rfp-items-center rfp-justify-center", children: /* @__PURE__ */ m("div", { className: "rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin" }) }),
|
|
208
|
-
M && /* @__PURE__ */ m(pe, { message: M }),
|
|
209
|
-
se && /* @__PURE__ */ m(
|
|
210
|
-
Le.img,
|
|
211
|
-
{
|
|
212
|
-
ref: be,
|
|
213
|
-
src: se,
|
|
214
|
-
alt: "Preview",
|
|
215
|
-
className: `rfp-max-w-none rfp-select-none ${!q || M || k ? "rfp-hidden" : ""}`,
|
|
216
|
-
style: {
|
|
217
|
-
transform: `translate(${p.x}px, ${p.y}px) scale(${v}) rotate(${he}deg)`,
|
|
218
|
-
transformOrigin: "center",
|
|
219
|
-
transition: E ? "none" : "transform 0.3s ease-out"
|
|
220
|
-
},
|
|
221
|
-
onLoad: ve,
|
|
222
|
-
onError: xe,
|
|
223
|
-
onDoubleClick: ye,
|
|
224
|
-
initial: { opacity: 0 },
|
|
225
|
-
animate: { opacity: q && !M && !k ? 1 : 0 },
|
|
226
|
-
transition: { duration: 0.3 },
|
|
227
|
-
draggable: !1
|
|
228
|
-
}
|
|
229
|
-
),
|
|
230
|
-
q && !M && g.width > 0 && /* @__PURE__ */ X("div", { className: "rfp-absolute rfp-bottom-2 rfp-right-3 rfp-text-[10px] rfp-text-fg-disabled hover:rfp-text-fg-secondary rfp-transition-colors rfp-pointer-events-auto rfp-select-none rfp-cursor-default", children: [
|
|
231
|
-
g.width,
|
|
232
|
-
" × ",
|
|
233
|
-
g.height,
|
|
234
|
-
L != null && ` · ${L < 1024 ? `${L} B` : L < 1024 * 1024 ? `${(L / 1024).toFixed(1)} KB` : `${(L / (1024 * 1024)).toFixed(1)} MB`}`
|
|
235
|
-
] }),
|
|
236
|
-
T > 1 && /* @__PURE__ */ X("div", { className: "rfp-absolute rfp-bottom-2 rfp-left-1/2 -rfp-translate-x-1/2 rfp-flex rfp-items-center rfp-gap-2 rfp-px-3 rfp-py-1.5 rfp-bg-surface-toolbar rfp-border rfp-border-line rfp-rounded-lg rfp-text-sm rfp-text-fg-primary rfp-shadow-md", children: [
|
|
237
|
-
/* @__PURE__ */ m(
|
|
238
|
-
"button",
|
|
239
|
-
{
|
|
240
|
-
type: "button",
|
|
241
|
-
onClick: () => fe(B - 1),
|
|
242
|
-
disabled: B <= 1 || G,
|
|
243
|
-
className: "rfp-px-2 rfp-py-0.5 rfp-rounded hover:rfp-bg-surface-nav-hover disabled:rfp-opacity-40 disabled:rfp-cursor-not-allowed",
|
|
244
|
-
children: "上一页"
|
|
245
|
-
}
|
|
246
|
-
),
|
|
247
|
-
/* @__PURE__ */ X("span", { className: "rfp-text-fg-secondary rfp-tabular-nums", children: [
|
|
248
|
-
B,
|
|
249
|
-
" / ",
|
|
250
|
-
T
|
|
251
|
-
] }),
|
|
252
|
-
/* @__PURE__ */ m(
|
|
253
|
-
"button",
|
|
254
|
-
{
|
|
255
|
-
type: "button",
|
|
256
|
-
onClick: () => fe(B + 1),
|
|
257
|
-
disabled: B >= T || G,
|
|
258
|
-
className: "rfp-px-2 rfp-py-0.5 rfp-rounded hover:rfp-bg-surface-nav-hover disabled:rfp-opacity-40 disabled:rfp-cursor-not-allowed",
|
|
259
|
-
children: "下一页"
|
|
260
|
-
}
|
|
261
|
-
)
|
|
262
|
-
] })
|
|
263
|
-
]
|
|
264
|
-
}
|
|
265
|
-
);
|
|
266
|
-
};
|
|
267
|
-
export {
|
|
268
|
-
Be as ImageRenderer
|
|
269
|
-
};
|
|
270
|
-
//# sourceMappingURL=index-CWKbnvW6.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-CWKbnvW6.mjs","sources":["../../src/renderers/Image/index.tsx"],"sourcesContent":["import { useState, useEffect, useRef, useCallback } from 'react';\nimport { motion } from 'framer-motion';\nimport { Loader2 } from 'lucide-react';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { detectImageFormat, getLoaderForMimeType } from '@eternalheart/file-preview-core';\nimport type { PreviewFile } from '@eternalheart/file-preview-core';\nimport { RendererError } from '../RendererError';\n\ninterface ImageRendererProps {\n url: string;\n zoom: number;\n rotation: number;\n resetKey?: number;\n fileSize?: number;\n file?: PreviewFile | File;\n onZoomChange?: (zoom: number) => void;\n onNaturalWidthChange?: (width: number) => void;\n onNaturalHeightChange?: (height: number) => void;\n}\n\nexport const ImageRenderer: React.FC<ImageRendererProps> = ({\n url,\n zoom,\n rotation,\n resetKey,\n fileSize,\n file,\n onZoomChange,\n onNaturalWidthChange,\n onNaturalHeightChange\n}) => {\n const t = useTranslator();\n const [loaded, setLoaded] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [decoding, setDecoding] = useState(false);\n const [decodeProgress, setDecodeProgress] = useState(0);\n const [decodeError, setDecodeError] = useState<string | null>(null);\n const [imageSrc, setImageSrc] = useState<string>('');\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(1);\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 [internalZoom, setInternalZoom] = useState(1);\n const [naturalSize, setNaturalSize] = useState({ width: 0, height: 0 });\n const imgRef = useRef<HTMLImageElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const blobUrlRef = useRef<string | null>(null);\n const fileBlobRef = useRef<Blob | null>(null);\n const loaderRef = useRef<any>(null);\n const pageCacheRef = useRef<Map<number, string>>(new Map());\n const isTouchDevice = useRef(false);\n const touchStartDistance = useRef(0);\n const touchStartZoom = useRef(1);\n const touchStartPos = useRef({ x: 0, y: 0 });\n const lastTapTime = useRef(0);\n\n // 解码逻辑:检测格式并按需解码\n useEffect(() => {\n let cancelled = false;\n\n const decodeIfNeeded = async () => {\n // 重置状态:清空 src 以避免上一张图片的 onLoad/onError 误触发到新文件\n setImageSrc('');\n setLoaded(false);\n setError(null);\n setDecoding(false);\n setDecodeError(null);\n setDecodeProgress(0);\n setPosition({ x: 0, y: 0 });\n setInternalZoom(1);\n setCurrentPage(1);\n setTotalPages(1);\n\n // 清理旧的 blob URL 与缓存\n if (blobUrlRef.current) {\n URL.revokeObjectURL(blobUrlRef.current);\n blobUrlRef.current = null;\n }\n pageCacheRef.current.forEach((url) => URL.revokeObjectURL(url));\n pageCacheRef.current.clear();\n fileBlobRef.current = null;\n loaderRef.current = null;\n\n // 如果没有 file 对象,直接使用 url\n if (!file) {\n if (!cancelled) setImageSrc(url);\n return;\n }\n\n try {\n // 检测图片格式\n const mimeType = await detectImageFormat(file);\n const loader = await getLoaderForMimeType(mimeType);\n\n // 如果不需要解码,直接使用原 URL\n if (!loader || !(await loader.needsDecode(mimeType))) {\n if (!cancelled) setImageSrc(url);\n return;\n }\n\n // 需要解码\n setDecoding(true);\n\n // 获取文件 Blob\n let fileBlob: Blob;\n if (file instanceof Blob) {\n fileBlob = file;\n } else {\n const response = await fetch(url);\n if (!response.ok) throw new Error('Failed to fetch file');\n fileBlob = await response.blob();\n }\n\n if (cancelled) return;\n\n // 缓存 Blob 与 loader 以便后续翻页\n fileBlobRef.current = fileBlob;\n loaderRef.current = loader;\n\n // 缓存 Blob 与 loader 以便后续翻页\n fileBlobRef.current = fileBlob;\n loaderRef.current = loader;\n\n // 获取元数据(用于检测多页 TIFF)\n if (loader.getMetadata) {\n try {\n const metadata = await loader.getMetadata(fileBlob);\n if (!cancelled && metadata.pageCount && metadata.pageCount > 1) {\n setTotalPages(metadata.pageCount);\n }\n } catch {\n // 忽略元数据获取失败\n }\n }\n\n // 调用 loader 解码(第 1 页 / 缩略图模式)\n const decodedBlob = await loader.decode(fileBlob, {\n page: 1,\n fullQuality: false,\n onProgress: (percent: number) => {\n if (!cancelled) {\n setDecodeProgress(percent);\n }\n },\n });\n\n if (cancelled) return;\n\n // 生成 blob URL\n const blobUrl = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n blobUrlRef.current = blobUrl;\n pageCacheRef.current.set(1, blobUrl);\n setImageSrc(blobUrl);\n setDecoding(false);\n } catch (err: any) {\n if (!cancelled) {\n setDecodeError(err?.message || '解码失败');\n setDecoding(false);\n }\n }\n };\n\n decodeIfNeeded();\n\n return () => {\n cancelled = true;\n };\n }, [url, file]);\n\n // 多页 TIFF 翻页:切换页码时重新解码\n const handlePageChange = useCallback(async (page: number) => {\n if (!fileBlobRef.current || !loaderRef.current) return;\n if (page < 1 || page > totalPages) return;\n\n // 命中缓存:直接切换\n const cached = pageCacheRef.current.get(page);\n if (cached) {\n setCurrentPage(page);\n setImageSrc(cached);\n return;\n }\n\n // 解码新页面\n setDecoding(true);\n try {\n const decodedBlob = await loaderRef.current.decode(fileBlobRef.current, { page });\n const blobUrl = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n // LRU:缓存超过 10 页时删除最早的\n if (pageCacheRef.current.size >= 10) {\n const firstKey = pageCacheRef.current.keys().next().value;\n if (firstKey !== undefined) {\n const oldUrl = pageCacheRef.current.get(firstKey);\n if (oldUrl) URL.revokeObjectURL(oldUrl);\n pageCacheRef.current.delete(firstKey);\n }\n }\n\n pageCacheRef.current.set(page, blobUrl);\n setCurrentPage(page);\n setImageSrc(blobUrl);\n setDecoding(false);\n } catch (err: any) {\n setDecodeError(err?.message || '翻页解码失败');\n setDecoding(false);\n }\n }, [totalPages]);\n\n // Cleanup blob URL on unmount\n useEffect(() => {\n return () => {\n if (blobUrlRef.current) {\n URL.revokeObjectURL(blobUrlRef.current);\n }\n pageCacheRef.current.forEach((url) => URL.revokeObjectURL(url));\n pageCacheRef.current.clear();\n };\n }, []);\n\n // 当外部 zoom 改变时,同步内部 zoom\n useEffect(() => {\n setInternalZoom(zoom);\n }, [zoom]);\n\n // 适应窗口/原始尺寸等操作时重置位置居中\n useEffect(() => {\n if (resetKey !== undefined) {\n setPosition({ x: 0, y: 0 });\n }\n }, [resetKey]);\n\n const handleLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {\n setLoaded(true);\n const img = e.currentTarget;\n setNaturalSize({ width: img.naturalWidth, height: img.naturalHeight });\n onNaturalWidthChange?.(img.naturalWidth);\n onNaturalHeightChange?.(img.naturalHeight);\n };\n\n // 边界限制:确保图片至少有一部分可见\n const clampPosition = useCallback((pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.current;\n if (!container || naturalSize.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.width * currentZoom;\n const imgH = naturalSize.height * currentZoom;\n\n // 至少保留 margin px 的图片在视口内\n const margin = Math.min(80, containerW * 0.15, containerH * 0.15);\n const rangeX = (containerW + imgW) / 2 - margin;\n const rangeY = (containerH + imgH) / 2 - margin;\n\n return {\n x: rangeX > 0 ? Math.max(-rangeX, Math.min(rangeX, pos.x)) : 0,\n y: rangeY > 0 ? Math.max(-rangeY, Math.min(rangeY, pos.y)) : 0,\n };\n }, [naturalSize]);\n\n const handleError = () => {\n setError(t('image.load_failed'));\n setLoaded(true);\n };\n\n // 双击复原:居中 + 缩放100%\n const handleDoubleClick = () => {\n setPosition({ x: 0, y: 0 });\n setInternalZoom(1);\n onZoomChange?.(1);\n };\n\n // 触屏事件处理\n const handleTouchStart = useCallback((e: TouchEvent) => {\n isTouchDevice.current = true;\n e.preventDefault();\n\n const touches = e.touches;\n if (touches.length === 1) {\n // 单指拖拽\n setIsDragging(true);\n setDragStart({\n x: touches[0].clientX - position.x,\n y: touches[0].clientY - position.y,\n });\n\n // 双击检测\n const now = Date.now();\n if (now - lastTapTime.current < 300) {\n // 双击复原:居中 + 缩放100%\n setPosition({ x: 0, y: 0 });\n setInternalZoom(1);\n onZoomChange?.(1);\n }\n lastTapTime.current = now;\n } else if (touches.length === 2) {\n // 双指缩放初始化\n setIsDragging(false);\n const distance = Math.hypot(\n touches[1].clientX - touches[0].clientX,\n touches[1].clientY - touches[0].clientY\n );\n touchStartDistance.current = distance;\n touchStartZoom.current = internalZoom;\n touchStartPos.current = { ...position };\n }\n }, [position, internalZoom, onZoomChange]);\n\n const handleTouchMove = useCallback((e: TouchEvent) => {\n e.preventDefault();\n\n const touches = e.touches;\n if (touches.length === 1 && isDragging) {\n // 单指拖拽\n setPosition(clampPosition({\n x: touches[0].clientX - dragStart.x,\n y: touches[0].clientY - dragStart.y,\n }, internalZoom));\n } else if (touches.length === 2) {\n // 双指缩放\n const container = containerRef.current;\n if (!container) return;\n\n const distance = Math.hypot(\n touches[1].clientX - touches[0].clientX,\n touches[1].clientY - touches[0].clientY\n );\n\n // 最小距离变化阈值,防止抖动\n if (Math.abs(distance - touchStartDistance.current) < 5) return;\n\n const scale = distance / touchStartDistance.current;\n const newZoom = Math.max(0.01, Math.min(10, touchStartZoom.current * scale));\n\n // 双指中心点作为缩放原点\n const rect = container.getBoundingClientRect();\n const centerX = (touches[0].clientX + touches[1].clientX) / 2 - rect.left - rect.width / 2;\n const centerY = (touches[0].clientY + touches[1].clientY) / 2 - rect.top - rect.height / 2;\n\n const zoomScale = newZoom / internalZoom;\n setPosition(clampPosition({\n x: centerX - zoomScale * (centerX - touchStartPos.current.x),\n y: centerY - zoomScale * (centerY - touchStartPos.current.y),\n }, newZoom));\n\n setInternalZoom(newZoom);\n onZoomChange?.(newZoom);\n }\n }, [isDragging, dragStart, internalZoom, clampPosition, onZoomChange]);\n\n const handleTouchEnd = useCallback(() => {\n setIsDragging(false);\n touchStartDistance.current = 0;\n }, []);\n\n // 鼠标滚轮缩放 —— 以鼠标位置为缩放原点\n // 使用原生事件 + passive: false,确保 preventDefault 生效,\n // 避免滚轮事件冒泡触发外层(如嵌入模式下的页面滚动)\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const rect = container.getBoundingClientRect();\n const mouseX = e.clientX - rect.left - rect.width / 2;\n const mouseY = e.clientY - rect.top - rect.height / 2;\n\n const delta = e.deltaY > 0 ? -0.05 : 0.05;\n\n setInternalZoom(prev => {\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n setPosition(pos => clampPosition({\n x: mouseX - scale * (mouseX - pos.x),\n y: mouseY - scale * (mouseY - pos.y),\n }, newZoom));\n\n onZoomChange?.(newZoom);\n return newZoom;\n });\n };\n\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n return () => container.removeEventListener('wheel', handleWheelNative);\n }, [onZoomChange, clampPosition]);\n\n // 触屏事件监听器\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n container.addEventListener('touchstart', handleTouchStart, { passive: false });\n container.addEventListener('touchmove', handleTouchMove, { passive: false });\n container.addEventListener('touchend', handleTouchEnd);\n container.addEventListener('touchcancel', handleTouchEnd);\n\n return () => {\n container.removeEventListener('touchstart', handleTouchStart);\n container.removeEventListener('touchmove', handleTouchMove);\n container.removeEventListener('touchend', handleTouchEnd);\n container.removeEventListener('touchcancel', handleTouchEnd);\n };\n }, [handleTouchStart, handleTouchMove, handleTouchEnd]);\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n if (isTouchDevice.current) return;\n if (e.button !== 0) return;\n setIsDragging(true);\n setDragStart({\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n });\n }, [position]);\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (isTouchDevice.current) return;\n if (!isDragging) return;\n setPosition(clampPosition({\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n }, internalZoom));\n }, [isDragging, dragStart, internalZoom, clampPosition]);\n\n const handleMouseUp = useCallback(() => {\n if (isTouchDevice.current) return;\n setIsDragging(false);\n }, []);\n\n return (\n <div\n ref={containerRef}\n className=\"rfp-relative rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-overflow-hidden\"\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n style={{ cursor: isDragging ? 'grabbing' : 'grab', touchAction: 'none' }}\n >\n {/* 解码中 */}\n {decoding && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-flex-col rfp-items-center rfp-justify-center rfp-bg-surface-1/80 rfp-z-10\">\n <Loader2 className=\"rfp-w-12 rfp-h-12 rfp-text-fg-primary rfp-animate-spin\" />\n <p className=\"rfp-mt-4 rfp-text-fg-secondary\">\n 正在解码... {decodeProgress > 0 && `${Math.round(decodeProgress)}%`}\n </p>\n </div>\n )}\n\n {/* 解码错误 */}\n {decodeError && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-1/80 rfp-z-10\">\n <RendererError message={t('image.decode_failed')} detail={decodeError} />\n </div>\n )}\n\n {!loaded && !error && !decoding && !decodeError && (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {error && (\n <RendererError message={error} />\n )}\n\n {imageSrc && (\n <motion.img\n ref={imgRef}\n src={imageSrc}\n alt=\"Preview\"\n className={`rfp-max-w-none rfp-select-none ${!loaded || error || decodeError ? 'rfp-hidden' : ''}`}\n style={{\n transform: `translate(${position.x}px, ${position.y}px) scale(${internalZoom}) rotate(${rotation}deg)`,\n transformOrigin: 'center',\n transition: isDragging ? 'none' : 'transform 0.3s ease-out',\n }}\n onLoad={handleLoad}\n onError={handleError}\n onDoubleClick={handleDoubleClick}\n initial={{ opacity: 0 }}\n animate={{ opacity: loaded && !error && !decodeError ? 1 : 0 }}\n transition={{ duration: 0.3 }}\n draggable={false}\n />\n )}\n\n {/* 右下角分辨率 */}\n {loaded && !error && naturalSize.width > 0 && (\n <div className=\"rfp-absolute rfp-bottom-2 rfp-right-3 rfp-text-[10px] rfp-text-fg-disabled hover:rfp-text-fg-secondary rfp-transition-colors rfp-pointer-events-auto rfp-select-none rfp-cursor-default\">\n {naturalSize.width} × {naturalSize.height}{fileSize != null && ` · ${fileSize < 1024 ? `${fileSize} B` : fileSize < 1024 * 1024 ? `${(fileSize / 1024).toFixed(1)} KB` : `${(fileSize / (1024 * 1024)).toFixed(1)} MB`}`}\n </div>\n )}\n\n {/* 多页 TIFF 翻页器 */}\n {totalPages > 1 && (\n <div className=\"rfp-absolute rfp-bottom-2 rfp-left-1/2 -rfp-translate-x-1/2 rfp-flex rfp-items-center rfp-gap-2 rfp-px-3 rfp-py-1.5 rfp-bg-surface-toolbar rfp-border rfp-border-line rfp-rounded-lg rfp-text-sm rfp-text-fg-primary rfp-shadow-md\">\n <button\n type=\"button\"\n onClick={() => handlePageChange(currentPage - 1)}\n disabled={currentPage <= 1 || decoding}\n className=\"rfp-px-2 rfp-py-0.5 rfp-rounded hover:rfp-bg-surface-nav-hover disabled:rfp-opacity-40 disabled:rfp-cursor-not-allowed\"\n >\n 上一页\n </button>\n <span className=\"rfp-text-fg-secondary rfp-tabular-nums\">\n {currentPage} / {totalPages}\n </span>\n <button\n type=\"button\"\n onClick={() => handlePageChange(currentPage + 1)}\n disabled={currentPage >= totalPages || decoding}\n className=\"rfp-px-2 rfp-py-0.5 rfp-rounded hover:rfp-bg-surface-nav-hover disabled:rfp-opacity-40 disabled:rfp-cursor-not-allowed\"\n >\n 下一页\n </button>\n </div>\n )}\n </div>\n );\n};\n"],"names":["ImageRenderer","url","zoom","rotation","resetKey","fileSize","file","onZoomChange","onNaturalWidthChange","onNaturalHeightChange","t","useTranslator","loaded","setLoaded","useState","error","setError","decoding","setDecoding","decodeProgress","setDecodeProgress","decodeError","setDecodeError","imageSrc","setImageSrc","currentPage","setCurrentPage","totalPages","setTotalPages","position","setPosition","isDragging","setIsDragging","dragStart","setDragStart","internalZoom","setInternalZoom","naturalSize","setNaturalSize","imgRef","useRef","containerRef","blobUrlRef","fileBlobRef","loaderRef","pageCacheRef","isTouchDevice","touchStartDistance","touchStartZoom","touchStartPos","lastTapTime","useEffect","cancelled","mimeType","detectImageFormat","loader","getLoaderForMimeType","fileBlob","response","metadata","decodedBlob","percent","blobUrl","err","handlePageChange","useCallback","page","cached","firstKey","oldUrl","handleLoad","img","clampPosition","pos","currentZoom","container","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleError","handleDoubleClick","handleTouchStart","touches","now","distance","handleTouchMove","scale","newZoom","rect","centerX","centerY","zoomScale","handleTouchEnd","handleWheelNative","e","mouseX","mouseY","delta","prev","handleMouseDown","handleMouseMove","handleMouseUp","jsxs","jsx","Loader2","RendererError","motion"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-C_BJatqr.mjs","sources":["../../src/renderers/Subtitle/index.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport {\n parseSubtitle,\n formatSubtitleTime,\n fetchTextUtf8,\n type SubtitleParseResult,\n type SubtitleFormat,\n} from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { RendererError } from '../RendererError';\n\ninterface SubtitleRendererProps {\n url: string;\n fileName: string;\n}\n\nconst FORMAT_BY_EXT: Record<string, SubtitleFormat> = {\n srt: 'srt',\n vtt: 'vtt',\n lrc: 'lrc',\n elrc: 'elrc',\n ass: 'ass',\n ssa: 'ssa',\n ttml: 'ttml',\n dfxp: 'ttml',\n};\n\nconst getFormat = (fileName: string): SubtitleFormat | undefined => {\n const ext = fileName.split('.').pop()?.toLowerCase() || '';\n return FORMAT_BY_EXT[ext];\n};\n\nexport const SubtitleRenderer: React.FC<SubtitleRendererProps> = ({ url, fileName }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [text, setText] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const controller = new AbortController();\n const load = async () => {\n try {\n setLoading(true);\n setError(null);\n setText(await fetchTextUtf8(url, { fetcher, signal: controller.signal }));\n } catch (err: any) {\n if (err.name === 'AbortError') return;\n console.warn('[SubtitleRenderer] Failed to load subtitle:', err instanceof Error ? err.message : String(err));\n setError(t('subtitle.load_failed'));\n } finally {\n setLoading(false);\n }\n };\n load();\n return () => controller.abort();\n }, [url]);\n\n const parsed: SubtitleParseResult | null = useMemo(() => {\n if (!text) return null;\n try {\n return parseSubtitle(text, getFormat(fileName));\n } catch (err) {\n // 字幕解析失败通常是格式不支持或文件损坏,用 warn 级别记录\n console.warn('[SubtitleRenderer] Failed to parse subtitle:', err instanceof Error ? err.message : String(err));\n return null;\n }\n }, [text, fileName]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-bg-[#0f0f12]\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error || !parsed) {\n return <RendererError message={error || t('subtitle.parse_failed')} />;\n }\n\n const isLyric = parsed.format === 'lrc' || parsed.format === 'elrc';\n const meta = parsed.metadata ?? {};\n const dotHover = isLyric ? 'group-hover:rfp-bg-violet-400' : 'group-hover:rfp-bg-sky-400';\n\n return (\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-bg-[#0f0f12]\">\n {/* 内容滚动区 */}\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-px-4 rfp-pt-6 rfp-pb-16\">\n <div className=\"rfp-relative\">\n {/* vertical line */}\n <div className=\"rfp-absolute rfp-left-[5px] rfp-top-2 rfp-bottom-2 rfp-w-px rfp-bg-surface-1\" />\n\n <ol className=\"rfp-space-y-5\">\n {parsed.cues.map((cue, i) => (\n <li key={`cue-${i}`} className=\"rfp-relative rfp-pl-6 rfp-group\">\n {/* dot */}\n <div\n className={`rfp-absolute rfp-left-0 rfp-top-[0.4rem] rfp-w-3 rfp-h-3 rfp-rounded-full rfp-bg-surface-3 rfp-border-2 rfp-border-[#0f0f12] rfp-transition-colors ${dotHover}`}\n />\n\n <div className=\"rfp-flex rfp-flex-wrap rfp-items-baseline rfp-gap-x-3 rfp-gap-y-1 rfp-mb-1.5\">\n <span className=\"rfp-text-[11px] rfp-font-mono rfp-text-fg-muted rfp-tabular-nums\">\n {formatSubtitleTime(cue.start)}\n </span>\n <span className=\"rfp-text-[11px] rfp-text-fg-disabled\">→</span>\n <span className=\"rfp-text-[11px] rfp-font-mono rfp-text-fg-muted rfp-tabular-nums\">\n {formatSubtitleTime(cue.end)}\n </span>\n <span className=\"rfp-text-[10px] rfp-font-mono rfp-text-fg-disabled rfp-tabular-nums\">\n #{cue.id ?? i + 1}\n </span>\n {cue.style && (\n <span className=\"rfp-text-[9px] rfp-uppercase rfp-tracking-widest rfp-text-fg-tertiary rfp-px-1.5 rfp-py-0.5 rfp-rounded rfp-bg-surface-1 rfp-border rfp-border-line-weak\">\n {cue.style}\n </span>\n )}\n </div>\n\n {cue.words && cue.words.length > 0 ? (\n <div className=\"rfp-flex rfp-flex-wrap rfp-gap-x-1.5 rfp-gap-y-1 rfp-text-base rfp-text-fg-primary rfp-leading-relaxed group-hover:rfp-text-fg-primary rfp-transition-colors\">\n {cue.words.map((word, wi) => (\n <span\n key={`w-${wi}`}\n className=\"rfp-inline-flex rfp-flex-col rfp-items-start\"\n title={formatSubtitleTime(word.start)}\n >\n <span className=\"rfp-text-[9px] rfp-text-fg-disabled rfp-font-mono rfp-leading-none rfp-tabular-nums\">\n {formatSubtitleTime(word.start).slice(3, 8)}\n </span>\n <span className=\"rfp-leading-snug\">{word.text}</span>\n </span>\n ))}\n </div>\n ) : (\n <p\n className={`rfp-whitespace-pre-wrap rfp-break-words rfp-leading-relaxed group-hover:rfp-text-fg-primary rfp-transition-colors rfp-text-fg-primary rfp-min-h-[1.25rem] ${\n isLyric ? 'rfp-text-base rfp-font-medium' : 'rfp-text-sm'\n }`}\n >\n {cue.text}\n </p>\n )}\n </li>\n ))}\n </ol>\n </div>\n </div>\n\n {/* 底部状态栏 */}\n <div className=\"rfp-pointer-events-none rfp-absolute rfp-bottom-3 rfp-right-3 rfp-flex rfp-items-center rfp-gap-2 rfp-px-2.5 rfp-py-1 rfp-rounded-full rfp-bg-surface-nav rfp-backdrop-blur rfp-border rfp-border-line-weak rfp-text-[10px] rfp-text-fg-tertiary rfp-font-mono rfp-tabular-nums\">\n <span>{parsed.cues.length} {isLyric ? t('subtitle.lines') : t('subtitle.cues')}</span>\n {meta.length && (\n <>\n <span className=\"rfp-text-fg-disabled\">·</span>\n <span>{meta.length}</span>\n </>\n )}\n </div>\n </div>\n );\n};\n"],"names":["FORMAT_BY_EXT","getFormat","fileName","ext","_a","SubtitleRenderer","url","t","useTranslator","fetcher","useFetcher","text","setText","useState","loading","setLoading","error","setError","useEffect","controller","fetchTextUtf8","err","parsed","useMemo","parseSubtitle","jsx","RendererError","isLyric","meta","dotHover","jsxs","cue","i","formatSubtitleTime","word","wi","Fragment"],"mappings":"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"}
|
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import { jsxs as E, jsx as l } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as dr, useRef as f, useState as x, useCallback as b, useImperativeHandle as mr, useEffect as q } from "react";
|
|
3
|
-
import hr from "@likecoin/epub-ts";
|
|
4
|
-
import { X as br } from "lucide-react";
|
|
5
|
-
import { u as wr, a as gr } from "./index-CEeKt7L3.mjs";
|
|
6
|
-
import { R as yr } from "./RendererError-D5i8eSpN.mjs";
|
|
7
|
-
if (typeof document < "u" && !document.getElementById("rfp-epub-styles")) {
|
|
8
|
-
const u = document.createElement("style");
|
|
9
|
-
u.id = "rfp-epub-styles", u.textContent = `
|
|
10
|
-
.epub-container { overflow-y: auto !important; scrollbar-width: thin; }
|
|
11
|
-
.epub-container::-webkit-scrollbar { width: 8px; }
|
|
12
|
-
.epub-container::-webkit-scrollbar-track { background: transparent; }
|
|
13
|
-
.epub-container::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 4px; }
|
|
14
|
-
.epub-container::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.3); }
|
|
15
|
-
.epub-view > iframe { background: white; }
|
|
16
|
-
`, document.head.appendChild(u);
|
|
17
|
-
}
|
|
18
|
-
const vr = 794, Er = dr(
|
|
19
|
-
({ url: u, onChapterChange: M, onFullWidthChange: X }, sr) => {
|
|
20
|
-
const _ = wr(), cr = gr(), h = f(null), I = f(null), p = f(null), d = f(M), W = f(X);
|
|
21
|
-
d.current = M, W.current = X;
|
|
22
|
-
const k = f(0), w = f(null), G = f(!1), [ar, j] = x(!0), [A, O] = x(null), [U, fr] = x(!1), [B, V] = x([]), [S, T] = x(!1), [J, K] = x(""), Q = f([]);
|
|
23
|
-
Q.current = B, G.current = U;
|
|
24
|
-
const Y = b(() => {
|
|
25
|
-
var r;
|
|
26
|
-
(r = p.current) == null || r.prev();
|
|
27
|
-
}, []), Z = b(() => {
|
|
28
|
-
var r;
|
|
29
|
-
(r = p.current) == null || r.next();
|
|
30
|
-
}, []), g = f(null), z = f(0), D = f((r) => {
|
|
31
|
-
var i, s;
|
|
32
|
-
const e = g.current;
|
|
33
|
-
if (!e) return;
|
|
34
|
-
const t = e;
|
|
35
|
-
if (t.scrollTop + t.clientHeight >= t.scrollHeight - 200)
|
|
36
|
-
try {
|
|
37
|
-
const n = (i = p.current) == null ? void 0 : i.manager;
|
|
38
|
-
(s = n == null ? void 0 : n.check) == null || s.call(n, 500, 500);
|
|
39
|
-
} catch {
|
|
40
|
-
}
|
|
41
|
-
}), y = b(() => {
|
|
42
|
-
g.current && (g.current.removeEventListener("scroll", D.current), g.current = null), cancelAnimationFrame(z.current);
|
|
43
|
-
const r = () => {
|
|
44
|
-
var t;
|
|
45
|
-
const e = ((t = h.current) == null ? void 0 : t.querySelector(".epub-container")) ?? null;
|
|
46
|
-
if (!e) {
|
|
47
|
-
z.current = requestAnimationFrame(r);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
g.current = e, e.addEventListener("scroll", D.current, { passive: !0 });
|
|
51
|
-
};
|
|
52
|
-
z.current = requestAnimationFrame(r);
|
|
53
|
-
}, []), C = b(() => {
|
|
54
|
-
var e;
|
|
55
|
-
const r = !G.current;
|
|
56
|
-
fr(r), (e = W.current) == null || e.call(W, r), setTimeout(() => {
|
|
57
|
-
const t = h.current, o = p.current;
|
|
58
|
-
!t || !o || (o.resize(t.offsetWidth, t.offsetHeight), w.current && o.display(w.current), y());
|
|
59
|
-
}, 350);
|
|
60
|
-
}, [y]), rr = b(() => {
|
|
61
|
-
T((r) => !r);
|
|
62
|
-
}, []), lr = b((r) => {
|
|
63
|
-
var e;
|
|
64
|
-
K(r), (e = p.current) == null || e.display(r), T(!1);
|
|
65
|
-
}, []);
|
|
66
|
-
mr(sr, () => ({
|
|
67
|
-
prevPage: Y,
|
|
68
|
-
nextPage: Z,
|
|
69
|
-
toggleFullWidth: C,
|
|
70
|
-
toggleToc: rr
|
|
71
|
-
}), [Y, Z, C, rr]), q(() => {
|
|
72
|
-
const r = h.current;
|
|
73
|
-
if (!r || !u) return;
|
|
74
|
-
j(!0), O(null), V([]), T(!1), r.innerHTML = "", w.current = null, k.current = 0;
|
|
75
|
-
let e = !1;
|
|
76
|
-
const t = window.setTimeout(() => {
|
|
77
|
-
e || o();
|
|
78
|
-
}, 0), o = async () => {
|
|
79
|
-
var i;
|
|
80
|
-
try {
|
|
81
|
-
let s = u;
|
|
82
|
-
u.startsWith("blob:") && (s = await (await cr(u)).arrayBuffer());
|
|
83
|
-
const n = hr(s);
|
|
84
|
-
I.current = n;
|
|
85
|
-
const c = n.renderTo(r, {
|
|
86
|
-
manager: "continuous",
|
|
87
|
-
flow: "scrolled",
|
|
88
|
-
width: "100%",
|
|
89
|
-
height: "100%"
|
|
90
|
-
});
|
|
91
|
-
p.current = c, c.themes.register("default", {
|
|
92
|
-
body: {
|
|
93
|
-
background: "#ffffff !important",
|
|
94
|
-
color: "#1a1a1a !important",
|
|
95
|
-
"font-family": '"Noto Serif SC", "Source Han Serif SC", Georgia, "Times New Roman", serif !important',
|
|
96
|
-
"font-size": "16px !important",
|
|
97
|
-
"line-height": "2 !important",
|
|
98
|
-
padding: "40px 60px !important",
|
|
99
|
-
"max-width": "100% !important",
|
|
100
|
-
"box-sizing": "border-box !important",
|
|
101
|
-
"word-break": "break-word !important",
|
|
102
|
-
"overflow-wrap": "break-word !important"
|
|
103
|
-
},
|
|
104
|
-
p: { "text-indent": "2em !important", margin: "0.8em 0 !important" },
|
|
105
|
-
h1: { "text-align": "center !important", margin: "1.5em 0 1em !important" },
|
|
106
|
-
h2: { margin: "1.2em 0 0.8em !important" },
|
|
107
|
-
h3: { margin: "1em 0 0.6em !important" },
|
|
108
|
-
img: { "max-width": "100% !important", height: "auto !important" },
|
|
109
|
-
a: { color: "#2563eb !important", "text-decoration": "none !important" }
|
|
110
|
-
}), c.themes.select("default"), await n.ready, n.locations.generate(1024).then(() => {
|
|
111
|
-
var N, R, H;
|
|
112
|
-
if (e) return;
|
|
113
|
-
k.current = n.locations.length();
|
|
114
|
-
const m = (N = p.current) == null ? void 0 : N.currentLocation(), a = ((R = m == null ? void 0 : m.start) == null ? void 0 : R.location) ?? 0;
|
|
115
|
-
(H = d.current) == null || H.call(d, a + 1, k.current);
|
|
116
|
-
}).catch(() => {
|
|
117
|
-
});
|
|
118
|
-
const v = await n.loaded.navigation;
|
|
119
|
-
if (!e && Array.isArray(v == null ? void 0 : v.toc) && V(v.toc), await c.display(), e) return;
|
|
120
|
-
j(!1), (i = d.current) == null || i.call(d, 1, k.current || 1), c.on("relocated", (m) => {
|
|
121
|
-
var H, er, nr, or;
|
|
122
|
-
const a = m;
|
|
123
|
-
if ((H = a == null ? void 0 : a.start) != null && H.cfi && (w.current = a.start.cfi), (er = a == null ? void 0 : a.start) != null && er.href) {
|
|
124
|
-
const P = a.start.href, $ = [], ir = (pr) => {
|
|
125
|
-
for (const L of pr) {
|
|
126
|
-
const F = L.href.split("#")[0];
|
|
127
|
-
F && (P === F || P.endsWith("/" + F) || P.endsWith(F)) && $.push(L.href), L.subitems && ir(L.subitems);
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
ir(Q.current), $.length === 1 && K($[0]);
|
|
131
|
-
}
|
|
132
|
-
const N = (nr = a == null ? void 0 : a.start) == null ? void 0 : nr.location, R = k.current;
|
|
133
|
-
typeof N == "number" && R > 0 && ((or = d.current) == null || or.call(d, N + 1, R));
|
|
134
|
-
});
|
|
135
|
-
} catch (s) {
|
|
136
|
-
console.error("EPUB 加载错误:", s), e || (O(_("epub.load_failed")), j(!1));
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
return () => {
|
|
140
|
-
var i, s, n;
|
|
141
|
-
e = !0, window.clearTimeout(t);
|
|
142
|
-
try {
|
|
143
|
-
(s = (i = p.current) == null ? void 0 : i.destroy) == null || s.call(i);
|
|
144
|
-
} catch {
|
|
145
|
-
}
|
|
146
|
-
try {
|
|
147
|
-
(n = I.current) == null || n.destroy();
|
|
148
|
-
} catch {
|
|
149
|
-
}
|
|
150
|
-
p.current = null, I.current = null;
|
|
151
|
-
};
|
|
152
|
-
}, [u]), q(() => {
|
|
153
|
-
const r = h.current;
|
|
154
|
-
if (!r) return;
|
|
155
|
-
let e = !0, t = { width: 0, height: 0 }, o = null;
|
|
156
|
-
const i = () => {
|
|
157
|
-
const n = h.current, c = p.current;
|
|
158
|
-
if (!(!n || !c)) {
|
|
159
|
-
if (c.resize(n.offsetWidth, n.offsetHeight), w.current)
|
|
160
|
-
try {
|
|
161
|
-
c.display(w.current);
|
|
162
|
-
} catch {
|
|
163
|
-
}
|
|
164
|
-
y();
|
|
165
|
-
}
|
|
166
|
-
}, s = new ResizeObserver(() => {
|
|
167
|
-
const n = h.current;
|
|
168
|
-
if (!n) return;
|
|
169
|
-
if (e) {
|
|
170
|
-
e = !1, t = { width: n.offsetWidth, height: n.offsetHeight };
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
const c = { width: n.offsetWidth, height: n.offsetHeight }, v = Math.abs(t.width - c.width), m = Math.abs(t.height - c.height);
|
|
174
|
-
v < 10 && m < 10 || (t = c, o !== null && clearTimeout(o), o = window.setTimeout(() => {
|
|
175
|
-
i();
|
|
176
|
-
}, 350));
|
|
177
|
-
});
|
|
178
|
-
return s.observe(r), () => {
|
|
179
|
-
s.disconnect(), o !== null && clearTimeout(o);
|
|
180
|
-
};
|
|
181
|
-
}, [y]), q(() => (y(), () => {
|
|
182
|
-
var r;
|
|
183
|
-
cancelAnimationFrame(z.current), (r = g.current) == null || r.removeEventListener("scroll", D.current);
|
|
184
|
-
}), [u, y]);
|
|
185
|
-
const ur = b((r) => r === J, [J]), tr = (r, e = 0) => /* @__PURE__ */ l("ul", { style: { marginLeft: e > 0 ? 16 : 0 }, children: r.map((t, o) => {
|
|
186
|
-
const i = ur(t.href);
|
|
187
|
-
return /* @__PURE__ */ E("li", { children: [
|
|
188
|
-
/* @__PURE__ */ l(
|
|
189
|
-
"button",
|
|
190
|
-
{
|
|
191
|
-
onClick: () => lr(t.href),
|
|
192
|
-
className: `rfp-w-full rfp-text-left rfp-py-2 rfp-px-3 rfp-text-sm rfp-rounded rfp-transition-all rfp-truncate ${i ? "rfp-text-fg-primary rfp-bg-surface-3 rfp-font-medium" : "rfp-text-fg-secondary hover:rfp-text-fg-primary hover:rfp-bg-surface-2"}`,
|
|
193
|
-
title: t.label,
|
|
194
|
-
children: t.label.trim()
|
|
195
|
-
}
|
|
196
|
-
),
|
|
197
|
-
t.subitems && t.subitems.length > 0 && tr(t.subitems, e + 1)
|
|
198
|
-
] }, `${t.href}-${o}`);
|
|
199
|
-
}) });
|
|
200
|
-
return /* @__PURE__ */ E("div", { className: "rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-justify-center rfp-bg-surface-1 rfp-overflow-hidden", children: [
|
|
201
|
-
A && /* @__PURE__ */ l(yr, { message: A }),
|
|
202
|
-
ar && !A && /* @__PURE__ */ l("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-z-10", children: /* @__PURE__ */ l("div", { className: "rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin" }) }),
|
|
203
|
-
B.length > 0 && /* @__PURE__ */ E(
|
|
204
|
-
"div",
|
|
205
|
-
{
|
|
206
|
-
className: "rfp-absolute rfp-inset-0 rfp-z-20 rfp-flex rfp-transition-opacity rfp-duration-300",
|
|
207
|
-
style: {
|
|
208
|
-
opacity: S ? 1 : 0,
|
|
209
|
-
pointerEvents: S ? "auto" : "none"
|
|
210
|
-
},
|
|
211
|
-
children: [
|
|
212
|
-
/* @__PURE__ */ E(
|
|
213
|
-
"div",
|
|
214
|
-
{
|
|
215
|
-
className: "rfp-w-72 rfp-max-w-[80%] rfp-h-full rfp-bg-surface-overlay rfp-backdrop-blur-xl rfp-border-r rfp-border-line-weak rfp-flex rfp-flex-col rfp-shadow-2xl rfp-transition-transform rfp-duration-300",
|
|
216
|
-
style: { transform: S ? "translateX(0)" : "translateX(-100%)" },
|
|
217
|
-
children: [
|
|
218
|
-
/* @__PURE__ */ E("div", { className: "rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-3 rfp-border-b rfp-border-line-weak rfp-flex-shrink-0", children: [
|
|
219
|
-
/* @__PURE__ */ l("span", { className: "rfp-text-fg-primary rfp-font-medium rfp-text-sm", children: _("toolbar.toc") }),
|
|
220
|
-
/* @__PURE__ */ l(
|
|
221
|
-
"button",
|
|
222
|
-
{
|
|
223
|
-
onClick: () => T(!1),
|
|
224
|
-
className: "rfp-text-fg-tertiary hover:rfp-text-fg-primary rfp-transition-colors",
|
|
225
|
-
children: /* @__PURE__ */ l(br, { className: "rfp-w-4 rfp-h-4" })
|
|
226
|
-
}
|
|
227
|
-
)
|
|
228
|
-
] }),
|
|
229
|
-
/* @__PURE__ */ l("div", { className: "rfp-flex-1 rfp-overflow-y-auto rfp-py-4 rfp-px-1", children: tr(B) })
|
|
230
|
-
]
|
|
231
|
-
}
|
|
232
|
-
),
|
|
233
|
-
/* @__PURE__ */ l(
|
|
234
|
-
"div",
|
|
235
|
-
{
|
|
236
|
-
className: "rfp-flex-1 rfp-transition-opacity rfp-duration-300",
|
|
237
|
-
style: { background: S ? "rgba(0,0,0,0.3)" : "transparent" },
|
|
238
|
-
onClick: () => T(!1)
|
|
239
|
-
}
|
|
240
|
-
)
|
|
241
|
-
]
|
|
242
|
-
}
|
|
243
|
-
),
|
|
244
|
-
!A && /* @__PURE__ */ l(
|
|
245
|
-
"div",
|
|
246
|
-
{
|
|
247
|
-
ref: h,
|
|
248
|
-
className: "rfp-h-full rfp-bg-surface-toolbar rfp-shadow-lg",
|
|
249
|
-
style: {
|
|
250
|
-
width: U ? "100%" : `${vr}px`,
|
|
251
|
-
maxWidth: "100%",
|
|
252
|
-
transition: "width 0.3s ease",
|
|
253
|
-
overflow: "hidden"
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
)
|
|
257
|
-
] });
|
|
258
|
-
}
|
|
259
|
-
);
|
|
260
|
-
export {
|
|
261
|
-
Er as EpubRenderer
|
|
262
|
-
};
|
|
263
|
-
//# sourceMappingURL=index-Cbz5Z6ZK.mjs.map
|