@zero-library/common 2.2.7 → 2.2.9
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/index.cjs.js +626 -626
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +624 -624
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -6,9 +6,15 @@ var antd = require('antd');
|
|
|
6
6
|
var classNames = require('classnames');
|
|
7
7
|
var docxPreview = require('docx-preview');
|
|
8
8
|
var React16 = require('react');
|
|
9
|
+
var AES = require('crypto-js/aes');
|
|
10
|
+
var encUtf8 = require('crypto-js/enc-utf8');
|
|
11
|
+
var MarkdownIt = require('markdown-it');
|
|
12
|
+
var Decimal = require('decimal.js');
|
|
13
|
+
var dayjs = require('dayjs');
|
|
14
|
+
var relativeTime = require('dayjs/plugin/relativeTime');
|
|
15
|
+
var axios = require('axios');
|
|
9
16
|
var parse = require('html-react-parser');
|
|
10
17
|
var jsonrepair = require('jsonrepair');
|
|
11
|
-
var markdownit = require('markdown-it');
|
|
12
18
|
var core$1 = require('@react-pdf-viewer/core');
|
|
13
19
|
var pageNavigation = require('@react-pdf-viewer/page-navigation');
|
|
14
20
|
var thumbnail = require('@react-pdf-viewer/thumbnail');
|
|
@@ -16,12 +22,6 @@ var zoom = require('@react-pdf-viewer/zoom');
|
|
|
16
22
|
require('@react-pdf-viewer/core/lib/styles/index.css');
|
|
17
23
|
var zh_CN = require('@react-pdf-viewer/locales/lib/zh_CN.json');
|
|
18
24
|
require('@react-pdf-viewer/page-navigation/lib/styles/index.css');
|
|
19
|
-
var AES = require('crypto-js/aes');
|
|
20
|
-
var encUtf8 = require('crypto-js/enc-utf8');
|
|
21
|
-
var Decimal = require('decimal.js');
|
|
22
|
-
var dayjs = require('dayjs');
|
|
23
|
-
var relativeTime = require('dayjs/plugin/relativeTime');
|
|
24
|
-
var axios = require('axios');
|
|
25
25
|
require('@react-pdf-viewer/thumbnail/lib/styles/index.css');
|
|
26
26
|
require('@react-pdf-viewer/zoom/lib/styles/index.css');
|
|
27
27
|
var react = require('@tiptap/react');
|
|
@@ -69,15 +69,15 @@ function _interopNamespace(e) {
|
|
|
69
69
|
var Icon__default = /*#__PURE__*/_interopDefault(Icon);
|
|
70
70
|
var classNames__default = /*#__PURE__*/_interopDefault(classNames);
|
|
71
71
|
var React16__namespace = /*#__PURE__*/_interopNamespace(React16);
|
|
72
|
-
var parse__default = /*#__PURE__*/_interopDefault(parse);
|
|
73
|
-
var markdownit__default = /*#__PURE__*/_interopDefault(markdownit);
|
|
74
|
-
var zh_CN__default = /*#__PURE__*/_interopDefault(zh_CN);
|
|
75
72
|
var AES__default = /*#__PURE__*/_interopDefault(AES);
|
|
76
73
|
var encUtf8__default = /*#__PURE__*/_interopDefault(encUtf8);
|
|
74
|
+
var MarkdownIt__default = /*#__PURE__*/_interopDefault(MarkdownIt);
|
|
77
75
|
var Decimal__default = /*#__PURE__*/_interopDefault(Decimal);
|
|
78
76
|
var dayjs__default = /*#__PURE__*/_interopDefault(dayjs);
|
|
79
77
|
var relativeTime__default = /*#__PURE__*/_interopDefault(relativeTime);
|
|
80
78
|
var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
79
|
+
var parse__default = /*#__PURE__*/_interopDefault(parse);
|
|
80
|
+
var zh_CN__default = /*#__PURE__*/_interopDefault(zh_CN);
|
|
81
81
|
var Table__default = /*#__PURE__*/_interopDefault(Table);
|
|
82
82
|
var TableCell__default = /*#__PURE__*/_interopDefault(TableCell);
|
|
83
83
|
var TableHeader__default = /*#__PURE__*/_interopDefault(TableHeader);
|
|
@@ -101,319 +101,32 @@ var AudioPlayer_default = ({ fileUrl }) => {
|
|
|
101
101
|
"\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 audio \u6807\u7B7E\u3002"
|
|
102
102
|
] });
|
|
103
103
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
containerRef.current.innerHTML = "";
|
|
110
|
-
fetch(fileUrl).then((res) => res.arrayBuffer()).then(
|
|
111
|
-
(arrayBuffer) => docxPreview.renderAsync(arrayBuffer, containerRef.current, null, {
|
|
112
|
-
breakPages: true,
|
|
113
|
-
renderHeaders: true,
|
|
114
|
-
renderFooters: true,
|
|
115
|
-
ignoreWidth: false,
|
|
116
|
-
ignoreHeight: false
|
|
117
|
-
})
|
|
118
|
-
).catch((err) => {
|
|
119
|
-
console.error("docx-preview \u6E32\u67D3\u5931\u8D25:", err);
|
|
120
|
-
if (containerRef.current) containerRef.current.innerHTML = '<p class="text-center">\u6587\u6863\u52A0\u8F7D\u5931\u8D25</p>';
|
|
121
|
-
});
|
|
122
|
-
}, [fileUrl]);
|
|
123
|
-
const zoomIn = () => setZoomRatio((z) => Math.min(z + 0.1, 3));
|
|
124
|
-
const zoomOut = () => setZoomRatio((z) => Math.max(z - 0.1, 0.3));
|
|
125
|
-
const resetZoom = () => {
|
|
126
|
-
setZoomRatio(1);
|
|
127
|
-
};
|
|
128
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classNames__default.default(styles_module_default.nsPreviewDocx, "height-full"), children: [
|
|
129
|
-
/* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 6, align: "center", className: styles_module_default.docxToolbar, children: [
|
|
130
|
-
/* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: zoomOut, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.MinusCircleOutlined, {}), title: "\u7F29\u5C0F" }),
|
|
131
|
-
/* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: zoomIn, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.PlusCircleOutlined, {}), title: "\u653E\u5927" }),
|
|
132
|
-
/* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: resetZoom, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.RedoOutlined, {}), title: "\u8FD8\u539F" })
|
|
133
|
-
] }),
|
|
134
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames__default.default(styles_module_default.docxContent, "height-full", "scroll-fade-in"), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
135
|
-
"div",
|
|
136
|
-
{
|
|
137
|
-
ref: containerRef,
|
|
138
|
-
style: {
|
|
139
|
-
transform: `scale(${zoomRatio})`,
|
|
140
|
-
transformOrigin: "top center"
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
) })
|
|
144
|
-
] });
|
|
145
|
-
};
|
|
146
|
-
var FileIcon_default = ({ suffix, fontSize = 22 }) => {
|
|
147
|
-
const styles = { fontSize, color: "var(--ant-color-primary)" };
|
|
148
|
-
const Icon2 = React16.useMemo(() => {
|
|
149
|
-
switch (suffix?.toUpperCase()) {
|
|
150
|
-
case "TXT":
|
|
151
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileTextOutlined, {});
|
|
152
|
-
case "PDF":
|
|
153
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FilePdfOutlined, {});
|
|
154
|
-
case "DOC":
|
|
155
|
-
case "DOCX":
|
|
156
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileWordOutlined, {});
|
|
157
|
-
case "XLS":
|
|
158
|
-
case "XLSX":
|
|
159
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileExcelOutlined, {});
|
|
160
|
-
case "PPT":
|
|
161
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FilePptOutlined, {});
|
|
162
|
-
case "MP4":
|
|
163
|
-
case "MOV":
|
|
164
|
-
case "MKV":
|
|
165
|
-
case "AVI":
|
|
166
|
-
case "FLV":
|
|
167
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.VideoCameraOutlined, {});
|
|
168
|
-
case "MP3":
|
|
169
|
-
case "WAV":
|
|
170
|
-
case "M4A":
|
|
171
|
-
case "ACC":
|
|
172
|
-
case "WMA":
|
|
173
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.NotificationOutlined, {});
|
|
174
|
-
case "JPG":
|
|
175
|
-
case "JPEG":
|
|
176
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileJpgOutlined, {});
|
|
177
|
-
case "PNG":
|
|
178
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileImageOutlined, {});
|
|
179
|
-
case "GIF":
|
|
180
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileGifOutlined, {});
|
|
181
|
-
case "MD":
|
|
182
|
-
case "MARKDOWN":
|
|
183
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileMarkdownOutlined, {});
|
|
184
|
-
case "ZIP":
|
|
185
|
-
case "RAR":
|
|
186
|
-
case "7Z":
|
|
187
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileZipOutlined, {});
|
|
188
|
-
case "CATALOG":
|
|
189
|
-
return /* @__PURE__ */ jsxRuntime.jsx("i", { style: styles, className: "iconfont icon-wenjianjia" });
|
|
190
|
-
// 文件夹图标
|
|
191
|
-
default:
|
|
192
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileUnknownOutlined, {});
|
|
193
|
-
}
|
|
194
|
-
}, [suffix]);
|
|
195
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles, children: Icon2 });
|
|
196
|
-
};
|
|
197
|
-
var VideoPlayer_default = ({ fileUrl }) => {
|
|
198
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("video", { controls: true, className: styles_module_default.nsPreviewVideo, children: [
|
|
199
|
-
/* @__PURE__ */ jsxRuntime.jsx("source", { src: fileUrl, type: "video/mp4" }),
|
|
200
|
-
"\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 video \u6807\u7B7E\u3002"
|
|
201
|
-
] });
|
|
202
|
-
};
|
|
203
|
-
var baseComponentMap = {
|
|
204
|
-
// renderMarkdown: () => import('@/components/RenderMarkdown')
|
|
205
|
-
};
|
|
206
|
-
var LazyComponent_default = ({ type, customComponents, ...rest }) => {
|
|
207
|
-
const componentMap = React16.useMemo(() => {
|
|
208
|
-
return { ...baseComponentMap, ...customComponents };
|
|
209
|
-
}, [customComponents]);
|
|
210
|
-
const LazyComponent = React16.useMemo(() => {
|
|
211
|
-
const loader = componentMap[type];
|
|
212
|
-
return loader ? React16.lazy(loader) : null;
|
|
213
|
-
}, [type, componentMap]);
|
|
214
|
-
if (!LazyComponent) return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
215
|
-
"\u672A\u77E5\u7C7B\u578B\uFF1A",
|
|
216
|
-
type
|
|
217
|
-
] });
|
|
218
|
-
return /* @__PURE__ */ jsxRuntime.jsx(React16.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx("div", { children: "\u52A0\u8F7D\u4E2D..." }), children: /* @__PURE__ */ jsxRuntime.jsx(LazyComponent, { ...rest }) });
|
|
219
|
-
};
|
|
220
|
-
var md = markdownit__default.default({ html: true, breaks: true });
|
|
221
|
-
md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
|
|
222
|
-
const token = tokens[idx];
|
|
223
|
-
token.attrPush(["target", "_blank"]);
|
|
224
|
-
return self.renderToken(tokens, idx, options);
|
|
225
|
-
};
|
|
226
|
-
function parseData(raw) {
|
|
227
|
-
let obj = {};
|
|
228
|
-
try {
|
|
229
|
-
obj = JSON.parse(raw);
|
|
230
|
-
} catch {
|
|
231
|
-
try {
|
|
232
|
-
obj = JSON.parse(jsonrepair.jsonrepair(raw));
|
|
233
|
-
} catch {
|
|
234
|
-
obj = { _raw: raw };
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
return obj;
|
|
104
|
+
|
|
105
|
+
// src/utils/is.ts
|
|
106
|
+
var toString = Object.prototype.toString;
|
|
107
|
+
function is(val, type) {
|
|
108
|
+
return toString.call(val) === `[object ${type}]`;
|
|
238
109
|
}
|
|
239
|
-
function
|
|
240
|
-
|
|
241
|
-
const regex = new RegExp(`(${escaped.join("|")})`, "gi");
|
|
242
|
-
return html.replace(regex, '<span class="cube-hl">$1</span>');
|
|
110
|
+
function isUnDef(val) {
|
|
111
|
+
return is(val, "Undefined");
|
|
243
112
|
}
|
|
244
|
-
function
|
|
245
|
-
return
|
|
113
|
+
function isDef(val) {
|
|
114
|
+
return !isUnDef(val);
|
|
246
115
|
}
|
|
247
|
-
function
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const start = src.indexOf(":::alert", pos);
|
|
254
|
-
if (start === -1) {
|
|
255
|
-
out += src.slice(pos);
|
|
256
|
-
break;
|
|
257
|
-
}
|
|
258
|
-
out += src.slice(pos, start);
|
|
259
|
-
const afterStart = src.slice(start);
|
|
260
|
-
const relAfter = afterStart.slice(":::alert".length);
|
|
261
|
-
const matchLineEnd = relAfter.search(/\s*:::\s*/);
|
|
262
|
-
let endIdx = -1;
|
|
263
|
-
let isNoEnd = 1;
|
|
264
|
-
if (matchLineEnd !== -1) {
|
|
265
|
-
endIdx = start + ":::alert".length + matchLineEnd;
|
|
266
|
-
isNoEnd = 0;
|
|
267
|
-
} else {
|
|
268
|
-
endIdx = src.length;
|
|
269
|
-
isNoEnd = 1;
|
|
270
|
-
}
|
|
271
|
-
const inner = src.slice(start + ":::alert".length, endIdx).trim();
|
|
272
|
-
const typeMatch = inner.match(/type\s*=\s*(?:(['"])(.*?)\1|(\S+))/);
|
|
273
|
-
const type = typeMatch ? typeMatch[2] ?? typeMatch[3] : void 0;
|
|
274
|
-
const dataIdx = inner.search(/\bdata\s*=/);
|
|
275
|
-
let rawData = "";
|
|
276
|
-
if (dataIdx !== -1) {
|
|
277
|
-
rawData = inner.slice(dataIdx + inner.slice(dataIdx).match(/\bdata\s*=/)[0].length).trim();
|
|
278
|
-
}
|
|
279
|
-
const ph = makePlaceholder(id++);
|
|
280
|
-
placeholders.set(ph, rawData);
|
|
281
|
-
const typeText = type ? `type=${JSON.stringify(type)}` : "";
|
|
282
|
-
out += `:::alert ${typeText} data="${ph}" loading="${isNoEnd}" :::`;
|
|
283
|
-
const realClose = src.indexOf(":::", endIdx);
|
|
284
|
-
pos = realClose === -1 ? endIdx : realClose + 3;
|
|
116
|
+
function isObject(val) {
|
|
117
|
+
return is(val, "Object");
|
|
118
|
+
}
|
|
119
|
+
function isEmptyObj(val) {
|
|
120
|
+
if (isObject(val)) {
|
|
121
|
+
return Object.keys(val).length === 0;
|
|
285
122
|
}
|
|
286
|
-
return
|
|
123
|
+
return false;
|
|
287
124
|
}
|
|
288
|
-
function
|
|
289
|
-
|
|
290
|
-
const pos = state.pos;
|
|
291
|
-
const src = state.src;
|
|
292
|
-
if (src.slice(pos, pos + 3) !== ":::") return false;
|
|
293
|
-
const m = src.slice(pos).match(/^:::alert\b([^\n\r]*?):::/);
|
|
294
|
-
if (!m) return false;
|
|
295
|
-
if (silent) return false;
|
|
296
|
-
const raw = m[1].trim();
|
|
297
|
-
const html = `<lazy-component ${raw}></lazy-component>`;
|
|
298
|
-
const token = state.push("html_inline", "", 0);
|
|
299
|
-
token.content = html;
|
|
300
|
-
state.pos += m[0].length;
|
|
301
|
-
return true;
|
|
302
|
-
});
|
|
125
|
+
function isDate(val) {
|
|
126
|
+
return is(val, "Date");
|
|
303
127
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
} catch {
|
|
307
|
-
}
|
|
308
|
-
var filterMarkdown = (content = "") => {
|
|
309
|
-
if (!content) return content;
|
|
310
|
-
return content.replace(/<!--[\s\S]*?(?:-->|$)/g, "");
|
|
311
|
-
};
|
|
312
|
-
var RenderMarkdown_default = ({ content = "", searchValue, customComponents, ...rest }) => {
|
|
313
|
-
const reactContent = React16.useMemo(() => {
|
|
314
|
-
if (!content) return null;
|
|
315
|
-
const { text: preprocessed, placeholders } = alertMarkClean(filterMarkdown(content));
|
|
316
|
-
let rawHtml = md.render(preprocessed);
|
|
317
|
-
rawHtml = searchValue ? highlightKeywords(rawHtml, [searchValue]) : rawHtml;
|
|
318
|
-
let lazyIndex = -1;
|
|
319
|
-
return parse__default.default(rawHtml, {
|
|
320
|
-
replace: (domNode) => {
|
|
321
|
-
if (domNode.name === "lazy-component") {
|
|
322
|
-
lazyIndex++;
|
|
323
|
-
const el = domNode;
|
|
324
|
-
const type = el.attribs.type;
|
|
325
|
-
const loading = !!Number(el.attribs.loading);
|
|
326
|
-
const dataAttr = el.attribs.data || "";
|
|
327
|
-
let data = {};
|
|
328
|
-
if (/^__ALERT_DATA_\d+__$/.test(dataAttr)) {
|
|
329
|
-
const raw = placeholders.get(dataAttr) ?? "";
|
|
330
|
-
data = parseData(raw);
|
|
331
|
-
}
|
|
332
|
-
return /* @__PURE__ */ jsxRuntime.jsx(LazyComponent_default, { customComponents, type, data, loading, ...rest }, `${type}${lazyIndex}`);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
}, [content, searchValue]);
|
|
337
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ns-markdown", children: reactContent });
|
|
338
|
-
};
|
|
339
|
-
var MarkdownPreview_default = ({ fileUrl, searchValue }) => {
|
|
340
|
-
const [content, setContent] = React16.useState("");
|
|
341
|
-
const [error, setError] = React16.useState("");
|
|
342
|
-
const fetchMarkdown = async () => {
|
|
343
|
-
const res = await fetch(fileUrl);
|
|
344
|
-
if (res.status !== 200) {
|
|
345
|
-
throw new Error(`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${res.status}`);
|
|
346
|
-
}
|
|
347
|
-
const markdownText = await res.text();
|
|
348
|
-
if (!markdownText) {
|
|
349
|
-
throw new Error("\u8FD4\u56DE\u5185\u5BB9\u4E3A\u7A7A");
|
|
350
|
-
}
|
|
351
|
-
setContent(markdownText);
|
|
352
|
-
};
|
|
353
|
-
const init = async () => {
|
|
354
|
-
setContent("");
|
|
355
|
-
setError("");
|
|
356
|
-
if (fileUrl) {
|
|
357
|
-
try {
|
|
358
|
-
await fetchMarkdown();
|
|
359
|
-
} catch (error2) {
|
|
360
|
-
setError("\u52A0\u8F7D\u6216\u89E3\u6790 Markdown \u5931\u8D25");
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
React16.useEffect(() => {
|
|
365
|
-
init();
|
|
366
|
-
}, [fileUrl]);
|
|
367
|
-
return error ? /* @__PURE__ */ jsxRuntime.jsx(antd.Result, { status: "error", title: error }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "height-full", children: /* @__PURE__ */ jsxRuntime.jsx(RenderMarkdown_default, { content, searchValue }) });
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
// src/hooks/iframe/iframeRelay.ts
|
|
371
|
-
function emit(type, data, to = "top") {
|
|
372
|
-
const payload = { type, data, to };
|
|
373
|
-
try {
|
|
374
|
-
window.parent.postMessage(payload, "*");
|
|
375
|
-
} catch (err) {
|
|
376
|
-
console.warn("emit parent failed", err);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
function emitToChild(iframeWindow, type, data, origin = "*") {
|
|
380
|
-
if (!iframeWindow) {
|
|
381
|
-
console.warn("emitToChild failed: iframeWindow is null");
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
const payload = { type, data, to: "child" };
|
|
385
|
-
try {
|
|
386
|
-
iframeWindow.postMessage(payload, origin);
|
|
387
|
-
} catch (err) {
|
|
388
|
-
console.warn("emit to child failed", err);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
// src/utils/is.ts
|
|
393
|
-
var toString = Object.prototype.toString;
|
|
394
|
-
function is(val, type) {
|
|
395
|
-
return toString.call(val) === `[object ${type}]`;
|
|
396
|
-
}
|
|
397
|
-
function isUnDef(val) {
|
|
398
|
-
return is(val, "Undefined");
|
|
399
|
-
}
|
|
400
|
-
function isDef(val) {
|
|
401
|
-
return !isUnDef(val);
|
|
402
|
-
}
|
|
403
|
-
function isObject(val) {
|
|
404
|
-
return is(val, "Object");
|
|
405
|
-
}
|
|
406
|
-
function isEmptyObj(val) {
|
|
407
|
-
if (isObject(val)) {
|
|
408
|
-
return Object.keys(val).length === 0;
|
|
409
|
-
}
|
|
410
|
-
return false;
|
|
411
|
-
}
|
|
412
|
-
function isDate(val) {
|
|
413
|
-
return is(val, "Date");
|
|
414
|
-
}
|
|
415
|
-
function isNull(val) {
|
|
416
|
-
return is(val, "Null");
|
|
128
|
+
function isNull(val) {
|
|
129
|
+
return is(val, "Null");
|
|
417
130
|
}
|
|
418
131
|
function isNullOrUnDef(val) {
|
|
419
132
|
return isUnDef(val) || isNull(val);
|
|
@@ -535,143 +248,6 @@ var isJson = (text = "") => {
|
|
|
535
248
|
return false;
|
|
536
249
|
}
|
|
537
250
|
};
|
|
538
|
-
|
|
539
|
-
// src/hooks/iframe/useIframeRelayBridge.ts
|
|
540
|
-
var useIframeRelayBridge_default = (allowedOrigins = ["*"]) => {
|
|
541
|
-
const handlers = React16.useRef({});
|
|
542
|
-
React16.useEffect(() => {
|
|
543
|
-
const onMessage = (evt) => {
|
|
544
|
-
const { data, source, origin } = evt;
|
|
545
|
-
if (!data || !isObject(data) || !data.type) return;
|
|
546
|
-
if (allowedOrigins[0] !== "*" && !allowedOrigins.includes(origin)) return;
|
|
547
|
-
const { type, data: params, to = "parent" } = data;
|
|
548
|
-
const isTop = window.parent === window;
|
|
549
|
-
if (to === "top" && !isTop) {
|
|
550
|
-
window.parent.postMessage(data, allowedOrigins[0] === "*" ? "*" : origin);
|
|
551
|
-
return;
|
|
552
|
-
}
|
|
553
|
-
const fns = handlers.current[type] || [];
|
|
554
|
-
fns.forEach((fn) => fn(params, source, origin));
|
|
555
|
-
};
|
|
556
|
-
window.addEventListener("message", onMessage);
|
|
557
|
-
return () => window.removeEventListener("message", onMessage);
|
|
558
|
-
}, [allowedOrigins]);
|
|
559
|
-
function on(type, handler) {
|
|
560
|
-
handlers.current[type] = handlers.current[type] || [];
|
|
561
|
-
handlers.current[type].push(handler);
|
|
562
|
-
}
|
|
563
|
-
function off(type, handler) {
|
|
564
|
-
handlers.current[type] = (handlers.current[type] || []).filter((fn) => fn !== handler);
|
|
565
|
-
}
|
|
566
|
-
return { on, off };
|
|
567
|
-
};
|
|
568
|
-
var useAutoRefresh_default = (listenValue, shouldRefresh, callback, delay = 1e4) => {
|
|
569
|
-
const timerRef = React16.useRef(null);
|
|
570
|
-
const shouldRefreshRef = React16.useRef(shouldRefresh);
|
|
571
|
-
const callbackRef = React16.useRef(callback);
|
|
572
|
-
const [num, setNum] = React16.useState(0);
|
|
573
|
-
React16.useEffect(() => {
|
|
574
|
-
shouldRefreshRef.current = shouldRefresh;
|
|
575
|
-
callbackRef.current = callback;
|
|
576
|
-
}, [shouldRefresh, callback]);
|
|
577
|
-
React16.useEffect(() => {
|
|
578
|
-
if (timerRef.current) {
|
|
579
|
-
clearTimeout(timerRef.current);
|
|
580
|
-
timerRef.current = null;
|
|
581
|
-
}
|
|
582
|
-
if (shouldRefreshRef.current(listenValue)) {
|
|
583
|
-
timerRef.current = setTimeout(async () => {
|
|
584
|
-
await callbackRef.current();
|
|
585
|
-
setNum(num + 1);
|
|
586
|
-
}, delay);
|
|
587
|
-
}
|
|
588
|
-
return () => {
|
|
589
|
-
if (timerRef.current) {
|
|
590
|
-
clearTimeout(timerRef.current);
|
|
591
|
-
}
|
|
592
|
-
};
|
|
593
|
-
}, [listenValue, delay, num]);
|
|
594
|
-
};
|
|
595
|
-
var useCountDown_default = (callback) => {
|
|
596
|
-
const [count, setCount] = React16.useState(0);
|
|
597
|
-
const [startCount, setStartCount] = React16.useState(0);
|
|
598
|
-
const timer = React16.useRef(null);
|
|
599
|
-
const pause = () => {
|
|
600
|
-
clearInterval(timer.current);
|
|
601
|
-
timer.current = null;
|
|
602
|
-
};
|
|
603
|
-
const start = (initialValue = 60) => {
|
|
604
|
-
pause();
|
|
605
|
-
setCount(initialValue);
|
|
606
|
-
setStartCount((startCount2) => startCount2 + 1);
|
|
607
|
-
timer.current = setInterval(() => {
|
|
608
|
-
setCount((count2) => count2 - 1);
|
|
609
|
-
}, 1e3);
|
|
610
|
-
};
|
|
611
|
-
React16.useEffect(() => {
|
|
612
|
-
return () => {
|
|
613
|
-
pause();
|
|
614
|
-
};
|
|
615
|
-
}, []);
|
|
616
|
-
React16.useEffect(() => {
|
|
617
|
-
if (count === 0 && startCount !== 0) {
|
|
618
|
-
pause();
|
|
619
|
-
callback?.();
|
|
620
|
-
}
|
|
621
|
-
}, [count]);
|
|
622
|
-
return { count, start, pause, startCount };
|
|
623
|
-
};
|
|
624
|
-
var useCreateValtioContext_default = () => {
|
|
625
|
-
const Context = React16.createContext(null);
|
|
626
|
-
const ValtioProvider = ({ store, children }) => /* @__PURE__ */ jsxRuntime.jsx(Context.Provider, { value: store, children });
|
|
627
|
-
const useValtioStore = () => {
|
|
628
|
-
const store = React16.useContext(Context);
|
|
629
|
-
if (!store) throw new Error("useStore must be used within Provider");
|
|
630
|
-
return store;
|
|
631
|
-
};
|
|
632
|
-
return {
|
|
633
|
-
ValtioProvider,
|
|
634
|
-
useValtioStore,
|
|
635
|
-
// 导出 Context 以便外部使用
|
|
636
|
-
Context
|
|
637
|
-
};
|
|
638
|
-
};
|
|
639
|
-
var useDebounce_default = (func, wait = 400) => {
|
|
640
|
-
const { current } = React16.useRef({ func, timeOut: null });
|
|
641
|
-
React16.useEffect(() => {
|
|
642
|
-
current.func = func;
|
|
643
|
-
}, [func]);
|
|
644
|
-
let args;
|
|
645
|
-
function debounce(..._args) {
|
|
646
|
-
args = _args;
|
|
647
|
-
if (current.timeOut) {
|
|
648
|
-
clearTimeout(current.timeOut);
|
|
649
|
-
current.timeOut = null;
|
|
650
|
-
}
|
|
651
|
-
return new Promise((resolve, reject) => {
|
|
652
|
-
current.timeOut = setTimeout(async () => {
|
|
653
|
-
try {
|
|
654
|
-
const result = await current.func.apply(null, args);
|
|
655
|
-
resolve(result);
|
|
656
|
-
} catch (e) {
|
|
657
|
-
reject(e);
|
|
658
|
-
}
|
|
659
|
-
}, wait);
|
|
660
|
-
});
|
|
661
|
-
}
|
|
662
|
-
function cancel() {
|
|
663
|
-
if (!current.timeOut) return;
|
|
664
|
-
clearTimeout(current.timeOut);
|
|
665
|
-
current.timeOut = null;
|
|
666
|
-
}
|
|
667
|
-
function flush() {
|
|
668
|
-
cancel();
|
|
669
|
-
return current.func.apply(null, args);
|
|
670
|
-
}
|
|
671
|
-
debounce.flush = flush;
|
|
672
|
-
debounce.cancel = cancel;
|
|
673
|
-
return React16.useCallback(debounce, []);
|
|
674
|
-
};
|
|
675
251
|
var OperatorToMethodName = {
|
|
676
252
|
"+": "plus",
|
|
677
253
|
"-": "minus",
|
|
@@ -1232,7 +808,7 @@ function formatSize(value, options = {}) {
|
|
|
1232
808
|
return `${toFixed(size, precision2, !trimZero)}${UNIT_LIST[index]}`;
|
|
1233
809
|
}
|
|
1234
810
|
var markdownToText = (() => {
|
|
1235
|
-
const md2 = new
|
|
811
|
+
const md2 = new MarkdownIt__default.default({
|
|
1236
812
|
html: true,
|
|
1237
813
|
linkify: true,
|
|
1238
814
|
typographer: false
|
|
@@ -1244,174 +820,17 @@ var markdownToText = (() => {
|
|
|
1244
820
|
return text;
|
|
1245
821
|
};
|
|
1246
822
|
})();
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
var
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
return effect();
|
|
1256
|
-
}
|
|
1257
|
-
}, [depsChanged]);
|
|
823
|
+
dayjs__default.default.extend(relativeTime__default.default);
|
|
824
|
+
var DEFAULT_DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
|
|
825
|
+
var DEFAULT_DATE_FORMAT = "YYYY-MM-DD";
|
|
826
|
+
var DEFAULT_YEAR_MONTH_FORMAT = "YYYY\u5E74MM\u6708";
|
|
827
|
+
var DEFAULT_YEAR_MONTH_DAY_FORMAT = "YYYY\u5E74MM\u6708DD\u65E5";
|
|
828
|
+
var DEFAULT_UNIT = "date";
|
|
829
|
+
var getStartOfTimestamp = (date, unit = DEFAULT_UNIT) => {
|
|
830
|
+
return dayjs__default.default(date).startOf(unit).valueOf();
|
|
1258
831
|
};
|
|
1259
|
-
var
|
|
1260
|
-
|
|
1261
|
-
const stateRef = React16.useRef(init);
|
|
1262
|
-
const setProxy = (newVal) => {
|
|
1263
|
-
stateRef.current = newVal;
|
|
1264
|
-
setState(newVal);
|
|
1265
|
-
};
|
|
1266
|
-
const getState = () => stateRef.current;
|
|
1267
|
-
return [state, setProxy, getState];
|
|
1268
|
-
};
|
|
1269
|
-
var useSpeech_default = ({ onResult, lang = "zh-CN" }) => {
|
|
1270
|
-
const [permission, setPermission] = React16.useState("prompt");
|
|
1271
|
-
const [isRecording, setIsRecording] = React16.useState(false);
|
|
1272
|
-
const recognitionRef = React16.useRef(null);
|
|
1273
|
-
React16.useEffect(() => {
|
|
1274
|
-
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
1275
|
-
if (!SpeechRecognition) {
|
|
1276
|
-
setPermission("unsupported");
|
|
1277
|
-
return;
|
|
1278
|
-
}
|
|
1279
|
-
const recognition = new SpeechRecognition();
|
|
1280
|
-
recognition.continuous = true;
|
|
1281
|
-
recognition.interimResults = false;
|
|
1282
|
-
recognition.lang = lang;
|
|
1283
|
-
recognition.onresult = (event) => {
|
|
1284
|
-
let transcript = "";
|
|
1285
|
-
for (let i = event.resultIndex; i < event.results.length; i++) {
|
|
1286
|
-
transcript += event.results[i][0].transcript;
|
|
1287
|
-
}
|
|
1288
|
-
onResult?.(transcript.trim());
|
|
1289
|
-
};
|
|
1290
|
-
recognition.onend = () => {
|
|
1291
|
-
setIsRecording(false);
|
|
1292
|
-
};
|
|
1293
|
-
recognition.onerror = (error) => {
|
|
1294
|
-
setIsRecording(false);
|
|
1295
|
-
console.error("Speech recognition error:", error);
|
|
1296
|
-
};
|
|
1297
|
-
recognitionRef.current = recognition;
|
|
1298
|
-
return () => {
|
|
1299
|
-
recognition.stop?.();
|
|
1300
|
-
recognition.onresult = null;
|
|
1301
|
-
recognition.onend = null;
|
|
1302
|
-
recognition.onerror = null;
|
|
1303
|
-
};
|
|
1304
|
-
}, [lang, onResult]);
|
|
1305
|
-
React16.useEffect(() => {
|
|
1306
|
-
if (!navigator.permissions) return;
|
|
1307
|
-
navigator.permissions.query({ name: "microphone" }).then((status) => {
|
|
1308
|
-
setPermission(status.state);
|
|
1309
|
-
status.onchange = () => setPermission(status.state);
|
|
1310
|
-
});
|
|
1311
|
-
}, []);
|
|
1312
|
-
const requestPermission = React16.useCallback(async () => {
|
|
1313
|
-
try {
|
|
1314
|
-
await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
1315
|
-
setPermission("granted");
|
|
1316
|
-
} catch {
|
|
1317
|
-
setPermission("denied");
|
|
1318
|
-
}
|
|
1319
|
-
}, []);
|
|
1320
|
-
const start = React16.useCallback(() => {
|
|
1321
|
-
if (permission === "prompt") {
|
|
1322
|
-
requestPermission();
|
|
1323
|
-
return;
|
|
1324
|
-
}
|
|
1325
|
-
if (permission !== "granted") return;
|
|
1326
|
-
if (!isRecording) {
|
|
1327
|
-
recognitionRef.current?.start();
|
|
1328
|
-
setIsRecording(true);
|
|
1329
|
-
}
|
|
1330
|
-
}, [permission, isRecording, requestPermission]);
|
|
1331
|
-
const stop = React16.useCallback(() => {
|
|
1332
|
-
try {
|
|
1333
|
-
recognitionRef.current?.stop();
|
|
1334
|
-
} finally {
|
|
1335
|
-
setIsRecording(false);
|
|
1336
|
-
}
|
|
1337
|
-
}, []);
|
|
1338
|
-
return {
|
|
1339
|
-
/**
|
|
1340
|
-
* 权限状态
|
|
1341
|
-
*/
|
|
1342
|
-
permission,
|
|
1343
|
-
/**
|
|
1344
|
-
* 录音状态
|
|
1345
|
-
*/
|
|
1346
|
-
isRecording,
|
|
1347
|
-
/** 开始语音识别 */
|
|
1348
|
-
start,
|
|
1349
|
-
/** 停止语音识别 */
|
|
1350
|
-
stop
|
|
1351
|
-
};
|
|
1352
|
-
};
|
|
1353
|
-
var useSyncInput_default = (storeValue, setStoreValue) => {
|
|
1354
|
-
const [inputValue, setInputValue] = React16.useState(storeValue);
|
|
1355
|
-
React16.useEffect(() => {
|
|
1356
|
-
if (storeValue !== inputValue) {
|
|
1357
|
-
setInputValue(storeValue);
|
|
1358
|
-
}
|
|
1359
|
-
}, [storeValue]);
|
|
1360
|
-
const handleValueChange = (value) => {
|
|
1361
|
-
setStoreValue(value);
|
|
1362
|
-
setInputValue(value);
|
|
1363
|
-
};
|
|
1364
|
-
return {
|
|
1365
|
-
inputValue,
|
|
1366
|
-
setInputValue: handleValueChange
|
|
1367
|
-
};
|
|
1368
|
-
};
|
|
1369
|
-
var useThrottle_default = (func, wait) => {
|
|
1370
|
-
const { current } = React16.useRef({ func, timeOut: null });
|
|
1371
|
-
React16.useEffect(() => {
|
|
1372
|
-
current.func = func;
|
|
1373
|
-
}, [func]);
|
|
1374
|
-
let args;
|
|
1375
|
-
function throttle(..._args) {
|
|
1376
|
-
args = _args;
|
|
1377
|
-
return new Promise((resolve, reject) => {
|
|
1378
|
-
if (!current.timeOut) {
|
|
1379
|
-
try {
|
|
1380
|
-
const result = current.func.apply(null, args);
|
|
1381
|
-
resolve(result);
|
|
1382
|
-
} catch (e) {
|
|
1383
|
-
reject(e);
|
|
1384
|
-
}
|
|
1385
|
-
current.timeOut = setTimeout(() => {
|
|
1386
|
-
current.timeOut = null;
|
|
1387
|
-
}, wait);
|
|
1388
|
-
}
|
|
1389
|
-
});
|
|
1390
|
-
}
|
|
1391
|
-
function cancel() {
|
|
1392
|
-
if (!current.timeOut) return;
|
|
1393
|
-
clearTimeout(current.timeOut);
|
|
1394
|
-
current.timeOut = null;
|
|
1395
|
-
}
|
|
1396
|
-
function flush() {
|
|
1397
|
-
cancel();
|
|
1398
|
-
return current.func.apply(null, args);
|
|
1399
|
-
}
|
|
1400
|
-
throttle.flush = flush;
|
|
1401
|
-
throttle.cancel = cancel;
|
|
1402
|
-
return React16.useCallback(throttle, []);
|
|
1403
|
-
};
|
|
1404
|
-
dayjs__default.default.extend(relativeTime__default.default);
|
|
1405
|
-
var DEFAULT_DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
|
|
1406
|
-
var DEFAULT_DATE_FORMAT = "YYYY-MM-DD";
|
|
1407
|
-
var DEFAULT_YEAR_MONTH_FORMAT = "YYYY\u5E74MM\u6708";
|
|
1408
|
-
var DEFAULT_YEAR_MONTH_DAY_FORMAT = "YYYY\u5E74MM\u6708DD\u65E5";
|
|
1409
|
-
var DEFAULT_UNIT = "date";
|
|
1410
|
-
var getStartOfTimestamp = (date, unit = DEFAULT_UNIT) => {
|
|
1411
|
-
return dayjs__default.default(date).startOf(unit).valueOf();
|
|
1412
|
-
};
|
|
1413
|
-
var getEndOfTimestamp = (date, unit = DEFAULT_UNIT) => {
|
|
1414
|
-
return dayjs__default.default(date).endOf(unit).valueOf();
|
|
832
|
+
var getEndOfTimestamp = (date, unit = DEFAULT_UNIT) => {
|
|
833
|
+
return dayjs__default.default(date).endOf(unit).valueOf();
|
|
1415
834
|
};
|
|
1416
835
|
var formatDate = (date, fmt = DEFAULT_DATE_TIME_FORMAT) => {
|
|
1417
836
|
if (date) {
|
|
@@ -1729,7 +1148,6 @@ function createSecureManager({ key, storage = localStorage, aesKey }) {
|
|
|
1729
1148
|
try {
|
|
1730
1149
|
return JSON.parse(cipher);
|
|
1731
1150
|
} catch (e) {
|
|
1732
|
-
console.log("Failed to parse stored data:", e);
|
|
1733
1151
|
return cipher;
|
|
1734
1152
|
}
|
|
1735
1153
|
};
|
|
@@ -1760,8 +1178,590 @@ function createTokenManager({ key, storage = localStorage }) {
|
|
|
1760
1178
|
clear: tokenManager.clear
|
|
1761
1179
|
};
|
|
1762
1180
|
}
|
|
1763
|
-
|
|
1764
|
-
|
|
1181
|
+
var DocxPreview_default = ({ fileUrl, scale = 1 }) => {
|
|
1182
|
+
const containerRef = React16.useRef(null);
|
|
1183
|
+
const [zoomRatio, setZoomRatio] = React16.useState(scale);
|
|
1184
|
+
React16.useEffect(() => {
|
|
1185
|
+
if (!fileUrl || !containerRef.current) return;
|
|
1186
|
+
containerRef.current.innerHTML = "";
|
|
1187
|
+
fetch(fileUrl).then((res) => res.arrayBuffer()).then(async (arrayBuffer) => {
|
|
1188
|
+
await docxPreview.renderAsync(arrayBuffer, containerRef.current, null, {
|
|
1189
|
+
breakPages: true,
|
|
1190
|
+
renderHeaders: true,
|
|
1191
|
+
renderFooters: true,
|
|
1192
|
+
ignoreWidth: false,
|
|
1193
|
+
ignoreHeight: false
|
|
1194
|
+
});
|
|
1195
|
+
containerRef.current.querySelectorAll("a[href]").forEach((linkEle) => {
|
|
1196
|
+
const href = linkEle.getAttribute("href");
|
|
1197
|
+
if (href && isExternal(href)) {
|
|
1198
|
+
linkEle.setAttribute("target", "_blank");
|
|
1199
|
+
linkEle.setAttribute("rel", "noopener noreferrer");
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
}).catch((err) => {
|
|
1203
|
+
console.error("docx-preview \u6E32\u67D3\u5931\u8D25:", err);
|
|
1204
|
+
if (containerRef.current) containerRef.current.innerHTML = '<p class="text-center">\u6587\u6863\u52A0\u8F7D\u5931\u8D25</p>';
|
|
1205
|
+
});
|
|
1206
|
+
}, [fileUrl]);
|
|
1207
|
+
const zoomIn = () => setZoomRatio((z) => Math.min(z + 0.1, 3));
|
|
1208
|
+
const zoomOut = () => setZoomRatio((z) => Math.max(z - 0.1, 0.3));
|
|
1209
|
+
const resetZoom = () => {
|
|
1210
|
+
setZoomRatio(1);
|
|
1211
|
+
};
|
|
1212
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classNames__default.default(styles_module_default.nsPreviewDocx, "height-full"), children: [
|
|
1213
|
+
/* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 6, align: "center", className: styles_module_default.docxToolbar, children: [
|
|
1214
|
+
/* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: zoomOut, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.MinusCircleOutlined, {}), title: "\u7F29\u5C0F" }),
|
|
1215
|
+
/* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: zoomIn, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.PlusCircleOutlined, {}), title: "\u653E\u5927" }),
|
|
1216
|
+
/* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: resetZoom, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.RedoOutlined, {}), title: "\u8FD8\u539F" })
|
|
1217
|
+
] }),
|
|
1218
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames__default.default(styles_module_default.docxContent, "height-full", "scroll-fade-in"), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1219
|
+
"div",
|
|
1220
|
+
{
|
|
1221
|
+
ref: containerRef,
|
|
1222
|
+
style: {
|
|
1223
|
+
transform: `scale(${zoomRatio})`,
|
|
1224
|
+
transformOrigin: "top center"
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
) })
|
|
1228
|
+
] });
|
|
1229
|
+
};
|
|
1230
|
+
var FileIcon_default = ({ suffix, fontSize = 22 }) => {
|
|
1231
|
+
const styles = { fontSize, color: "var(--ant-color-primary)" };
|
|
1232
|
+
const Icon2 = React16.useMemo(() => {
|
|
1233
|
+
switch (suffix?.toUpperCase()) {
|
|
1234
|
+
case "TXT":
|
|
1235
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileTextOutlined, {});
|
|
1236
|
+
case "PDF":
|
|
1237
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FilePdfOutlined, {});
|
|
1238
|
+
case "DOC":
|
|
1239
|
+
case "DOCX":
|
|
1240
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileWordOutlined, {});
|
|
1241
|
+
case "XLS":
|
|
1242
|
+
case "XLSX":
|
|
1243
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileExcelOutlined, {});
|
|
1244
|
+
case "PPT":
|
|
1245
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FilePptOutlined, {});
|
|
1246
|
+
case "MP4":
|
|
1247
|
+
case "MOV":
|
|
1248
|
+
case "MKV":
|
|
1249
|
+
case "AVI":
|
|
1250
|
+
case "FLV":
|
|
1251
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.VideoCameraOutlined, {});
|
|
1252
|
+
case "MP3":
|
|
1253
|
+
case "WAV":
|
|
1254
|
+
case "M4A":
|
|
1255
|
+
case "ACC":
|
|
1256
|
+
case "WMA":
|
|
1257
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.NotificationOutlined, {});
|
|
1258
|
+
case "JPG":
|
|
1259
|
+
case "JPEG":
|
|
1260
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileJpgOutlined, {});
|
|
1261
|
+
case "PNG":
|
|
1262
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileImageOutlined, {});
|
|
1263
|
+
case "GIF":
|
|
1264
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileGifOutlined, {});
|
|
1265
|
+
case "MD":
|
|
1266
|
+
case "MARKDOWN":
|
|
1267
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileMarkdownOutlined, {});
|
|
1268
|
+
case "ZIP":
|
|
1269
|
+
case "RAR":
|
|
1270
|
+
case "7Z":
|
|
1271
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileZipOutlined, {});
|
|
1272
|
+
case "CATALOG":
|
|
1273
|
+
return /* @__PURE__ */ jsxRuntime.jsx("i", { style: styles, className: "iconfont icon-wenjianjia" });
|
|
1274
|
+
// 文件夹图标
|
|
1275
|
+
default:
|
|
1276
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileUnknownOutlined, {});
|
|
1277
|
+
}
|
|
1278
|
+
}, [suffix]);
|
|
1279
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles, children: Icon2 });
|
|
1280
|
+
};
|
|
1281
|
+
var VideoPlayer_default = ({ fileUrl }) => {
|
|
1282
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("video", { controls: true, className: styles_module_default.nsPreviewVideo, children: [
|
|
1283
|
+
/* @__PURE__ */ jsxRuntime.jsx("source", { src: fileUrl, type: "video/mp4" }),
|
|
1284
|
+
"\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 video \u6807\u7B7E\u3002"
|
|
1285
|
+
] });
|
|
1286
|
+
};
|
|
1287
|
+
var baseComponentMap = {
|
|
1288
|
+
// renderMarkdown: () => import('@/components/RenderMarkdown')
|
|
1289
|
+
};
|
|
1290
|
+
var LazyComponent_default = ({ type, customComponents, ...rest }) => {
|
|
1291
|
+
const componentMap = React16.useMemo(() => {
|
|
1292
|
+
return { ...baseComponentMap, ...customComponents };
|
|
1293
|
+
}, [customComponents]);
|
|
1294
|
+
const LazyComponent = React16.useMemo(() => {
|
|
1295
|
+
const loader = componentMap[type];
|
|
1296
|
+
return loader ? React16.lazy(loader) : null;
|
|
1297
|
+
}, [type, componentMap]);
|
|
1298
|
+
if (!LazyComponent) return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1299
|
+
"\u672A\u77E5\u7C7B\u578B\uFF1A",
|
|
1300
|
+
type
|
|
1301
|
+
] });
|
|
1302
|
+
return /* @__PURE__ */ jsxRuntime.jsx(React16.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx("div", { children: "\u52A0\u8F7D\u4E2D..." }), children: /* @__PURE__ */ jsxRuntime.jsx(LazyComponent, { ...rest }) });
|
|
1303
|
+
};
|
|
1304
|
+
var md = MarkdownIt__default.default({ html: true, breaks: true });
|
|
1305
|
+
md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
|
|
1306
|
+
const token = tokens[idx];
|
|
1307
|
+
token.attrPush(["target", "_blank"]);
|
|
1308
|
+
return self.renderToken(tokens, idx, options);
|
|
1309
|
+
};
|
|
1310
|
+
function parseData(raw) {
|
|
1311
|
+
let obj = {};
|
|
1312
|
+
try {
|
|
1313
|
+
obj = JSON.parse(raw);
|
|
1314
|
+
} catch {
|
|
1315
|
+
try {
|
|
1316
|
+
obj = JSON.parse(jsonrepair.jsonrepair(raw));
|
|
1317
|
+
} catch {
|
|
1318
|
+
obj = { _raw: raw };
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
return obj;
|
|
1322
|
+
}
|
|
1323
|
+
function highlightKeywords(html, keywords) {
|
|
1324
|
+
const escaped = keywords.map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
1325
|
+
const regex = new RegExp(`(${escaped.join("|")})`, "gi");
|
|
1326
|
+
return html.replace(regex, '<span class="cube-hl">$1</span>');
|
|
1327
|
+
}
|
|
1328
|
+
function makePlaceholder(id) {
|
|
1329
|
+
return `__ALERT_DATA_${id}__`;
|
|
1330
|
+
}
|
|
1331
|
+
function alertMarkClean(src) {
|
|
1332
|
+
let pos = 0;
|
|
1333
|
+
let id = 0;
|
|
1334
|
+
let out = "";
|
|
1335
|
+
const placeholders = /* @__PURE__ */ new Map();
|
|
1336
|
+
while (pos < src.length) {
|
|
1337
|
+
const start = src.indexOf(":::alert", pos);
|
|
1338
|
+
if (start === -1) {
|
|
1339
|
+
out += src.slice(pos);
|
|
1340
|
+
break;
|
|
1341
|
+
}
|
|
1342
|
+
out += src.slice(pos, start);
|
|
1343
|
+
const afterStart = src.slice(start);
|
|
1344
|
+
const relAfter = afterStart.slice(":::alert".length);
|
|
1345
|
+
const matchLineEnd = relAfter.search(/\s*:::\s*/);
|
|
1346
|
+
let endIdx = -1;
|
|
1347
|
+
let isNoEnd = 1;
|
|
1348
|
+
if (matchLineEnd !== -1) {
|
|
1349
|
+
endIdx = start + ":::alert".length + matchLineEnd;
|
|
1350
|
+
isNoEnd = 0;
|
|
1351
|
+
} else {
|
|
1352
|
+
endIdx = src.length;
|
|
1353
|
+
isNoEnd = 1;
|
|
1354
|
+
}
|
|
1355
|
+
const inner = src.slice(start + ":::alert".length, endIdx).trim();
|
|
1356
|
+
const typeMatch = inner.match(/type\s*=\s*(?:(['"])(.*?)\1|(\S+))/);
|
|
1357
|
+
const type = typeMatch ? typeMatch[2] ?? typeMatch[3] : void 0;
|
|
1358
|
+
const dataIdx = inner.search(/\bdata\s*=/);
|
|
1359
|
+
let rawData = "";
|
|
1360
|
+
if (dataIdx !== -1) {
|
|
1361
|
+
rawData = inner.slice(dataIdx + inner.slice(dataIdx).match(/\bdata\s*=/)[0].length).trim();
|
|
1362
|
+
}
|
|
1363
|
+
const ph = makePlaceholder(id++);
|
|
1364
|
+
placeholders.set(ph, rawData);
|
|
1365
|
+
const typeText = type ? `type=${JSON.stringify(type)}` : "";
|
|
1366
|
+
out += `:::alert ${typeText} data="${ph}" loading="${isNoEnd}" :::`;
|
|
1367
|
+
const realClose = src.indexOf(":::", endIdx);
|
|
1368
|
+
pos = realClose === -1 ? endIdx : realClose + 3;
|
|
1369
|
+
}
|
|
1370
|
+
return { text: out, placeholders };
|
|
1371
|
+
}
|
|
1372
|
+
function alertInlinePlugin(md2) {
|
|
1373
|
+
md2.inline.ruler.before("emphasis", "alert_inline", function(state, silent) {
|
|
1374
|
+
const pos = state.pos;
|
|
1375
|
+
const src = state.src;
|
|
1376
|
+
if (src.slice(pos, pos + 3) !== ":::") return false;
|
|
1377
|
+
const m = src.slice(pos).match(/^:::alert\b([^\n\r]*?):::/);
|
|
1378
|
+
if (!m) return false;
|
|
1379
|
+
if (silent) return false;
|
|
1380
|
+
const raw = m[1].trim();
|
|
1381
|
+
const html = `<lazy-component ${raw}></lazy-component>`;
|
|
1382
|
+
const token = state.push("html_inline", "", 0);
|
|
1383
|
+
token.content = html;
|
|
1384
|
+
state.pos += m[0].length;
|
|
1385
|
+
return true;
|
|
1386
|
+
});
|
|
1387
|
+
}
|
|
1388
|
+
try {
|
|
1389
|
+
md.use(alertInlinePlugin);
|
|
1390
|
+
} catch {
|
|
1391
|
+
}
|
|
1392
|
+
var filterMarkdown = (content = "") => {
|
|
1393
|
+
if (!content) return content;
|
|
1394
|
+
return content.replace(/<!--[\s\S]*?(?:-->|$)/g, "");
|
|
1395
|
+
};
|
|
1396
|
+
var RenderMarkdown_default = ({ content = "", searchValue, customComponents, ...rest }) => {
|
|
1397
|
+
const reactContent = React16.useMemo(() => {
|
|
1398
|
+
if (!content) return null;
|
|
1399
|
+
const { text: preprocessed, placeholders } = alertMarkClean(filterMarkdown(content));
|
|
1400
|
+
let rawHtml = md.render(preprocessed);
|
|
1401
|
+
rawHtml = searchValue ? highlightKeywords(rawHtml, [searchValue]) : rawHtml;
|
|
1402
|
+
let lazyIndex = -1;
|
|
1403
|
+
return parse__default.default(rawHtml, {
|
|
1404
|
+
replace: (domNode) => {
|
|
1405
|
+
if (domNode.name === "lazy-component") {
|
|
1406
|
+
lazyIndex++;
|
|
1407
|
+
const el = domNode;
|
|
1408
|
+
const type = el.attribs.type;
|
|
1409
|
+
const loading = !!Number(el.attribs.loading);
|
|
1410
|
+
const dataAttr = el.attribs.data || "";
|
|
1411
|
+
let data = {};
|
|
1412
|
+
if (/^__ALERT_DATA_\d+__$/.test(dataAttr)) {
|
|
1413
|
+
const raw = placeholders.get(dataAttr) ?? "";
|
|
1414
|
+
data = parseData(raw);
|
|
1415
|
+
}
|
|
1416
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LazyComponent_default, { customComponents, type, data, loading, ...rest }, `${type}${lazyIndex}`);
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
});
|
|
1420
|
+
}, [content, searchValue]);
|
|
1421
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ns-markdown", children: reactContent });
|
|
1422
|
+
};
|
|
1423
|
+
var MarkdownPreview_default = ({ fileUrl, searchValue }) => {
|
|
1424
|
+
const [content, setContent] = React16.useState("");
|
|
1425
|
+
const [error, setError] = React16.useState("");
|
|
1426
|
+
const fetchMarkdown = async () => {
|
|
1427
|
+
const res = await fetch(fileUrl);
|
|
1428
|
+
if (res.status !== 200) {
|
|
1429
|
+
throw new Error(`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${res.status}`);
|
|
1430
|
+
}
|
|
1431
|
+
const markdownText = await res.text();
|
|
1432
|
+
if (!markdownText) {
|
|
1433
|
+
throw new Error("\u8FD4\u56DE\u5185\u5BB9\u4E3A\u7A7A");
|
|
1434
|
+
}
|
|
1435
|
+
setContent(markdownText);
|
|
1436
|
+
};
|
|
1437
|
+
const init = async () => {
|
|
1438
|
+
setContent("");
|
|
1439
|
+
setError("");
|
|
1440
|
+
if (fileUrl) {
|
|
1441
|
+
try {
|
|
1442
|
+
await fetchMarkdown();
|
|
1443
|
+
} catch (error2) {
|
|
1444
|
+
setError("\u52A0\u8F7D\u6216\u89E3\u6790 Markdown \u5931\u8D25");
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
};
|
|
1448
|
+
React16.useEffect(() => {
|
|
1449
|
+
init();
|
|
1450
|
+
}, [fileUrl]);
|
|
1451
|
+
return error ? /* @__PURE__ */ jsxRuntime.jsx(antd.Result, { status: "error", title: error }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "height-full", children: /* @__PURE__ */ jsxRuntime.jsx(RenderMarkdown_default, { content, searchValue }) });
|
|
1452
|
+
};
|
|
1453
|
+
|
|
1454
|
+
// src/hooks/iframe/iframeRelay.ts
|
|
1455
|
+
function emit(type, data, to = "top") {
|
|
1456
|
+
const payload = { type, data, to };
|
|
1457
|
+
try {
|
|
1458
|
+
window.parent.postMessage(payload, "*");
|
|
1459
|
+
} catch (err) {
|
|
1460
|
+
console.warn("emit parent failed", err);
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
function emitToChild(iframeWindow, type, data, origin = "*") {
|
|
1464
|
+
if (!iframeWindow) {
|
|
1465
|
+
console.warn("emitToChild failed: iframeWindow is null");
|
|
1466
|
+
return;
|
|
1467
|
+
}
|
|
1468
|
+
const payload = { type, data, to: "child" };
|
|
1469
|
+
try {
|
|
1470
|
+
iframeWindow.postMessage(payload, origin);
|
|
1471
|
+
} catch (err) {
|
|
1472
|
+
console.warn("emit to child failed", err);
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
var useIframeRelayBridge_default = (allowedOrigins = ["*"]) => {
|
|
1476
|
+
const handlers = React16.useRef({});
|
|
1477
|
+
React16.useEffect(() => {
|
|
1478
|
+
const onMessage = (evt) => {
|
|
1479
|
+
const { data, source, origin } = evt;
|
|
1480
|
+
if (!data || !isObject(data) || !data.type) return;
|
|
1481
|
+
if (allowedOrigins[0] !== "*" && !allowedOrigins.includes(origin)) return;
|
|
1482
|
+
const { type, data: params, to = "parent" } = data;
|
|
1483
|
+
const isTop = window.parent === window;
|
|
1484
|
+
if (to === "top" && !isTop) {
|
|
1485
|
+
window.parent.postMessage(data, allowedOrigins[0] === "*" ? "*" : origin);
|
|
1486
|
+
return;
|
|
1487
|
+
}
|
|
1488
|
+
const fns = handlers.current[type] || [];
|
|
1489
|
+
fns.forEach((fn) => fn(params, source, origin));
|
|
1490
|
+
};
|
|
1491
|
+
window.addEventListener("message", onMessage);
|
|
1492
|
+
return () => window.removeEventListener("message", onMessage);
|
|
1493
|
+
}, [allowedOrigins]);
|
|
1494
|
+
function on(type, handler) {
|
|
1495
|
+
handlers.current[type] = handlers.current[type] || [];
|
|
1496
|
+
handlers.current[type].push(handler);
|
|
1497
|
+
}
|
|
1498
|
+
function off(type, handler) {
|
|
1499
|
+
handlers.current[type] = (handlers.current[type] || []).filter((fn) => fn !== handler);
|
|
1500
|
+
}
|
|
1501
|
+
return { on, off };
|
|
1502
|
+
};
|
|
1503
|
+
var useAutoRefresh_default = (listenValue, shouldRefresh, callback, delay = 1e4) => {
|
|
1504
|
+
const timerRef = React16.useRef(null);
|
|
1505
|
+
const shouldRefreshRef = React16.useRef(shouldRefresh);
|
|
1506
|
+
const callbackRef = React16.useRef(callback);
|
|
1507
|
+
const [num, setNum] = React16.useState(0);
|
|
1508
|
+
React16.useEffect(() => {
|
|
1509
|
+
shouldRefreshRef.current = shouldRefresh;
|
|
1510
|
+
callbackRef.current = callback;
|
|
1511
|
+
}, [shouldRefresh, callback]);
|
|
1512
|
+
React16.useEffect(() => {
|
|
1513
|
+
if (timerRef.current) {
|
|
1514
|
+
clearTimeout(timerRef.current);
|
|
1515
|
+
timerRef.current = null;
|
|
1516
|
+
}
|
|
1517
|
+
if (shouldRefreshRef.current(listenValue)) {
|
|
1518
|
+
timerRef.current = setTimeout(async () => {
|
|
1519
|
+
await callbackRef.current();
|
|
1520
|
+
setNum(num + 1);
|
|
1521
|
+
}, delay);
|
|
1522
|
+
}
|
|
1523
|
+
return () => {
|
|
1524
|
+
if (timerRef.current) {
|
|
1525
|
+
clearTimeout(timerRef.current);
|
|
1526
|
+
}
|
|
1527
|
+
};
|
|
1528
|
+
}, [listenValue, delay, num]);
|
|
1529
|
+
};
|
|
1530
|
+
var useCountDown_default = (callback) => {
|
|
1531
|
+
const [count, setCount] = React16.useState(0);
|
|
1532
|
+
const [startCount, setStartCount] = React16.useState(0);
|
|
1533
|
+
const timer = React16.useRef(null);
|
|
1534
|
+
const pause = () => {
|
|
1535
|
+
clearInterval(timer.current);
|
|
1536
|
+
timer.current = null;
|
|
1537
|
+
};
|
|
1538
|
+
const start = (initialValue = 60) => {
|
|
1539
|
+
pause();
|
|
1540
|
+
setCount(initialValue);
|
|
1541
|
+
setStartCount((startCount2) => startCount2 + 1);
|
|
1542
|
+
timer.current = setInterval(() => {
|
|
1543
|
+
setCount((count2) => count2 - 1);
|
|
1544
|
+
}, 1e3);
|
|
1545
|
+
};
|
|
1546
|
+
React16.useEffect(() => {
|
|
1547
|
+
return () => {
|
|
1548
|
+
pause();
|
|
1549
|
+
};
|
|
1550
|
+
}, []);
|
|
1551
|
+
React16.useEffect(() => {
|
|
1552
|
+
if (count === 0 && startCount !== 0) {
|
|
1553
|
+
pause();
|
|
1554
|
+
callback?.();
|
|
1555
|
+
}
|
|
1556
|
+
}, [count]);
|
|
1557
|
+
return { count, start, pause, startCount };
|
|
1558
|
+
};
|
|
1559
|
+
var useCreateValtioContext_default = () => {
|
|
1560
|
+
const Context = React16.createContext(null);
|
|
1561
|
+
const ValtioProvider = ({ store, children }) => /* @__PURE__ */ jsxRuntime.jsx(Context.Provider, { value: store, children });
|
|
1562
|
+
const useValtioStore = () => {
|
|
1563
|
+
const store = React16.useContext(Context);
|
|
1564
|
+
if (!store) throw new Error("useStore must be used within Provider");
|
|
1565
|
+
return store;
|
|
1566
|
+
};
|
|
1567
|
+
return {
|
|
1568
|
+
ValtioProvider,
|
|
1569
|
+
useValtioStore,
|
|
1570
|
+
// 导出 Context 以便外部使用
|
|
1571
|
+
Context
|
|
1572
|
+
};
|
|
1573
|
+
};
|
|
1574
|
+
var useDebounce_default = (func, wait = 400) => {
|
|
1575
|
+
const { current } = React16.useRef({ func, timeOut: null });
|
|
1576
|
+
React16.useEffect(() => {
|
|
1577
|
+
current.func = func;
|
|
1578
|
+
}, [func]);
|
|
1579
|
+
let args;
|
|
1580
|
+
function debounce(..._args) {
|
|
1581
|
+
args = _args;
|
|
1582
|
+
if (current.timeOut) {
|
|
1583
|
+
clearTimeout(current.timeOut);
|
|
1584
|
+
current.timeOut = null;
|
|
1585
|
+
}
|
|
1586
|
+
return new Promise((resolve, reject) => {
|
|
1587
|
+
current.timeOut = setTimeout(async () => {
|
|
1588
|
+
try {
|
|
1589
|
+
const result = await current.func.apply(null, args);
|
|
1590
|
+
resolve(result);
|
|
1591
|
+
} catch (e) {
|
|
1592
|
+
reject(e);
|
|
1593
|
+
}
|
|
1594
|
+
}, wait);
|
|
1595
|
+
});
|
|
1596
|
+
}
|
|
1597
|
+
function cancel() {
|
|
1598
|
+
if (!current.timeOut) return;
|
|
1599
|
+
clearTimeout(current.timeOut);
|
|
1600
|
+
current.timeOut = null;
|
|
1601
|
+
}
|
|
1602
|
+
function flush() {
|
|
1603
|
+
cancel();
|
|
1604
|
+
return current.func.apply(null, args);
|
|
1605
|
+
}
|
|
1606
|
+
debounce.flush = flush;
|
|
1607
|
+
debounce.cancel = cancel;
|
|
1608
|
+
return React16.useCallback(debounce, []);
|
|
1609
|
+
};
|
|
1610
|
+
var useDeepEffect_default = (effect, deps) => {
|
|
1611
|
+
const prevDepsRef = React16.useRef();
|
|
1612
|
+
const depsChanged = !prevDepsRef.current || deps.length !== prevDepsRef.current.length || deps.some((dep, i) => !deepEqual(dep, prevDepsRef.current[i]));
|
|
1613
|
+
React16.useEffect(() => {
|
|
1614
|
+
if (depsChanged) {
|
|
1615
|
+
prevDepsRef.current = deps;
|
|
1616
|
+
return effect();
|
|
1617
|
+
}
|
|
1618
|
+
}, [depsChanged]);
|
|
1619
|
+
};
|
|
1620
|
+
var useRefState_default = (init) => {
|
|
1621
|
+
const [state, setState] = React16.useState(init);
|
|
1622
|
+
const stateRef = React16.useRef(init);
|
|
1623
|
+
const setProxy = (newVal) => {
|
|
1624
|
+
stateRef.current = newVal;
|
|
1625
|
+
setState(newVal);
|
|
1626
|
+
};
|
|
1627
|
+
const getState = () => stateRef.current;
|
|
1628
|
+
return [state, setProxy, getState];
|
|
1629
|
+
};
|
|
1630
|
+
var useSpeech_default = ({ onResult, lang = "zh-CN" }) => {
|
|
1631
|
+
const [permission, setPermission] = React16.useState("prompt");
|
|
1632
|
+
const [isRecording, setIsRecording] = React16.useState(false);
|
|
1633
|
+
const recognitionRef = React16.useRef(null);
|
|
1634
|
+
React16.useEffect(() => {
|
|
1635
|
+
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
1636
|
+
if (!SpeechRecognition) {
|
|
1637
|
+
setPermission("unsupported");
|
|
1638
|
+
return;
|
|
1639
|
+
}
|
|
1640
|
+
const recognition = new SpeechRecognition();
|
|
1641
|
+
recognition.continuous = true;
|
|
1642
|
+
recognition.interimResults = false;
|
|
1643
|
+
recognition.lang = lang;
|
|
1644
|
+
recognition.onresult = (event) => {
|
|
1645
|
+
let transcript = "";
|
|
1646
|
+
for (let i = event.resultIndex; i < event.results.length; i++) {
|
|
1647
|
+
transcript += event.results[i][0].transcript;
|
|
1648
|
+
}
|
|
1649
|
+
onResult?.(transcript.trim());
|
|
1650
|
+
};
|
|
1651
|
+
recognition.onend = () => {
|
|
1652
|
+
setIsRecording(false);
|
|
1653
|
+
};
|
|
1654
|
+
recognition.onerror = (error) => {
|
|
1655
|
+
setIsRecording(false);
|
|
1656
|
+
console.error("Speech recognition error:", error);
|
|
1657
|
+
};
|
|
1658
|
+
recognitionRef.current = recognition;
|
|
1659
|
+
return () => {
|
|
1660
|
+
recognition.stop?.();
|
|
1661
|
+
recognition.onresult = null;
|
|
1662
|
+
recognition.onend = null;
|
|
1663
|
+
recognition.onerror = null;
|
|
1664
|
+
};
|
|
1665
|
+
}, [lang, onResult]);
|
|
1666
|
+
React16.useEffect(() => {
|
|
1667
|
+
if (!navigator.permissions) return;
|
|
1668
|
+
navigator.permissions.query({ name: "microphone" }).then((status) => {
|
|
1669
|
+
setPermission(status.state);
|
|
1670
|
+
status.onchange = () => setPermission(status.state);
|
|
1671
|
+
});
|
|
1672
|
+
}, []);
|
|
1673
|
+
const requestPermission = React16.useCallback(async () => {
|
|
1674
|
+
try {
|
|
1675
|
+
await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
1676
|
+
setPermission("granted");
|
|
1677
|
+
} catch {
|
|
1678
|
+
setPermission("denied");
|
|
1679
|
+
}
|
|
1680
|
+
}, []);
|
|
1681
|
+
const start = React16.useCallback(() => {
|
|
1682
|
+
if (permission === "prompt") {
|
|
1683
|
+
requestPermission();
|
|
1684
|
+
return;
|
|
1685
|
+
}
|
|
1686
|
+
if (permission !== "granted") return;
|
|
1687
|
+
if (!isRecording) {
|
|
1688
|
+
recognitionRef.current?.start();
|
|
1689
|
+
setIsRecording(true);
|
|
1690
|
+
}
|
|
1691
|
+
}, [permission, isRecording, requestPermission]);
|
|
1692
|
+
const stop = React16.useCallback(() => {
|
|
1693
|
+
try {
|
|
1694
|
+
recognitionRef.current?.stop();
|
|
1695
|
+
} finally {
|
|
1696
|
+
setIsRecording(false);
|
|
1697
|
+
}
|
|
1698
|
+
}, []);
|
|
1699
|
+
return {
|
|
1700
|
+
/**
|
|
1701
|
+
* 权限状态
|
|
1702
|
+
*/
|
|
1703
|
+
permission,
|
|
1704
|
+
/**
|
|
1705
|
+
* 录音状态
|
|
1706
|
+
*/
|
|
1707
|
+
isRecording,
|
|
1708
|
+
/** 开始语音识别 */
|
|
1709
|
+
start,
|
|
1710
|
+
/** 停止语音识别 */
|
|
1711
|
+
stop
|
|
1712
|
+
};
|
|
1713
|
+
};
|
|
1714
|
+
var useSyncInput_default = (storeValue, setStoreValue) => {
|
|
1715
|
+
const [inputValue, setInputValue] = React16.useState(storeValue);
|
|
1716
|
+
React16.useEffect(() => {
|
|
1717
|
+
if (storeValue !== inputValue) {
|
|
1718
|
+
setInputValue(storeValue);
|
|
1719
|
+
}
|
|
1720
|
+
}, [storeValue]);
|
|
1721
|
+
const handleValueChange = (value) => {
|
|
1722
|
+
setStoreValue(value);
|
|
1723
|
+
setInputValue(value);
|
|
1724
|
+
};
|
|
1725
|
+
return {
|
|
1726
|
+
inputValue,
|
|
1727
|
+
setInputValue: handleValueChange
|
|
1728
|
+
};
|
|
1729
|
+
};
|
|
1730
|
+
var useThrottle_default = (func, wait) => {
|
|
1731
|
+
const { current } = React16.useRef({ func, timeOut: null });
|
|
1732
|
+
React16.useEffect(() => {
|
|
1733
|
+
current.func = func;
|
|
1734
|
+
}, [func]);
|
|
1735
|
+
let args;
|
|
1736
|
+
function throttle(..._args) {
|
|
1737
|
+
args = _args;
|
|
1738
|
+
return new Promise((resolve, reject) => {
|
|
1739
|
+
if (!current.timeOut) {
|
|
1740
|
+
try {
|
|
1741
|
+
const result = current.func.apply(null, args);
|
|
1742
|
+
resolve(result);
|
|
1743
|
+
} catch (e) {
|
|
1744
|
+
reject(e);
|
|
1745
|
+
}
|
|
1746
|
+
current.timeOut = setTimeout(() => {
|
|
1747
|
+
current.timeOut = null;
|
|
1748
|
+
}, wait);
|
|
1749
|
+
}
|
|
1750
|
+
});
|
|
1751
|
+
}
|
|
1752
|
+
function cancel() {
|
|
1753
|
+
if (!current.timeOut) return;
|
|
1754
|
+
clearTimeout(current.timeOut);
|
|
1755
|
+
current.timeOut = null;
|
|
1756
|
+
}
|
|
1757
|
+
function flush() {
|
|
1758
|
+
cancel();
|
|
1759
|
+
return current.func.apply(null, args);
|
|
1760
|
+
}
|
|
1761
|
+
throttle.flush = flush;
|
|
1762
|
+
throttle.cancel = cancel;
|
|
1763
|
+
return React16.useCallback(throttle, []);
|
|
1764
|
+
};
|
|
1765
1765
|
var useWebSocket_default = ({
|
|
1766
1766
|
url,
|
|
1767
1767
|
onMessage,
|
|
@@ -1923,7 +1923,7 @@ var ProtectedView = ({
|
|
|
1923
1923
|
};
|
|
1924
1924
|
var openLinksNewTabPlugin = () => {
|
|
1925
1925
|
const onAnnotationLayerRender = (e) => {
|
|
1926
|
-
e.container.querySelectorAll(".rpv-core__annotation--link a").forEach((linkEle) => {
|
|
1926
|
+
e.container.querySelectorAll(".rpv-core__annotation--link a[href]").forEach((linkEle) => {
|
|
1927
1927
|
const href = linkEle.getAttribute("href");
|
|
1928
1928
|
if (href && isExternal(href)) {
|
|
1929
1929
|
linkEle.setAttribute("target", "_blank");
|