@eternalheart/vue-file-preview 1.3.8 → 1.3.10
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 +4 -0
- package/README.zh-CN.md +4 -0
- package/lib/FilePreviewContent.vue.d.ts +13 -1
- package/lib/FilePreviewContent.vue.d.ts.map +1 -1
- package/lib/FilePreviewEmbed.vue.d.ts +13 -1
- package/lib/FilePreviewEmbed.vue.d.ts.map +1 -1
- package/lib/FilePreviewModal.vue.d.ts +13 -1
- package/lib/FilePreviewModal.vue.d.ts.map +1 -1
- package/lib/chunks/{index-BYzQg-jL.mjs → index-7TEaCdxH.mjs} +25 -25
- package/lib/chunks/index-7TEaCdxH.mjs.map +1 -0
- package/lib/chunks/{index-BM9FaQUl.mjs → index-B4_-Yo-b.mjs} +2 -2
- package/lib/chunks/{index-BM9FaQUl.mjs.map → index-B4_-Yo-b.mjs.map} +1 -1
- package/lib/chunks/index-BD0HLPzh.mjs +116 -0
- package/lib/chunks/index-BD0HLPzh.mjs.map +1 -0
- package/lib/chunks/{index-DAo-7spn.mjs → index-BOL895ZO.mjs} +35 -35
- package/lib/chunks/index-BOL895ZO.mjs.map +1 -0
- package/lib/chunks/index-BUn7C84b.mjs +281 -0
- package/lib/chunks/index-BUn7C84b.mjs.map +1 -0
- package/lib/chunks/{index-lHlugUBI.mjs → index-BY_XuO1z.mjs} +2 -2
- package/lib/chunks/{index-lHlugUBI.mjs.map → index-BY_XuO1z.mjs.map} +1 -1
- package/lib/chunks/{index-DXlcF1Dk.mjs → index-BcXyjt8Z.mjs} +2 -2
- package/lib/chunks/{index-DXlcF1Dk.mjs.map → index-BcXyjt8Z.mjs.map} +1 -1
- package/lib/chunks/{index-BoL1b2w-.mjs → index-BlNjLD3A.mjs} +28 -28
- package/lib/chunks/index-BlNjLD3A.mjs.map +1 -0
- package/lib/chunks/index-BuYJGBLT.mjs +2204 -0
- package/lib/chunks/index-BuYJGBLT.mjs.map +1 -0
- package/lib/chunks/{index-D9wf6m37.mjs → index-CuChO3jv.mjs} +53 -53
- package/lib/chunks/index-CuChO3jv.mjs.map +1 -0
- package/lib/chunks/index-CxiRIgnd.mjs +111 -0
- package/lib/chunks/index-CxiRIgnd.mjs.map +1 -0
- package/lib/chunks/index-D-j14MHC.mjs +164 -0
- package/lib/chunks/index-D-j14MHC.mjs.map +1 -0
- package/lib/chunks/{index-C7uOM7XL.mjs → index-DhQPH7M7.mjs} +53 -53
- package/lib/chunks/index-DhQPH7M7.mjs.map +1 -0
- package/lib/chunks/{index-dzB4jd9b.mjs → index-DheF8bvY.mjs} +106 -106
- package/lib/chunks/index-DheF8bvY.mjs.map +1 -0
- package/lib/chunks/{index-Bri7VeRx.mjs → index-DsZdtQJg.mjs} +46 -46
- package/lib/chunks/index-DsZdtQJg.mjs.map +1 -0
- package/lib/chunks/{index-BCkcZs4y.mjs → index-fD12G5fh.mjs} +31 -31
- package/lib/chunks/index-fD12G5fh.mjs.map +1 -0
- package/lib/chunks/index-h8VDgpZB.mjs +244 -0
- package/lib/chunks/index-h8VDgpZB.mjs.map +1 -0
- package/lib/chunks/{index-CTsscgqY.mjs → index-xBRMnurm.mjs} +32 -32
- package/lib/chunks/index-xBRMnurm.mjs.map +1 -0
- package/lib/chunks/{index-5Smm2vx0.mjs → index-y5WgRh6y.mjs} +24 -24
- package/lib/chunks/index-y5WgRh6y.mjs.map +1 -0
- package/lib/composables/useRequest.d.ts +24 -0
- package/lib/composables/useRequest.d.ts.map +1 -0
- package/lib/index.cjs +28 -24
- package/lib/index.cjs.map +1 -1
- package/lib/index.css +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.mjs +9 -8
- package/lib/renderers/Csv/index.vue.d.ts.map +1 -1
- package/lib/renderers/Docx/index.vue.d.ts.map +1 -1
- package/lib/renderers/Epub/index.vue.d.ts.map +1 -1
- package/lib/renderers/Font/FontPreviewLine.vue.d.ts +18 -0
- package/lib/renderers/Font/FontPreviewLine.vue.d.ts.map +1 -0
- package/lib/renderers/Font/index.vue.d.ts +6 -0
- package/lib/renderers/Font/index.vue.d.ts.map +1 -0
- package/lib/renderers/Json/index.vue.d.ts.map +1 -1
- package/lib/renderers/Markdown/index.vue.d.ts.map +1 -1
- package/lib/renderers/Mobi/index.vue.d.ts.map +1 -1
- package/lib/renderers/Msg/index.vue.d.ts.map +1 -1
- package/lib/renderers/Pdf/index.vue.d.ts.map +1 -1
- package/lib/renderers/Pptx/index.vue.d.ts.map +1 -1
- package/lib/renderers/Subtitle/index.vue.d.ts.map +1 -1
- package/lib/renderers/Text/index.vue.d.ts.map +1 -1
- package/lib/renderers/Xlsx/index.vue.d.ts.map +1 -1
- package/lib/renderers/Xml/index.vue.d.ts.map +1 -1
- package/lib/renderers/Zip/index.vue.d.ts.map +1 -1
- package/lib/renderers/lazy.d.ts +1 -0
- package/lib/renderers/lazy.d.ts.map +1 -1
- package/lib/types.d.ts +1 -1
- package/lib/types.d.ts.map +1 -1
- package/package.json +3 -1
- package/lib/chunks/index-5Smm2vx0.mjs.map +0 -1
- package/lib/chunks/index-BCkcZs4y.mjs.map +0 -1
- package/lib/chunks/index-BYzQg-jL.mjs.map +0 -1
- package/lib/chunks/index-BoL1b2w-.mjs.map +0 -1
- package/lib/chunks/index-Bri7VeRx.mjs.map +0 -1
- package/lib/chunks/index-C324a7kV.mjs +0 -2017
- package/lib/chunks/index-C324a7kV.mjs.map +0 -1
- package/lib/chunks/index-C7uOM7XL.mjs.map +0 -1
- package/lib/chunks/index-CTsscgqY.mjs.map +0 -1
- package/lib/chunks/index-Ch7AEfnk.mjs +0 -116
- package/lib/chunks/index-Ch7AEfnk.mjs.map +0 -1
- package/lib/chunks/index-D9wf6m37.mjs.map +0 -1
- package/lib/chunks/index-DAEQe-RI.mjs +0 -111
- package/lib/chunks/index-DAEQe-RI.mjs.map +0 -1
- package/lib/chunks/index-DAo-7spn.mjs.map +0 -1
- package/lib/chunks/index-ELyTQZeF.mjs +0 -281
- package/lib/chunks/index-ELyTQZeF.mjs.map +0 -1
- package/lib/chunks/index-cZn4ih-x.mjs +0 -111
- package/lib/chunks/index-cZn4ih-x.mjs.map +0 -1
- package/lib/chunks/index-dzB4jd9b.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -232,6 +232,10 @@ Differences from `FilePreviewModal`:
|
|
|
232
232
|
- **Excel**: XLSX format support
|
|
233
233
|
- **PowerPoint**: PPTX/PPT format support, slide preview
|
|
234
234
|
|
|
235
|
+
### Fonts
|
|
236
|
+
- **Formats**: TTF, OTF, WOFF, WOFF2
|
|
237
|
+
- **Features**: Font metadata (family, designer, version), character set preview, custom text input, multi-size display
|
|
238
|
+
|
|
235
239
|
### Code & Text
|
|
236
240
|
- **Markdown**: GitHub Flavored Markdown, code highlighting
|
|
237
241
|
- **Code Files**: JS, TS, Python, Java, C++, Go, Rust, and 40+ languages
|
package/README.zh-CN.md
CHANGED
|
@@ -232,6 +232,10 @@ const files = [
|
|
|
232
232
|
- **Excel**: XLSX 格式支持
|
|
233
233
|
- **PowerPoint**: PPTX/PPT 格式支持、幻灯片预览
|
|
234
234
|
|
|
235
|
+
### 字体
|
|
236
|
+
- **格式**: TTF, OTF, WOFF, WOFF2
|
|
237
|
+
- **功能**: 字体元数据(字体家族、设计师、版本)、字符集预览、自定义文本输入、多字号展示
|
|
238
|
+
|
|
235
239
|
### 代码 & 文本
|
|
236
240
|
- **Markdown**: GitHub Flavored Markdown,代码高亮
|
|
237
241
|
- **代码文件**: JS, TS, Python, Java, C++, Go, Rust 等 40+ 种语言
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type PreviewFileInput, type Locale, type Messages, type Theme, type CustomRendererEventPayload } from '@eternalheart/file-preview-core';
|
|
1
|
+
import { type PreviewFile, type PreviewFileInput, type Locale, type Messages, type Theme, type CustomRendererEventPayload, type RequestHandler, type RequestInitFactory, type ShouldFetchAsBlob } from '@eternalheart/file-preview-core';
|
|
2
2
|
import type { CustomRenderer } from './types';
|
|
3
3
|
interface Props {
|
|
4
4
|
files: PreviewFileInput[];
|
|
@@ -16,6 +16,14 @@ interface Props {
|
|
|
16
16
|
headless?: boolean;
|
|
17
17
|
/** 主题模式,默认 'dark' */
|
|
18
18
|
theme?: Theme;
|
|
19
|
+
/** 自定义 RequestInit(或工厂函数):注入 Authorization 等鉴权头 */
|
|
20
|
+
requestInit?: RequestInitFactory;
|
|
21
|
+
/** 自定义请求处理器:完全接管库内 fetch */
|
|
22
|
+
requestHandler?: RequestHandler;
|
|
23
|
+
/** 返回 true 时,对应文件先 fetcher→blob URL 后喂给 image/video/audio/pdf 等 renderer */
|
|
24
|
+
shouldFetchAsBlob?: ShouldFetchAsBlob;
|
|
25
|
+
/** 自定义下载回调;不传时库内默认通过 fetcher 拉 Blob 触发下载 */
|
|
26
|
+
onDownload?: (file: PreviewFile) => void | Promise<void>;
|
|
19
27
|
}
|
|
20
28
|
declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
21
29
|
close: () => any;
|
|
@@ -26,6 +34,8 @@ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, imp
|
|
|
26
34
|
onNavigate?: ((index: number) => any) | undefined;
|
|
27
35
|
"onCustom-event"?: ((payload: CustomRendererEventPayload<unknown>) => any) | undefined;
|
|
28
36
|
}>, {
|
|
37
|
+
requestInit: RequestInitFactory;
|
|
38
|
+
requestHandler: RequestHandler;
|
|
29
39
|
mode: "modal" | "embed";
|
|
30
40
|
theme: Theme;
|
|
31
41
|
customRenderers: CustomRenderer[];
|
|
@@ -33,6 +43,8 @@ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, imp
|
|
|
33
43
|
locale: Locale;
|
|
34
44
|
messages: Partial<Record<Locale, Partial<Messages>>>;
|
|
35
45
|
headless: boolean;
|
|
46
|
+
shouldFetchAsBlob: ShouldFetchAsBlob;
|
|
47
|
+
onDownload: (file: PreviewFile) => void | Promise<void>;
|
|
36
48
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
37
49
|
export default _default;
|
|
38
50
|
//# sourceMappingURL=FilePreviewContent.vue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilePreviewContent.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewContent.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FilePreviewContent.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewContent.vue"],"names":[],"mappings":"AAsxBA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,KAAK,EACV,KAAK,0BAA0B,EAC/B,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,SAAS,CAAC;AAsCrE,UAAU,KAAK;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,kCAAkC;IAClC,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;;;;;;;;;;iBAPe,kBAAkB;oBAEf,cAAc;UAdxB,OAAO,GAAG,OAAO;WAUhB,KAAK;qBAZK,cAAc,EAAE;qBAIhB,MAAM;YAEf,MAAM;cAEJ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;cAE1C,OAAO;uBAQE,iBAAiB;gBAExB,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;;AAotC1D,wBAQG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PreviewFileInput, Locale, Messages, Theme, CustomRendererEventPayload } from '@eternalheart/file-preview-core';
|
|
1
|
+
import type { PreviewFile, PreviewFileInput, Locale, Messages, Theme, CustomRendererEventPayload, RequestHandler, RequestInitFactory, ShouldFetchAsBlob } from '@eternalheart/file-preview-core';
|
|
2
2
|
import type { CustomRenderer } from './types';
|
|
3
3
|
interface Props {
|
|
4
4
|
files: PreviewFileInput[];
|
|
@@ -16,6 +16,14 @@ interface Props {
|
|
|
16
16
|
headless?: boolean;
|
|
17
17
|
/** 主题模式,默认 'dark' */
|
|
18
18
|
theme?: Theme;
|
|
19
|
+
/** 自定义 RequestInit(或工厂函数):注入 Authorization 等鉴权头 */
|
|
20
|
+
requestInit?: RequestInitFactory;
|
|
21
|
+
/** 自定义请求处理器:完全接管库内 fetch */
|
|
22
|
+
requestHandler?: RequestHandler;
|
|
23
|
+
/** 返回 true 时,对应文件先 fetcher→blob URL 后喂给 image/video/audio/pdf 等 renderer */
|
|
24
|
+
shouldFetchAsBlob?: ShouldFetchAsBlob;
|
|
25
|
+
/** 自定义下载回调;不传时库内默认通过 fetcher 拉 Blob 触发下载 */
|
|
26
|
+
onDownload?: (file: PreviewFile) => void | Promise<void>;
|
|
19
27
|
}
|
|
20
28
|
declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
21
29
|
navigate: (index: number) => any;
|
|
@@ -24,6 +32,8 @@ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, imp
|
|
|
24
32
|
onNavigate?: ((index: number) => any) | undefined;
|
|
25
33
|
"onCustom-event"?: ((payload: CustomRendererEventPayload<unknown>) => any) | undefined;
|
|
26
34
|
}>, {
|
|
35
|
+
requestInit: RequestInitFactory;
|
|
36
|
+
requestHandler: RequestHandler;
|
|
27
37
|
height: number | string;
|
|
28
38
|
width: number | string;
|
|
29
39
|
theme: Theme;
|
|
@@ -32,6 +42,8 @@ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, imp
|
|
|
32
42
|
locale: Locale;
|
|
33
43
|
messages: Partial<Record<Locale, Partial<Messages>>>;
|
|
34
44
|
headless: boolean;
|
|
45
|
+
shouldFetchAsBlob: ShouldFetchAsBlob;
|
|
46
|
+
onDownload: (file: PreviewFile) => void | Promise<void>;
|
|
35
47
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
36
48
|
export default _default;
|
|
37
49
|
//# sourceMappingURL=FilePreviewEmbed.vue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilePreviewEmbed.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewEmbed.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FilePreviewEmbed.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewEmbed.vue"],"names":[],"mappings":"AAsHA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACjM,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,UAAU,KAAK;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,SAAS;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;;;;;;;;iBAPe,kBAAkB;oBAEf,cAAc;YAZtB,MAAM,GAAG,MAAM;WAFhB,MAAM,GAAG,MAAM;WAUf,KAAK;kBAbE,MAAM;qBACH,cAAc,EAAE;YAMzB,MAAM;cAEJ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;cAE1C,OAAO;uBAQE,iBAAiB;gBAExB,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;;AAsK1D,wBAQG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PreviewFileInput, Locale, Messages, Theme, CustomRendererEventPayload } from '@eternalheart/file-preview-core';
|
|
1
|
+
import type { PreviewFile, PreviewFileInput, Locale, Messages, Theme, CustomRendererEventPayload, RequestHandler, RequestInitFactory, ShouldFetchAsBlob } from '@eternalheart/file-preview-core';
|
|
2
2
|
import type { CustomRenderer } from './types';
|
|
3
3
|
interface Props {
|
|
4
4
|
files: PreviewFileInput[];
|
|
@@ -13,6 +13,14 @@ interface Props {
|
|
|
13
13
|
headless?: boolean;
|
|
14
14
|
/** 主题模式,默认 'dark' */
|
|
15
15
|
theme?: Theme;
|
|
16
|
+
/** 自定义 RequestInit(或工厂函数):注入 Authorization 等鉴权头 */
|
|
17
|
+
requestInit?: RequestInitFactory;
|
|
18
|
+
/** 自定义请求处理器:完全接管库内 fetch */
|
|
19
|
+
requestHandler?: RequestHandler;
|
|
20
|
+
/** 返回 true 时,对应文件先 fetcher→blob URL 后喂给 image/video/audio/pdf 等 renderer */
|
|
21
|
+
shouldFetchAsBlob?: ShouldFetchAsBlob;
|
|
22
|
+
/** 自定义下载回调;不传时库内默认通过 fetcher 拉 Blob 触发下载 */
|
|
23
|
+
onDownload?: (file: PreviewFile) => void | Promise<void>;
|
|
16
24
|
}
|
|
17
25
|
declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
18
26
|
close: () => any;
|
|
@@ -23,11 +31,15 @@ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, imp
|
|
|
23
31
|
onNavigate?: ((index: number) => any) | undefined;
|
|
24
32
|
"onCustom-event"?: ((payload: CustomRendererEventPayload<unknown>) => any) | undefined;
|
|
25
33
|
}>, {
|
|
34
|
+
requestInit: RequestInitFactory;
|
|
35
|
+
requestHandler: RequestHandler;
|
|
26
36
|
theme: Theme;
|
|
27
37
|
customRenderers: CustomRenderer[];
|
|
28
38
|
locale: Locale;
|
|
29
39
|
messages: Partial<Record<Locale, Partial<Messages>>>;
|
|
30
40
|
headless: boolean;
|
|
41
|
+
shouldFetchAsBlob: ShouldFetchAsBlob;
|
|
42
|
+
onDownload: (file: PreviewFile) => void | Promise<void>;
|
|
31
43
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
32
44
|
export default _default;
|
|
33
45
|
//# sourceMappingURL=FilePreviewModal.vue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilePreviewModal.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewModal.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FilePreviewModal.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewModal.vue"],"names":[],"mappings":"AAoIA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACjM,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI9C,UAAU,KAAK;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,SAAS;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;;;;;;;;;;iBAPe,kBAAkB;oBAEf,cAAc;WAJvB,KAAK;qBARK,cAAc,EAAE;YAEzB,MAAM;cAEJ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;cAE1C,OAAO;uBAQE,iBAAiB;gBAExB,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;;AAuN1D,wBAQG"}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { defineComponent as
|
|
1
|
+
import { defineComponent as P, ref as y, onMounted as W, watch as R, onBeforeUnmount as j, openBlock as g, createElementBlock as b, createElementVNode as f, toDisplayString as E, unref as T, createCommentVNode as k, createVNode as F, normalizeStyle as L } from "vue";
|
|
2
2
|
import { Presentation as N } from "lucide-vue-next";
|
|
3
3
|
import { init as D } from "pptx-preview";
|
|
4
|
-
import { u as S } from "./index-
|
|
5
|
-
const
|
|
4
|
+
import { u as S, a as V } from "./index-BuYJGBLT.mjs";
|
|
5
|
+
const q = { class: "vfp-relative vfp-flex vfp-flex-col vfp-items-center vfp-w-full vfp-h-full" }, A = {
|
|
6
6
|
key: 0,
|
|
7
7
|
class: "vfp-absolute vfp-inset-0 vfp-flex vfp-items-center vfp-justify-center vfp-bg-surface-toolbar vfp-backdrop-blur-sm vfp-z-10"
|
|
8
|
-
},
|
|
8
|
+
}, H = { class: "vfp-text-center" }, I = { class: "vfp-text-xs md:vfp-text-sm vfp-text-fg-secondary vfp-font-medium" }, O = {
|
|
9
9
|
key: 1,
|
|
10
10
|
class: "vfp-absolute vfp-inset-0 vfp-flex vfp-items-center vfp-justify-center vfp-bg-surface-toolbar vfp-backdrop-blur-sm vfp-z-10"
|
|
11
|
-
},
|
|
11
|
+
}, U = { class: "vfp-text-center vfp-max-w-sm md:vfp-max-w-md vfp-px-4" }, $ = { class: "vfp-w-24 vfp-h-24 md:vfp-w-32 md:vfp-h-32 vfp-mx-auto vfp-mb-4 md:vfp-mb-6 vfp-rounded-2xl md:vfp-rounded-3xl vfp-bg-gradient-to-br vfp-from-orange-500 vfp-via-red-500 vfp-to-pink-500 vfp-flex vfp-items-center vfp-justify-center vfp-shadow-2xl" }, G = { class: "vfp-text-lg md:vfp-text-xl vfp-text-fg-primary vfp-mb-2 md:vfp-mb-3 vfp-font-medium" }, J = { class: "vfp-text-xs md:vfp-text-sm vfp-text-fg-tertiary vfp-mb-4 md:vfp-mb-6" }, K = ["href"], ee = /* @__PURE__ */ P({
|
|
12
12
|
__name: "index",
|
|
13
13
|
props: {
|
|
14
14
|
url: {},
|
|
15
15
|
tiled: { type: Boolean, default: !0 }
|
|
16
16
|
},
|
|
17
17
|
setup(M) {
|
|
18
|
-
const a = M, { t: l } = S(), s = y(!0), p = y(null), c = y(0), r = y(null);
|
|
18
|
+
const a = M, { t: l } = S(), B = V(), s = y(!0), p = y(null), c = y(0), r = y(null);
|
|
19
19
|
let o = null, m = null, d = null, u = null, h = { width: 0, height: 0 };
|
|
20
20
|
const w = () => {
|
|
21
21
|
var v;
|
|
22
22
|
if (!r.value) return { width: 960, height: 540 };
|
|
23
23
|
const t = r.value.clientWidth, e = ((v = r.value.parentElement) == null ? void 0 : v.clientWidth) || 0, i = t > 100 ? t : e > 100 ? e : 300, n = Math.floor(i * 9 / 16);
|
|
24
24
|
return { width: i, height: n };
|
|
25
|
-
},
|
|
25
|
+
}, C = async () => {
|
|
26
26
|
if (!(!r.value || !d || c.value === 0))
|
|
27
27
|
try {
|
|
28
28
|
if (o)
|
|
@@ -46,7 +46,7 @@ const V = { class: "vfp-relative vfp-flex vfp-flex-col vfp-items-center vfp-w-fu
|
|
|
46
46
|
p.value = l.value("pptx.timeout"), s.value = !1;
|
|
47
47
|
}, 3e4);
|
|
48
48
|
try {
|
|
49
|
-
const e = await
|
|
49
|
+
const e = await B.value(a.url, {
|
|
50
50
|
mode: "cors",
|
|
51
51
|
credentials: "omit",
|
|
52
52
|
redirect: "follow"
|
|
@@ -87,7 +87,7 @@ const V = { class: "vfp-relative vfp-flex vfp-flex-col vfp-items-center vfp-w-fu
|
|
|
87
87
|
e instanceof Error ? i = e.message : typeof e == "string" && (i = e), p.value = i, s.value = !1;
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
|
-
return
|
|
90
|
+
return W(() => {
|
|
91
91
|
if (!r.value) return;
|
|
92
92
|
let t = !0;
|
|
93
93
|
m = new ResizeObserver(() => {
|
|
@@ -97,42 +97,42 @@ const V = { class: "vfp-relative vfp-flex vfp-flex-col vfp-items-center vfp-w-fu
|
|
|
97
97
|
}
|
|
98
98
|
const e = w(), i = Math.abs(h.width - e.width), n = Math.abs(h.height - e.height);
|
|
99
99
|
i < 10 && n < 10 || (h = e, u !== null && clearTimeout(u), u = window.setTimeout(() => {
|
|
100
|
-
o && d &&
|
|
100
|
+
o && d && C();
|
|
101
101
|
}, 800));
|
|
102
102
|
}), m.observe(r.value), setTimeout(() => {
|
|
103
103
|
requestAnimationFrame(() => requestAnimationFrame(() => z()));
|
|
104
104
|
}, 150);
|
|
105
|
-
}),
|
|
105
|
+
}), R(
|
|
106
106
|
() => a.url,
|
|
107
107
|
() => {
|
|
108
108
|
z();
|
|
109
109
|
}
|
|
110
|
-
),
|
|
110
|
+
), j(() => {
|
|
111
111
|
if (m && m.disconnect(), u !== null && clearTimeout(u), d = null, c.value = 0, o)
|
|
112
112
|
try {
|
|
113
113
|
o.destroy();
|
|
114
114
|
} catch {
|
|
115
115
|
}
|
|
116
116
|
o = null;
|
|
117
|
-
}), (t, e) => (g(), b("div",
|
|
118
|
-
s.value ? (g(), b("div",
|
|
119
|
-
f("div",
|
|
117
|
+
}), (t, e) => (g(), b("div", q, [
|
|
118
|
+
s.value ? (g(), b("div", A, [
|
|
119
|
+
f("div", H, [
|
|
120
120
|
e[0] || (e[0] = f("div", { class: "vfp-w-10 vfp-h-10 md:vfp-w-12 md:vfp-h-12 vfp-mx-auto vfp-mb-3 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin" }, null, -1)),
|
|
121
|
-
f("p",
|
|
121
|
+
f("p", I, E(T(l)("pptx.loading")), 1)
|
|
122
122
|
])
|
|
123
123
|
])) : k("", !0),
|
|
124
|
-
p.value && !s.value ? (g(), b("div",
|
|
125
|
-
f("div",
|
|
126
|
-
f("div",
|
|
127
|
-
|
|
124
|
+
p.value && !s.value ? (g(), b("div", O, [
|
|
125
|
+
f("div", U, [
|
|
126
|
+
f("div", $, [
|
|
127
|
+
F(T(N), { class: "vfp-w-12 vfp-h-12 md:vfp-w-16 md:vfp-h-16 vfp-text-fg-primary" })
|
|
128
128
|
]),
|
|
129
|
-
f("p",
|
|
130
|
-
f("p",
|
|
129
|
+
f("p", G, E(T(l)("pptx.load_failed")), 1),
|
|
130
|
+
f("p", J, E(p.value), 1),
|
|
131
131
|
f("a", {
|
|
132
132
|
href: M.url,
|
|
133
133
|
download: "",
|
|
134
134
|
class: "vfp-inline-flex vfp-items-center vfp-gap-2 vfp-px-4 vfp-py-2 md:vfp-px-6 md:vfp-py-3 vfp-bg-gradient-to-r vfp-from-purple-500 vfp-to-pink-500 vfp-text-fg-primary vfp-text-sm md:vfp-text-base vfp-rounded-lg md:vfp-rounded-xl hover:vfp-scale-105 vfp-transition-all vfp-shadow-lg"
|
|
135
|
-
}, " 下载文件 ", 8,
|
|
135
|
+
}, " 下载文件 ", 8, K),
|
|
136
136
|
e[1] || (e[1] = f("p", { class: "vfp-text-xs vfp-text-fg-muted vfp-mt-3 md:vfp-mt-4" }, " 提示:可以使用 Microsoft PowerPoint 或 WPS 打开 ", -1))
|
|
137
137
|
])
|
|
138
138
|
])) : k("", !0),
|
|
@@ -147,6 +147,6 @@ const V = { class: "vfp-relative vfp-flex vfp-flex-col vfp-items-center vfp-w-fu
|
|
|
147
147
|
}
|
|
148
148
|
});
|
|
149
149
|
export {
|
|
150
|
-
|
|
150
|
+
ee as default
|
|
151
151
|
};
|
|
152
|
-
//# sourceMappingURL=index-
|
|
152
|
+
//# sourceMappingURL=index-7TEaCdxH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-7TEaCdxH.mjs","sources":["../../src/renderers/Pptx/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount } from 'vue';\nimport { Presentation } from 'lucide-vue-next';\nimport { init } from 'pptx-preview';\nimport { useTranslator } from '../../composables/useTranslator';\nimport { useFetcher } from '../../composables/useRequest';\n\nconst props = withDefaults(\n defineProps<{\n url: string;\n tiled?: boolean;\n }>(),\n { tiled: true }\n);\n\nconst { t } = useTranslator();\nconst fetcher = useFetcher();\n\nconst loading = ref(true);\nconst error = ref<string | null>(null);\nconst slideCount = ref(0);\nconst containerRef = ref<HTMLDivElement | null>(null);\nlet previewer: ReturnType<typeof init> | null = null;\nlet resizeObserver: ResizeObserver | null = null;\nlet arrayBufferRef: ArrayBuffer | null = null;\nlet resizeTimeout: number | null = null;\nlet lastDimensions = { width: 0, height: 0 };\n\nconst calculateDimensions = () => {\n if (!containerRef.value) return { width: 960, height: 540 };\n const rawWidth = containerRef.value.clientWidth;\n const parentWidth = containerRef.value.parentElement?.clientWidth || 0;\n const containerWidth = rawWidth > 100 ? rawWidth : parentWidth > 100 ? parentWidth : 300;\n const height = Math.floor((containerWidth * 9) / 16);\n return { width: containerWidth, height };\n};\n\nconst reinitializePreviewer = async () => {\n if (!containerRef.value || !arrayBufferRef || slideCount.value === 0) return;\n\n try {\n if (previewer) {\n try {\n previewer.destroy();\n } catch {\n // ignore\n }\n }\n\n containerRef.value.innerHTML = '';\n\n const currentDimensions = calculateDimensions();\n previewer = init(containerRef.value, {\n width: currentDimensions.width,\n height: props.tiled ? currentDimensions.height * slideCount.value : currentDimensions.height,\n mode: props.tiled ? 'list' : 'slide',\n });\n\n await previewer.preview(arrayBufferRef);\n } catch {\n // 静默处理\n }\n};\n\nconst loadPptx = async () => {\n if (!containerRef.value) return;\n\n loading.value = true;\n error.value = null;\n\n let timeoutId: number | null = window.setTimeout(() => {\n error.value = t.value('pptx.timeout');\n loading.value = false;\n }, 30000);\n\n try {\n const response = await fetcher.value(props.url, {\n mode: 'cors',\n credentials: 'omit',\n redirect: 'follow',\n });\n\n if (!response.ok) {\n if (response.status === 404) throw new Error(t.value('pptx.not_found'));\n if (response.status === 403) throw new Error('无权限访问此文件');\n if (response.status >= 500) throw new Error('服务器错误,请稍后重试');\n throw new Error(`文件加载失败 (${response.status})`);\n }\n\n const arrayBuffer = await response.arrayBuffer();\n if (arrayBuffer.byteLength === 0) throw new Error('文件为空');\n\n arrayBufferRef = arrayBuffer;\n\n // 步骤 1: 创建隐藏容器获取 slideCount\n const hiddenContainer = document.createElement('div');\n hiddenContainer.style.cssText = 'position:absolute;left:-9999px;top:-9999px;visibility:hidden';\n document.body.appendChild(hiddenContainer);\n\n try {\n const tempPreviewer = init(hiddenContainer, {\n width: 100,\n height: 100,\n mode: 'slide',\n });\n\n try {\n await tempPreviewer.preview(arrayBuffer);\n } catch {\n throw new Error(t.value('pptx.invalid_format'));\n }\n\n const count = tempPreviewer.slideCount;\n if (!count || count === 0) throw new Error(t.value('pptx.no_pages'));\n\n tempPreviewer.destroy();\n\n slideCount.value = count;\n\n if (containerRef.value) {\n containerRef.value.innerHTML = '';\n }\n\n const currentDimensions = calculateDimensions();\n previewer = init(containerRef.value, {\n width: currentDimensions.width,\n height: props.tiled ? currentDimensions.height * count : currentDimensions.height,\n mode: props.tiled ? 'list' : 'slide',\n });\n\n await previewer.preview(arrayBuffer);\n\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n loading.value = false;\n } finally {\n if (document.body.contains(hiddenContainer)) {\n document.body.removeChild(hiddenContainer);\n }\n }\n } catch (err) {\n if (timeoutId !== null) clearTimeout(timeoutId);\n let errorMsg = t.value('pptx.parse_failed');\n if (err instanceof Error) errorMsg = err.message;\n else if (typeof err === 'string') errorMsg = err;\n error.value = errorMsg;\n loading.value = false;\n }\n};\n\nonMounted(() => {\n if (!containerRef.value) return;\n\n let isInitialRender = true;\n\n resizeObserver = new ResizeObserver(() => {\n if (isInitialRender) {\n isInitialRender = false;\n lastDimensions = calculateDimensions();\n return;\n }\n\n const newDimensions = calculateDimensions();\n const widthDiff = Math.abs(lastDimensions.width - newDimensions.width);\n const heightDiff = Math.abs(lastDimensions.height - newDimensions.height);\n\n if (widthDiff < 10 && heightDiff < 10) return;\n\n lastDimensions = newDimensions;\n\n if (resizeTimeout !== null) clearTimeout(resizeTimeout);\n\n resizeTimeout = window.setTimeout(() => {\n if (previewer && arrayBufferRef) reinitializePreviewer();\n }, 800);\n });\n\n resizeObserver.observe(containerRef.value);\n\n setTimeout(() => {\n requestAnimationFrame(() => requestAnimationFrame(() => loadPptx()));\n }, 150);\n});\n\nwatch(\n () => props.url,\n () => {\n loadPptx();\n }\n);\n\nonBeforeUnmount(() => {\n if (resizeObserver) resizeObserver.disconnect();\n if (resizeTimeout !== null) clearTimeout(resizeTimeout);\n arrayBufferRef = null;\n slideCount.value = 0;\n if (previewer) {\n try {\n previewer.destroy();\n } catch {\n // ignore\n }\n }\n previewer = null;\n});\n</script>\n\n<template>\n <div class=\"vfp-relative vfp-flex vfp-flex-col vfp-items-center vfp-w-full vfp-h-full\">\n <div\n v-if=\"loading\"\n class=\"vfp-absolute vfp-inset-0 vfp-flex vfp-items-center vfp-justify-center vfp-bg-surface-toolbar vfp-backdrop-blur-sm vfp-z-10\"\n >\n <div class=\"vfp-text-center\">\n <div\n class=\"vfp-w-10 vfp-h-10 md:vfp-w-12 md:vfp-h-12 vfp-mx-auto vfp-mb-3 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n <p class=\"vfp-text-xs md:vfp-text-sm vfp-text-fg-secondary vfp-font-medium\">{{ t('pptx.loading') }}</p>\n </div>\n </div>\n\n <div\n v-if=\"error && !loading\"\n class=\"vfp-absolute vfp-inset-0 vfp-flex vfp-items-center vfp-justify-center vfp-bg-surface-toolbar vfp-backdrop-blur-sm vfp-z-10\"\n >\n <div class=\"vfp-text-center vfp-max-w-sm md:vfp-max-w-md vfp-px-4\">\n <div\n class=\"vfp-w-24 vfp-h-24 md:vfp-w-32 md:vfp-h-32 vfp-mx-auto vfp-mb-4 md:vfp-mb-6 vfp-rounded-2xl md:vfp-rounded-3xl vfp-bg-gradient-to-br vfp-from-orange-500 vfp-via-red-500 vfp-to-pink-500 vfp-flex vfp-items-center vfp-justify-center vfp-shadow-2xl\"\n >\n <Presentation class=\"vfp-w-12 vfp-h-12 md:vfp-w-16 md:vfp-h-16 vfp-text-fg-primary\" />\n </div>\n <p class=\"vfp-text-lg md:vfp-text-xl vfp-text-fg-primary vfp-mb-2 md:vfp-mb-3 vfp-font-medium\">\n {{ t('pptx.load_failed') }}\n </p>\n <p class=\"vfp-text-xs md:vfp-text-sm vfp-text-fg-tertiary vfp-mb-4 md:vfp-mb-6\">{{ error }}</p>\n <a\n :href=\"url\"\n download\n class=\"vfp-inline-flex vfp-items-center vfp-gap-2 vfp-px-4 vfp-py-2 md:vfp-px-6 md:vfp-py-3 vfp-bg-gradient-to-r vfp-from-purple-500 vfp-to-pink-500 vfp-text-fg-primary vfp-text-sm md:vfp-text-base vfp-rounded-lg md:vfp-rounded-xl hover:vfp-scale-105 vfp-transition-all vfp-shadow-lg\"\n >\n 下载文件\n </a>\n <p class=\"vfp-text-xs vfp-text-fg-muted vfp-mt-3 md:vfp-mt-4\">\n 提示:可以使用 Microsoft PowerPoint 或 WPS 打开\n </p>\n </div>\n </div>\n\n <div\n v-if=\"!error\"\n ref=\"containerRef\"\n class=\"pptx-wrapper vfp-w-full vfp-max-w-full md:vfp-max-w-6xl\"\n :style=\"{ opacity: loading ? 0 : 1 }\"\n />\n </div>\n</template>\n"],"names":["props","__props","t","useTranslator","fetcher","useFetcher","loading","ref","error","slideCount","containerRef","previewer","resizeObserver","arrayBufferRef","resizeTimeout","lastDimensions","calculateDimensions","rawWidth","parentWidth","_a","containerWidth","height","reinitializePreviewer","currentDimensions","init","loadPptx","timeoutId","response","arrayBuffer","hiddenContainer","tempPreviewer","count","err","errorMsg","onMounted","isInitialRender","newDimensions","widthDiff","heightDiff","watch","onBeforeUnmount","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_createElementVNode","_hoisted_3","_hoisted_4","_toDisplayString","_unref","_hoisted_5","_hoisted_6","_hoisted_7","_createVNode","Presentation","_hoisted_8","_hoisted_9","_hoisted_10","_cache"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineComponent as U, ref as o, watch as z, onMounted as V, onBeforeUnmount as O, computed as E, openBlock as x, createElementBlock as y, normalizeStyle as Y, createElementVNode as C, createCommentVNode as k, toDisplayString as w, normalizeClass as Z } from "vue";
|
|
2
|
-
import { u as q,
|
|
2
|
+
import { u as q, h as A } from "./index-BuYJGBLT.mjs";
|
|
3
3
|
const F = {
|
|
4
4
|
key: 0,
|
|
5
5
|
class: "vfp-flex vfp-items-center vfp-justify-center"
|
|
@@ -131,4 +131,4 @@ const F = {
|
|
|
131
131
|
export {
|
|
132
132
|
ne as default
|
|
133
133
|
};
|
|
134
|
-
//# sourceMappingURL=index-
|
|
134
|
+
//# sourceMappingURL=index-B4_-Yo-b.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-BM9FaQUl.mjs","sources":["../../src/renderers/Image/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue';\nimport { formatFileSize } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\n\nconst props = defineProps<{\n url: string;\n zoom: number;\n rotation: number;\n resetKey?: number;\n fileSize?: number;\n}>();\n\nconst emit = defineEmits<{\n (e: 'zoomChange', zoom: number): void;\n (e: 'naturalWidthChange', width: number): void;\n (e: 'naturalHeightChange', height: number): void;\n}>();\n\nconst { t } = useTranslator();\n\nconst loaded = ref(false);\nconst error = ref<string | null>(null);\nconst position = ref({ x: 0, y: 0 });\nconst isDragging = ref(false);\nlet dragStart = { x: 0, y: 0 };\nconst internalZoom = ref(1);\nconst naturalSize = ref({ width: 0, height: 0 });\n\nconst imgRef = ref<HTMLImageElement | null>(null);\nconst containerRef = ref<HTMLDivElement | null>(null);\n\nwatch(\n () => props.url,\n () => {\n loaded.value = false;\n error.value = null;\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n }\n);\n\nwatch(\n () => props.zoom,\n (z) => {\n internalZoom.value = z;\n }\n);\n\nwatch(\n () => props.resetKey,\n () => {\n position.value = { x: 0, y: 0 };\n }\n);\n\nconst clampPosition = (pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.value;\n if (!container || naturalSize.value.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.value.width * currentZoom;\n const imgH = naturalSize.value.height * currentZoom;\n\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};\n\nconst handleLoad = (e: Event) => {\n loaded.value = true;\n const img = e.currentTarget as HTMLImageElement;\n naturalSize.value = { width: img.naturalWidth, height: img.naturalHeight };\n emit('naturalWidthChange', img.naturalWidth);\n emit('naturalHeightChange', img.naturalHeight);\n};\n\nconst handleError = () => {\n error.value = t.value('image.load_failed');\n loaded.value = true;\n};\n\nconst handleDoubleClick = () => {\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n emit('zoomChange', 1);\n};\n\n// 鼠标滚轮缩放\nconst handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const container = containerRef.value;\n if (!container) return;\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 const prev = internalZoom.value;\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n position.value = clampPosition(\n {\n x: mouseX - scale * (mouseX - position.value.x),\n y: mouseY - scale * (mouseY - position.value.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n emit('zoomChange', newZoom);\n};\n\nonMounted(() => {\n const container = containerRef.value;\n if (container) {\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n }\n});\n\nonBeforeUnmount(() => {\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n }\n});\n\nconst handleMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n isDragging.value = true;\n dragStart = {\n x: e.clientX - position.value.x,\n y: e.clientY - position.value.y,\n };\n};\n\nconst handleMouseMove = (e: MouseEvent) => {\n if (!isDragging.value) return;\n position.value = clampPosition(\n {\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n },\n internalZoom.value\n );\n};\n\nconst handleMouseUp = () => {\n isDragging.value = false;\n};\n\nconst transformStyle = computed(() => ({\n transform: `translate(${position.value.x}px, ${position.value.y}px) scale(${internalZoom.value}) rotate(${props.rotation}deg)`,\n transformOrigin: 'center',\n transition: isDragging.value ? 'none' : 'transform 0.3s ease-out',\n opacity: loaded.value ? 1 : 0,\n}));\n\nconst sizeText = computed(() => {\n if (props.fileSize == null) return '';\n return ` · ${formatFileSize(props.fileSize)}`;\n});\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"vfp-relative vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-overflow-hidden\"\n :style=\"{ cursor: isDragging ? 'grabbing' : 'grab' }\"\n @mousedown=\"handleMouseDown\"\n @mousemove=\"handleMouseMove\"\n @mouseup=\"handleMouseUp\"\n @mouseleave=\"handleMouseUp\"\n >\n <div v-if=\"!loaded && !error\" class=\"vfp-flex vfp-items-center vfp-justify-center\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <div v-if=\"error\" class=\"vfp-text-fg-secondary vfp-text-center\">\n <p class=\"vfp-text-lg\">{{ error }}</p>\n </div>\n\n <img\n ref=\"imgRef\"\n :src=\"url\"\n alt=\"Preview\"\n :class=\"['vfp-max-w-none vfp-select-none', !loaded && 'vfp-hidden']\"\n :style=\"transformStyle\"\n :draggable=\"false\"\n @load=\"handleLoad\"\n @error=\"handleError\"\n @dblclick=\"handleDoubleClick\"\n />\n\n <div\n v-if=\"loaded && !error && naturalSize.width > 0\"\n class=\"vfp-absolute vfp-bottom-2 vfp-right-3 vfp-text-[10px] vfp-text-fg-disabled hover:vfp-text-fg-secondary vfp-transition-colors vfp-pointer-events-auto vfp-select-none vfp-cursor-default\"\n >\n {{ naturalSize.width }} × {{ naturalSize.height }}{{ sizeText }}\n </div>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","t","useTranslator","loaded","ref","error","position","isDragging","dragStart","internalZoom","naturalSize","imgRef","containerRef","watch","z","clampPosition","pos","currentZoom","container","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleLoad","img","handleError","handleDoubleClick","handleWheelNative","rect","mouseX","mouseY","delta","prev","newZoom","scale","onMounted","onBeforeUnmount","handleMouseDown","handleMouseMove","handleMouseUp","transformStyle","computed","sizeText","formatFileSize","_createElementBlock","_openBlock","_hoisted_1","_cache","_createElementVNode","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_5"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-B4_-Yo-b.mjs","sources":["../../src/renderers/Image/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue';\nimport { formatFileSize } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\n\nconst props = defineProps<{\n url: string;\n zoom: number;\n rotation: number;\n resetKey?: number;\n fileSize?: number;\n}>();\n\nconst emit = defineEmits<{\n (e: 'zoomChange', zoom: number): void;\n (e: 'naturalWidthChange', width: number): void;\n (e: 'naturalHeightChange', height: number): void;\n}>();\n\nconst { t } = useTranslator();\n\nconst loaded = ref(false);\nconst error = ref<string | null>(null);\nconst position = ref({ x: 0, y: 0 });\nconst isDragging = ref(false);\nlet dragStart = { x: 0, y: 0 };\nconst internalZoom = ref(1);\nconst naturalSize = ref({ width: 0, height: 0 });\n\nconst imgRef = ref<HTMLImageElement | null>(null);\nconst containerRef = ref<HTMLDivElement | null>(null);\n\nwatch(\n () => props.url,\n () => {\n loaded.value = false;\n error.value = null;\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n }\n);\n\nwatch(\n () => props.zoom,\n (z) => {\n internalZoom.value = z;\n }\n);\n\nwatch(\n () => props.resetKey,\n () => {\n position.value = { x: 0, y: 0 };\n }\n);\n\nconst clampPosition = (pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.value;\n if (!container || naturalSize.value.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.value.width * currentZoom;\n const imgH = naturalSize.value.height * currentZoom;\n\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};\n\nconst handleLoad = (e: Event) => {\n loaded.value = true;\n const img = e.currentTarget as HTMLImageElement;\n naturalSize.value = { width: img.naturalWidth, height: img.naturalHeight };\n emit('naturalWidthChange', img.naturalWidth);\n emit('naturalHeightChange', img.naturalHeight);\n};\n\nconst handleError = () => {\n error.value = t.value('image.load_failed');\n loaded.value = true;\n};\n\nconst handleDoubleClick = () => {\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n emit('zoomChange', 1);\n};\n\n// 鼠标滚轮缩放\nconst handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const container = containerRef.value;\n if (!container) return;\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 const prev = internalZoom.value;\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n position.value = clampPosition(\n {\n x: mouseX - scale * (mouseX - position.value.x),\n y: mouseY - scale * (mouseY - position.value.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n emit('zoomChange', newZoom);\n};\n\nonMounted(() => {\n const container = containerRef.value;\n if (container) {\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n }\n});\n\nonBeforeUnmount(() => {\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n }\n});\n\nconst handleMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n isDragging.value = true;\n dragStart = {\n x: e.clientX - position.value.x,\n y: e.clientY - position.value.y,\n };\n};\n\nconst handleMouseMove = (e: MouseEvent) => {\n if (!isDragging.value) return;\n position.value = clampPosition(\n {\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n },\n internalZoom.value\n );\n};\n\nconst handleMouseUp = () => {\n isDragging.value = false;\n};\n\nconst transformStyle = computed(() => ({\n transform: `translate(${position.value.x}px, ${position.value.y}px) scale(${internalZoom.value}) rotate(${props.rotation}deg)`,\n transformOrigin: 'center',\n transition: isDragging.value ? 'none' : 'transform 0.3s ease-out',\n opacity: loaded.value ? 1 : 0,\n}));\n\nconst sizeText = computed(() => {\n if (props.fileSize == null) return '';\n return ` · ${formatFileSize(props.fileSize)}`;\n});\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"vfp-relative vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-overflow-hidden\"\n :style=\"{ cursor: isDragging ? 'grabbing' : 'grab' }\"\n @mousedown=\"handleMouseDown\"\n @mousemove=\"handleMouseMove\"\n @mouseup=\"handleMouseUp\"\n @mouseleave=\"handleMouseUp\"\n >\n <div v-if=\"!loaded && !error\" class=\"vfp-flex vfp-items-center vfp-justify-center\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <div v-if=\"error\" class=\"vfp-text-fg-secondary vfp-text-center\">\n <p class=\"vfp-text-lg\">{{ error }}</p>\n </div>\n\n <img\n ref=\"imgRef\"\n :src=\"url\"\n alt=\"Preview\"\n :class=\"['vfp-max-w-none vfp-select-none', !loaded && 'vfp-hidden']\"\n :style=\"transformStyle\"\n :draggable=\"false\"\n @load=\"handleLoad\"\n @error=\"handleError\"\n @dblclick=\"handleDoubleClick\"\n />\n\n <div\n v-if=\"loaded && !error && naturalSize.width > 0\"\n class=\"vfp-absolute vfp-bottom-2 vfp-right-3 vfp-text-[10px] vfp-text-fg-disabled hover:vfp-text-fg-secondary vfp-transition-colors vfp-pointer-events-auto vfp-select-none vfp-cursor-default\"\n >\n {{ naturalSize.width }} × {{ naturalSize.height }}{{ sizeText }}\n </div>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","t","useTranslator","loaded","ref","error","position","isDragging","dragStart","internalZoom","naturalSize","imgRef","containerRef","watch","z","clampPosition","pos","currentZoom","container","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleLoad","img","handleError","handleDoubleClick","handleWheelNative","rect","mouseX","mouseY","delta","prev","newZoom","scale","onMounted","onBeforeUnmount","handleMouseDown","handleMouseMove","handleMouseUp","transformStyle","computed","sizeText","formatFileSize","_createElementBlock","_openBlock","_hoisted_1","_cache","_createElementVNode","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_5"],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { defineComponent as j, ref as h, watch as S, computed as y, openBlock as a, createElementBlock as r, createElementVNode as e, toDisplayString as o, unref as c, normalizeClass as b, Fragment as x, renderList as k, createCommentVNode as C } from "vue";
|
|
2
|
+
import { u as V, a as z, C as A, e as d, F as D, _ as I } from "./index-BuYJGBLT.mjs";
|
|
3
|
+
const M = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-bg-[#0f0f12]"
|
|
6
|
+
}, O = {
|
|
7
|
+
key: 1,
|
|
8
|
+
class: "vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-bg-[#0f0f12]"
|
|
9
|
+
}, R = { class: "vfp-text-fg-secondary vfp-text-center" }, X = { class: "vfp-text-lg" }, Y = { class: "content-scroll" }, q = { class: "timeline" }, G = { class: "cues" }, H = { class: "cue-meta" }, J = { class: "cue-time" }, K = { class: "cue-time" }, P = { class: "cue-id" }, Q = {
|
|
10
|
+
key: 0,
|
|
11
|
+
class: "cue-style"
|
|
12
|
+
}, U = {
|
|
13
|
+
key: 0,
|
|
14
|
+
class: "cue-words"
|
|
15
|
+
}, W = ["title"], Z = { class: "cue-word-time" }, $ = { class: "cue-word-text" }, ee = { class: "status-pill" }, te = /* @__PURE__ */ j({
|
|
16
|
+
__name: "index",
|
|
17
|
+
props: {
|
|
18
|
+
url: {},
|
|
19
|
+
fileName: {}
|
|
20
|
+
},
|
|
21
|
+
setup(F) {
|
|
22
|
+
const v = F, { t: u } = V(), N = z(), f = h(""), p = h(!0), i = h(null), T = {
|
|
23
|
+
srt: "srt",
|
|
24
|
+
vtt: "vtt",
|
|
25
|
+
lrc: "lrc",
|
|
26
|
+
elrc: "elrc",
|
|
27
|
+
ass: "ass",
|
|
28
|
+
ssa: "ssa",
|
|
29
|
+
ttml: "ttml",
|
|
30
|
+
dfxp: "ttml"
|
|
31
|
+
}, B = (s) => {
|
|
32
|
+
var l;
|
|
33
|
+
const t = ((l = s.split(".").pop()) == null ? void 0 : l.toLowerCase()) || "";
|
|
34
|
+
return T[t];
|
|
35
|
+
};
|
|
36
|
+
S(() => v.url, async () => {
|
|
37
|
+
p.value = !0, i.value = null;
|
|
38
|
+
try {
|
|
39
|
+
f.value = await D(v.url, { fetcher: N.value });
|
|
40
|
+
} catch (s) {
|
|
41
|
+
console.error(s), i.value = u.value("subtitle.load_failed");
|
|
42
|
+
} finally {
|
|
43
|
+
p.value = !1;
|
|
44
|
+
}
|
|
45
|
+
}, { immediate: !0 });
|
|
46
|
+
const n = y(() => {
|
|
47
|
+
if (!f.value) return null;
|
|
48
|
+
try {
|
|
49
|
+
return A(f.value, B(v.fileName));
|
|
50
|
+
} catch (s) {
|
|
51
|
+
return console.error(s), null;
|
|
52
|
+
}
|
|
53
|
+
}), _ = y(() => {
|
|
54
|
+
var s, t;
|
|
55
|
+
return ((s = n.value) == null ? void 0 : s.format) === "lrc" || ((t = n.value) == null ? void 0 : t.format) === "elrc";
|
|
56
|
+
}), w = y(() => {
|
|
57
|
+
var s;
|
|
58
|
+
return ((s = n.value) == null ? void 0 : s.metadata) ?? {};
|
|
59
|
+
}), E = (s) => d(s).slice(3, 8);
|
|
60
|
+
return (s, t) => p.value ? (a(), r("div", M, [...t[0] || (t[0] = [
|
|
61
|
+
e("div", { class: "vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin" }, null, -1)
|
|
62
|
+
])])) : i.value || !n.value ? (a(), r("div", O, [
|
|
63
|
+
e("div", R, [
|
|
64
|
+
e("p", X, o(i.value || c(u)("subtitle.parse_failed")), 1)
|
|
65
|
+
])
|
|
66
|
+
])) : (a(), r("div", {
|
|
67
|
+
key: 2,
|
|
68
|
+
class: b(["vfp-relative vfp-w-full vfp-h-full vfp-bg-[#0f0f12]", _.value ? "flavor-lyric" : "flavor-subtitle"])
|
|
69
|
+
}, [
|
|
70
|
+
e("div", Y, [
|
|
71
|
+
e("div", q, [
|
|
72
|
+
t[3] || (t[3] = e("div", { class: "timeline-line" }, null, -1)),
|
|
73
|
+
e("ol", G, [
|
|
74
|
+
(a(!0), r(x, null, k(n.value.cues, (l, g) => (a(), r("li", {
|
|
75
|
+
key: "cue-" + g,
|
|
76
|
+
class: "cue-row"
|
|
77
|
+
}, [
|
|
78
|
+
t[2] || (t[2] = e("div", { class: "cue-dot" }, null, -1)),
|
|
79
|
+
e("div", H, [
|
|
80
|
+
e("span", J, o(c(d)(l.start)), 1),
|
|
81
|
+
t[1] || (t[1] = e("span", { class: "cue-arrow" }, "→", -1)),
|
|
82
|
+
e("span", K, o(c(d)(l.end)), 1),
|
|
83
|
+
e("span", P, "#" + o(l.id ?? g + 1), 1),
|
|
84
|
+
l.style ? (a(), r("span", Q, o(l.style), 1)) : C("", !0)
|
|
85
|
+
]),
|
|
86
|
+
l.words && l.words.length > 0 ? (a(), r("div", U, [
|
|
87
|
+
(a(!0), r(x, null, k(l.words, (m, L) => (a(), r("span", {
|
|
88
|
+
key: "w-" + L,
|
|
89
|
+
class: "cue-word",
|
|
90
|
+
title: c(d)(m.start)
|
|
91
|
+
}, [
|
|
92
|
+
e("span", Z, o(E(m.start)), 1),
|
|
93
|
+
e("span", $, o(m.text), 1)
|
|
94
|
+
], 8, W))), 128))
|
|
95
|
+
])) : (a(), r("p", {
|
|
96
|
+
key: 1,
|
|
97
|
+
class: b(["cue-text", { lyric: _.value }])
|
|
98
|
+
}, o(l.text), 3))
|
|
99
|
+
]))), 128))
|
|
100
|
+
])
|
|
101
|
+
])
|
|
102
|
+
]),
|
|
103
|
+
e("div", ee, [
|
|
104
|
+
e("span", null, o(n.value.cues.length) + " " + o(_.value ? c(u)("subtitle.lines") : c(u)("subtitle.cues")), 1),
|
|
105
|
+
w.value.length ? (a(), r(x, { key: 0 }, [
|
|
106
|
+
t[4] || (t[4] = e("span", { class: "dot" }, "·", -1)),
|
|
107
|
+
e("span", null, o(w.value.length), 1)
|
|
108
|
+
], 64)) : C("", !0)
|
|
109
|
+
])
|
|
110
|
+
], 2));
|
|
111
|
+
}
|
|
112
|
+
}), re = /* @__PURE__ */ I(te, [["__scopeId", "data-v-20d6aab5"]]);
|
|
113
|
+
export {
|
|
114
|
+
re as default
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=index-BD0HLPzh.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-BD0HLPzh.mjs","sources":["../../src/renderers/Subtitle/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, watch } from 'vue';\nimport {\n parseSubtitle,\n formatSubtitleTime,\n fetchTextUtf8,\n type SubtitleParseResult,\n type SubtitleFormat,\n} from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\nimport { useFetcher } from '../../composables/useRequest';\n\nconst props = defineProps<{\n url: string;\n fileName: string;\n}>();\n\nconst { t } = useTranslator();\nconst fetcher = useFetcher();\n\nconst text = ref<string>('');\nconst loading = ref(true);\nconst error = ref<string | null>(null);\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\nconst load = async () => {\n loading.value = true;\n error.value = null;\n try {\n text.value = await fetchTextUtf8(props.url, { fetcher: fetcher.value });\n } catch (err) {\n console.error(err);\n error.value = t.value('subtitle.load_failed');\n } finally {\n loading.value = false;\n }\n};\n\nwatch(() => props.url, load, { immediate: true });\n\nconst parsed = computed<SubtitleParseResult | null>(() => {\n if (!text.value) return null;\n try {\n return parseSubtitle(text.value, getFormat(props.fileName));\n } catch (err) {\n console.error(err);\n return null;\n }\n});\n\nconst isLyric = computed(() => parsed.value?.format === 'lrc' || parsed.value?.format === 'elrc');\n\nconst meta = computed<Record<string, string>>(() => parsed.value?.metadata ?? {});\n\nconst wordTimeShort = (t: number) => formatSubtitleTime(t).slice(3, 8);\n</script>\n\n<template>\n <div\n v-if=\"loading\"\n class=\"vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-bg-[#0f0f12]\"\n >\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <div\n v-else-if=\"error || !parsed\"\n class=\"vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-bg-[#0f0f12]\"\n >\n <div class=\"vfp-text-fg-secondary vfp-text-center\">\n <p class=\"vfp-text-lg\">{{ error || t('subtitle.parse_failed') }}</p>\n </div>\n </div>\n\n <div\n v-else\n class=\"vfp-relative vfp-w-full vfp-h-full vfp-bg-[#0f0f12]\"\n :class=\"isLyric ? 'flavor-lyric' : 'flavor-subtitle'\"\n >\n <!-- 内容滚动区 -->\n <div class=\"content-scroll\">\n <div class=\"timeline\">\n <div class=\"timeline-line\" />\n <ol class=\"cues\">\n <li v-for=\"(cue, i) in parsed.cues\" :key=\"'cue-' + i\" class=\"cue-row\">\n <div class=\"cue-dot\" />\n <div class=\"cue-meta\">\n <span class=\"cue-time\">{{ formatSubtitleTime(cue.start) }}</span>\n <span class=\"cue-arrow\">→</span>\n <span class=\"cue-time\">{{ formatSubtitleTime(cue.end) }}</span>\n <span class=\"cue-id\">#{{ cue.id ?? i + 1 }}</span>\n <span v-if=\"cue.style\" class=\"cue-style\">{{ cue.style }}</span>\n </div>\n <div v-if=\"cue.words && cue.words.length > 0\" class=\"cue-words\">\n <span\n v-for=\"(word, wi) in cue.words\"\n :key=\"'w-' + wi\"\n class=\"cue-word\"\n :title=\"formatSubtitleTime(word.start)\"\n >\n <span class=\"cue-word-time\">{{ wordTimeShort(word.start) }}</span>\n <span class=\"cue-word-text\">{{ word.text }}</span>\n </span>\n </div>\n <p v-else class=\"cue-text\" :class=\"{ lyric: isLyric }\">{{ cue.text }}</p>\n </li>\n </ol>\n </div>\n </div>\n\n <!-- 右下角浮签 -->\n <div class=\"status-pill\">\n <span>{{ parsed.cues.length }} {{ isLyric ? t('subtitle.lines') : t('subtitle.cues') }}</span>\n <template v-if=\"meta.length\">\n <span class=\"dot\">·</span>\n <span>{{ meta.length }}</span>\n </template>\n </div>\n </div>\n</template>\n\n<style scoped>\n.content-scroll {\n width: 100%;\n height: 100%;\n overflow: auto;\n padding: 1.5rem 1.5rem 4rem;\n}\n@media (min-width: 768px) {\n .content-scroll {\n padding: 1.5rem 2.5rem 5rem;\n }\n}\n.status-pill {\n pointer-events: none;\n position: absolute;\n bottom: 0.75rem;\n right: 0.75rem;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.25rem 0.625rem;\n border-radius: 9999px;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(8px);\n border: 1px solid var(--fp-line);\n font-size: 0.625rem;\n color: var(--fp-fg-tertiary);\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n font-variant-numeric: tabular-nums;\n}\n@media (min-width: 768px) {\n .status-pill {\n bottom: 1rem;\n right: 1rem;\n }\n}\n.dot {\n color: var(--fp-fg-disabled);\n}\n\n.timeline {\n position: relative;\n max-width: 64rem;\n margin: 0 auto;\n}\n.timeline-line {\n position: absolute;\n left: 5px;\n top: 0.5rem;\n bottom: 0.5rem;\n width: 1px;\n background: var(--fp-line-weak);\n}\n@media (min-width: 768px) {\n .timeline-line {\n left: 7px;\n }\n}\n.cues {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 1.25rem;\n}\n@media (min-width: 768px) {\n .cues {\n gap: 1.5rem;\n }\n}\n.cue-row {\n position: relative;\n padding-left: 1.5rem;\n}\n@media (min-width: 768px) {\n .cue-row {\n padding-left: 2rem;\n }\n}\n.cue-dot {\n position: absolute;\n left: 0;\n top: 0.5rem;\n width: 0.75rem;\n height: 0.75rem;\n border-radius: 9999px;\n background: var(--fp-surface-3);\n border: 2px solid #0f0f12;\n transition: background-color 0.2s;\n}\n.flavor-lyric .cue-row:hover .cue-dot {\n background: rgb(167, 139, 250);\n}\n.flavor-subtitle .cue-row:hover .cue-dot {\n background: rgb(56, 189, 248);\n}\n.cue-meta {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 0.25rem 0.75rem;\n margin-bottom: 0.375rem;\n}\n.cue-time {\n font-size: 0.6875rem;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n color: var(--fp-fg-muted);\n font-variant-numeric: tabular-nums;\n}\n.cue-arrow {\n font-size: 0.6875rem;\n color: var(--fp-fg-disabled);\n}\n.cue-id {\n font-size: 0.625rem;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n color: var(--fp-fg-disabled);\n font-variant-numeric: tabular-nums;\n}\n.cue-style {\n font-size: 0.5625rem;\n text-transform: uppercase;\n letter-spacing: 0.1em;\n color: var(--fp-fg-tertiary);\n padding: 0.125rem 0.375rem;\n border-radius: 0.25rem;\n background: var(--fp-line-weak);\n border: 1px solid var(--fp-line);\n}\n.cue-text {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-word;\n line-height: 1.625;\n color: var(--fp-fg-primary);\n font-size: 0.875rem;\n transition: color 0.2s;\n}\n@media (min-width: 768px) {\n .cue-text {\n font-size: 1rem;\n }\n}\n.cue-text.lyric {\n font-size: 1rem;\n font-weight: 500;\n}\n@media (min-width: 768px) {\n .cue-text.lyric {\n font-size: 1.25rem;\n }\n}\n.cue-row:hover .cue-text {\n color: #fff;\n}\n.cue-words {\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem 0.375rem;\n font-size: 1rem;\n color: var(--fp-fg-primary);\n line-height: 1.625;\n transition: color 0.2s;\n}\n@media (min-width: 768px) {\n .cue-words {\n font-size: 1.125rem;\n }\n}\n.cue-row:hover .cue-words {\n color: #fff;\n}\n.cue-word {\n display: inline-flex;\n flex-direction: column;\n align-items: flex-start;\n}\n.cue-word-time {\n font-size: 0.5625rem;\n color: var(--fp-fg-disabled);\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n line-height: 1;\n font-variant-numeric: tabular-nums;\n}\n.cue-word-text {\n line-height: 1.4;\n}\n</style>\n"],"names":["props","__props","t","useTranslator","fetcher","useFetcher","text","ref","loading","error","FORMAT_BY_EXT","getFormat","fileName","ext","_a","watch","fetchTextUtf8","err","parsed","computed","parseSubtitle","isLyric","_b","meta","wordTimeShort","formatSubtitleTime","_openBlock","_createElementBlock","_hoisted_1","_cache","_createElementVNode","_hoisted_2","_hoisted_3","_hoisted_4","_toDisplayString","_unref","_normalizeClass","_hoisted_5","_hoisted_6","_hoisted_7","_Fragment","cue","i","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","word","wi","_hoisted_15","_hoisted_16","_hoisted_17"],"mappings":"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"}
|