@huyooo/file-explorer-bridge-electron 0.3.0 → 0.4.3

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.
@@ -56,7 +56,53 @@ function createFileExplorerAPI() {
56
56
  };
57
57
  import_electron.ipcRenderer.on(channel("searchResults"), handler);
58
58
  return () => import_electron.ipcRenderer.removeListener(channel("searchResults"), handler);
59
- }
59
+ },
60
+ compressFiles: (sources, options) => import_electron.ipcRenderer.invoke(channel("compressFiles"), sources, options),
61
+ extractArchive: (archivePath, options) => import_electron.ipcRenderer.invoke(channel("extractArchive"), archivePath, options),
62
+ isArchiveFile: (filePath) => import_electron.ipcRenderer.invoke(channel("isArchiveFile"), filePath),
63
+ onCompressProgress: (callback) => {
64
+ const handler = (_event, data) => {
65
+ callback(data);
66
+ };
67
+ import_electron.ipcRenderer.on(channel("compressProgress"), handler);
68
+ return () => import_electron.ipcRenderer.removeListener(channel("compressProgress"), handler);
69
+ },
70
+ onExtractProgress: (callback) => {
71
+ const handler = (_event, data) => {
72
+ callback(data);
73
+ };
74
+ import_electron.ipcRenderer.on(channel("extractProgress"), handler);
75
+ return () => import_electron.ipcRenderer.removeListener(channel("extractProgress"), handler);
76
+ },
77
+ watchDirectory: (dirPath, watchId) => import_electron.ipcRenderer.invoke(channel("watchDirectory"), dirPath, watchId),
78
+ unwatchDirectory: (watchId) => import_electron.ipcRenderer.invoke(channel("unwatchDirectory"), watchId),
79
+ onWatchEvent: (callback) => {
80
+ const handler = (_event, data) => {
81
+ callback(data);
82
+ };
83
+ import_electron.ipcRenderer.on(channel("watchEvent"), handler);
84
+ return () => import_electron.ipcRenderer.removeListener(channel("watchEvent"), handler);
85
+ },
86
+ showFileInfo: (filePath) => import_electron.ipcRenderer.invoke(channel("showFileInfo"), filePath),
87
+ openInTerminal: (dirPath) => import_electron.ipcRenderer.invoke(channel("openInTerminal"), dirPath),
88
+ openInEditor: (targetPath) => import_electron.ipcRenderer.invoke(channel("openInEditor"), targetPath),
89
+ openInNewWindow: (folderPath) => import_electron.ipcRenderer.invoke(channel("openInNewWindow"), folderPath),
90
+ requestWindowFocus: () => import_electron.ipcRenderer.send(channel("requestWindowFocus")),
91
+ // ===== 媒体服务 API =====
92
+ mediaNeedsTranscode: (filePath) => import_electron.ipcRenderer.invoke(channel("mediaNeedsTranscode"), filePath),
93
+ mediaGetPlayableUrl: (filePath) => import_electron.ipcRenderer.invoke(channel("mediaGetPlayableUrl"), filePath),
94
+ mediaGetMetadata: (filePath) => import_electron.ipcRenderer.invoke(channel("mediaGetMetadata"), filePath),
95
+ onMediaTranscodeProgress: (callback) => {
96
+ const handler = (_event, data) => {
97
+ callback(data);
98
+ };
99
+ import_electron.ipcRenderer.on(channel("mediaTranscodeProgress"), handler);
100
+ return () => import_electron.ipcRenderer.removeListener(channel("mediaTranscodeProgress"), handler);
101
+ },
102
+ mediaCleanupFile: (filePath) => import_electron.ipcRenderer.invoke(channel("mediaCleanupFile"), filePath),
103
+ // ===== 媒体预览窗口 API =====
104
+ openMediaPreviewWindow: (filePath, mediaType) => import_electron.ipcRenderer.invoke(channel("openMediaPreviewWindow"), filePath, mediaType),
105
+ closeMediaPreviewWindow: (filePath) => import_electron.ipcRenderer.invoke(channel("closeMediaPreviewWindow"), filePath)
60
106
  };
61
107
  }
62
108
  function exposeFileExplorerAPI(apiName = "fileExplorerAPI") {
@@ -126,6 +126,139 @@ interface FileExplorerAPI {
126
126
  items: unknown[];
127
127
  done: boolean;
128
128
  }) => void) => () => void;
129
+ /** 压缩文件 */
130
+ compressFiles: (sources: string[], options: {
131
+ format: 'zip' | 'tar' | 'tgz' | 'tarbz2';
132
+ level?: 'fast' | 'normal' | 'best';
133
+ outputName: string;
134
+ outputDir: string;
135
+ deleteSource?: boolean;
136
+ }) => Promise<{
137
+ success: boolean;
138
+ outputPath?: string;
139
+ error?: string;
140
+ }>;
141
+ /** 解压文件 */
142
+ extractArchive: (archivePath: string, options: {
143
+ targetDir: string;
144
+ deleteArchive?: boolean;
145
+ }) => Promise<{
146
+ success: boolean;
147
+ outputPath?: string;
148
+ error?: string;
149
+ }>;
150
+ /** 判断是否为压缩文件 */
151
+ isArchiveFile: (filePath: string) => Promise<boolean>;
152
+ /** 监听压缩进度 */
153
+ onCompressProgress: (callback: (data: {
154
+ currentFile: string;
155
+ processedCount: number;
156
+ totalCount: number;
157
+ percent: number;
158
+ }) => void) => () => void;
159
+ /** 监听解压进度 */
160
+ onExtractProgress: (callback: (data: {
161
+ currentFile: string;
162
+ processedCount: number;
163
+ totalCount: number;
164
+ percent: number;
165
+ }) => void) => () => void;
166
+ /** 监听目录变化 */
167
+ watchDirectory: (dirPath: string, watchId: string) => Promise<{
168
+ success: boolean;
169
+ error?: string;
170
+ }>;
171
+ /** 停止监听目录 */
172
+ unwatchDirectory: (watchId: string) => Promise<{
173
+ success: boolean;
174
+ }>;
175
+ /** 监听文件变化事件 */
176
+ onWatchEvent: (callback: (data: {
177
+ watchId: string;
178
+ event: {
179
+ type: 'add' | 'change' | 'remove' | 'rename';
180
+ path: string;
181
+ filename: string;
182
+ };
183
+ }) => void) => () => void;
184
+ /** 显示文件/文件夹的系统属性窗口 */
185
+ showFileInfo: (filePath: string) => Promise<{
186
+ success: boolean;
187
+ error?: string;
188
+ }>;
189
+ /** 在终端中打开目录 */
190
+ openInTerminal: (dirPath: string) => Promise<{
191
+ success: boolean;
192
+ error?: string;
193
+ }>;
194
+ /** 通过 Cursor 打开 */
195
+ openInEditor: (targetPath: string) => Promise<{
196
+ success: boolean;
197
+ error?: string;
198
+ }>;
199
+ /** 在新窗口中打开文件夹(使用系统文件管理器) */
200
+ openInNewWindow: (folderPath: string) => Promise<{
201
+ success: boolean;
202
+ error?: string;
203
+ }>;
204
+ /** 请求窗口聚焦(用于右键打开菜单前激活窗口) */
205
+ requestWindowFocus: () => void;
206
+ /** 检测媒体文件是否需要转码 */
207
+ mediaNeedsTranscode: (filePath: string) => Promise<{
208
+ success: boolean;
209
+ data?: {
210
+ type: 'video' | 'audio';
211
+ needsTranscode: boolean;
212
+ method: 'direct' | 'remux' | 'transcode';
213
+ estimatedTime?: number;
214
+ targetFormat?: string;
215
+ };
216
+ error?: string;
217
+ }>;
218
+ /** 获取可播放的媒体 URL(自动转码) */
219
+ mediaGetPlayableUrl: (filePath: string) => Promise<{
220
+ success: boolean;
221
+ url?: string;
222
+ error?: string;
223
+ }>;
224
+ /** 获取媒体元数据 */
225
+ mediaGetMetadata: (filePath: string) => Promise<{
226
+ success: boolean;
227
+ data?: {
228
+ filePath: string;
229
+ type: 'video' | 'audio';
230
+ duration: number;
231
+ title?: string;
232
+ artist?: string;
233
+ album?: string;
234
+ };
235
+ error?: string;
236
+ }>;
237
+ /** 监听转码进度 */
238
+ onMediaTranscodeProgress: (callback: (data: {
239
+ filePath: string;
240
+ progress: {
241
+ percent: number;
242
+ time?: number;
243
+ duration?: number;
244
+ speed?: string;
245
+ };
246
+ }) => void) => () => void;
247
+ /** 清理指定文件的转码缓存 */
248
+ mediaCleanupFile: (filePath: string) => Promise<{
249
+ success: boolean;
250
+ error?: string;
251
+ }>;
252
+ /** 打开媒体预览窗口 */
253
+ openMediaPreviewWindow: (filePath: string, mediaType: 'image' | 'video' | 'audio') => Promise<{
254
+ success: boolean;
255
+ error?: string;
256
+ }>;
257
+ /** 关闭媒体预览窗口 */
258
+ closeMediaPreviewWindow: (filePath: string) => Promise<{
259
+ success: boolean;
260
+ error?: string;
261
+ }>;
129
262
  }
130
263
  /**
131
264
  * 创建文件操作 API
@@ -126,6 +126,139 @@ interface FileExplorerAPI {
126
126
  items: unknown[];
127
127
  done: boolean;
128
128
  }) => void) => () => void;
129
+ /** 压缩文件 */
130
+ compressFiles: (sources: string[], options: {
131
+ format: 'zip' | 'tar' | 'tgz' | 'tarbz2';
132
+ level?: 'fast' | 'normal' | 'best';
133
+ outputName: string;
134
+ outputDir: string;
135
+ deleteSource?: boolean;
136
+ }) => Promise<{
137
+ success: boolean;
138
+ outputPath?: string;
139
+ error?: string;
140
+ }>;
141
+ /** 解压文件 */
142
+ extractArchive: (archivePath: string, options: {
143
+ targetDir: string;
144
+ deleteArchive?: boolean;
145
+ }) => Promise<{
146
+ success: boolean;
147
+ outputPath?: string;
148
+ error?: string;
149
+ }>;
150
+ /** 判断是否为压缩文件 */
151
+ isArchiveFile: (filePath: string) => Promise<boolean>;
152
+ /** 监听压缩进度 */
153
+ onCompressProgress: (callback: (data: {
154
+ currentFile: string;
155
+ processedCount: number;
156
+ totalCount: number;
157
+ percent: number;
158
+ }) => void) => () => void;
159
+ /** 监听解压进度 */
160
+ onExtractProgress: (callback: (data: {
161
+ currentFile: string;
162
+ processedCount: number;
163
+ totalCount: number;
164
+ percent: number;
165
+ }) => void) => () => void;
166
+ /** 监听目录变化 */
167
+ watchDirectory: (dirPath: string, watchId: string) => Promise<{
168
+ success: boolean;
169
+ error?: string;
170
+ }>;
171
+ /** 停止监听目录 */
172
+ unwatchDirectory: (watchId: string) => Promise<{
173
+ success: boolean;
174
+ }>;
175
+ /** 监听文件变化事件 */
176
+ onWatchEvent: (callback: (data: {
177
+ watchId: string;
178
+ event: {
179
+ type: 'add' | 'change' | 'remove' | 'rename';
180
+ path: string;
181
+ filename: string;
182
+ };
183
+ }) => void) => () => void;
184
+ /** 显示文件/文件夹的系统属性窗口 */
185
+ showFileInfo: (filePath: string) => Promise<{
186
+ success: boolean;
187
+ error?: string;
188
+ }>;
189
+ /** 在终端中打开目录 */
190
+ openInTerminal: (dirPath: string) => Promise<{
191
+ success: boolean;
192
+ error?: string;
193
+ }>;
194
+ /** 通过 Cursor 打开 */
195
+ openInEditor: (targetPath: string) => Promise<{
196
+ success: boolean;
197
+ error?: string;
198
+ }>;
199
+ /** 在新窗口中打开文件夹(使用系统文件管理器) */
200
+ openInNewWindow: (folderPath: string) => Promise<{
201
+ success: boolean;
202
+ error?: string;
203
+ }>;
204
+ /** 请求窗口聚焦(用于右键打开菜单前激活窗口) */
205
+ requestWindowFocus: () => void;
206
+ /** 检测媒体文件是否需要转码 */
207
+ mediaNeedsTranscode: (filePath: string) => Promise<{
208
+ success: boolean;
209
+ data?: {
210
+ type: 'video' | 'audio';
211
+ needsTranscode: boolean;
212
+ method: 'direct' | 'remux' | 'transcode';
213
+ estimatedTime?: number;
214
+ targetFormat?: string;
215
+ };
216
+ error?: string;
217
+ }>;
218
+ /** 获取可播放的媒体 URL(自动转码) */
219
+ mediaGetPlayableUrl: (filePath: string) => Promise<{
220
+ success: boolean;
221
+ url?: string;
222
+ error?: string;
223
+ }>;
224
+ /** 获取媒体元数据 */
225
+ mediaGetMetadata: (filePath: string) => Promise<{
226
+ success: boolean;
227
+ data?: {
228
+ filePath: string;
229
+ type: 'video' | 'audio';
230
+ duration: number;
231
+ title?: string;
232
+ artist?: string;
233
+ album?: string;
234
+ };
235
+ error?: string;
236
+ }>;
237
+ /** 监听转码进度 */
238
+ onMediaTranscodeProgress: (callback: (data: {
239
+ filePath: string;
240
+ progress: {
241
+ percent: number;
242
+ time?: number;
243
+ duration?: number;
244
+ speed?: string;
245
+ };
246
+ }) => void) => () => void;
247
+ /** 清理指定文件的转码缓存 */
248
+ mediaCleanupFile: (filePath: string) => Promise<{
249
+ success: boolean;
250
+ error?: string;
251
+ }>;
252
+ /** 打开媒体预览窗口 */
253
+ openMediaPreviewWindow: (filePath: string, mediaType: 'image' | 'video' | 'audio') => Promise<{
254
+ success: boolean;
255
+ error?: string;
256
+ }>;
257
+ /** 关闭媒体预览窗口 */
258
+ closeMediaPreviewWindow: (filePath: string) => Promise<{
259
+ success: boolean;
260
+ error?: string;
261
+ }>;
129
262
  }
130
263
  /**
131
264
  * 创建文件操作 API
@@ -31,7 +31,53 @@ function createFileExplorerAPI() {
31
31
  };
32
32
  ipcRenderer.on(channel("searchResults"), handler);
33
33
  return () => ipcRenderer.removeListener(channel("searchResults"), handler);
34
- }
34
+ },
35
+ compressFiles: (sources, options) => ipcRenderer.invoke(channel("compressFiles"), sources, options),
36
+ extractArchive: (archivePath, options) => ipcRenderer.invoke(channel("extractArchive"), archivePath, options),
37
+ isArchiveFile: (filePath) => ipcRenderer.invoke(channel("isArchiveFile"), filePath),
38
+ onCompressProgress: (callback) => {
39
+ const handler = (_event, data) => {
40
+ callback(data);
41
+ };
42
+ ipcRenderer.on(channel("compressProgress"), handler);
43
+ return () => ipcRenderer.removeListener(channel("compressProgress"), handler);
44
+ },
45
+ onExtractProgress: (callback) => {
46
+ const handler = (_event, data) => {
47
+ callback(data);
48
+ };
49
+ ipcRenderer.on(channel("extractProgress"), handler);
50
+ return () => ipcRenderer.removeListener(channel("extractProgress"), handler);
51
+ },
52
+ watchDirectory: (dirPath, watchId) => ipcRenderer.invoke(channel("watchDirectory"), dirPath, watchId),
53
+ unwatchDirectory: (watchId) => ipcRenderer.invoke(channel("unwatchDirectory"), watchId),
54
+ onWatchEvent: (callback) => {
55
+ const handler = (_event, data) => {
56
+ callback(data);
57
+ };
58
+ ipcRenderer.on(channel("watchEvent"), handler);
59
+ return () => ipcRenderer.removeListener(channel("watchEvent"), handler);
60
+ },
61
+ showFileInfo: (filePath) => ipcRenderer.invoke(channel("showFileInfo"), filePath),
62
+ openInTerminal: (dirPath) => ipcRenderer.invoke(channel("openInTerminal"), dirPath),
63
+ openInEditor: (targetPath) => ipcRenderer.invoke(channel("openInEditor"), targetPath),
64
+ openInNewWindow: (folderPath) => ipcRenderer.invoke(channel("openInNewWindow"), folderPath),
65
+ requestWindowFocus: () => ipcRenderer.send(channel("requestWindowFocus")),
66
+ // ===== 媒体服务 API =====
67
+ mediaNeedsTranscode: (filePath) => ipcRenderer.invoke(channel("mediaNeedsTranscode"), filePath),
68
+ mediaGetPlayableUrl: (filePath) => ipcRenderer.invoke(channel("mediaGetPlayableUrl"), filePath),
69
+ mediaGetMetadata: (filePath) => ipcRenderer.invoke(channel("mediaGetMetadata"), filePath),
70
+ onMediaTranscodeProgress: (callback) => {
71
+ const handler = (_event, data) => {
72
+ callback(data);
73
+ };
74
+ ipcRenderer.on(channel("mediaTranscodeProgress"), handler);
75
+ return () => ipcRenderer.removeListener(channel("mediaTranscodeProgress"), handler);
76
+ },
77
+ mediaCleanupFile: (filePath) => ipcRenderer.invoke(channel("mediaCleanupFile"), filePath),
78
+ // ===== 媒体预览窗口 API =====
79
+ openMediaPreviewWindow: (filePath, mediaType) => ipcRenderer.invoke(channel("openMediaPreviewWindow"), filePath, mediaType),
80
+ closeMediaPreviewWindow: (filePath) => ipcRenderer.invoke(channel("closeMediaPreviewWindow"), filePath)
35
81
  };
36
82
  }
37
83
  function exposeFileExplorerAPI(apiName = "fileExplorerAPI") {
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/preload/preview.ts
21
+ var preview_exports = {};
22
+ __export(preview_exports, {
23
+ exposePreviewWindowAPI: () => exposePreviewWindowAPI
24
+ });
25
+ module.exports = __toCommonJS(preview_exports);
26
+ var import_electron = require("electron");
27
+ var CHANNEL_PREFIX = "file-explorer-preview";
28
+ var channel = (name) => `${CHANNEL_PREFIX}:${name}`;
29
+ function createPreviewWindowAPI() {
30
+ return {
31
+ minimizeWindow: () => import_electron.ipcRenderer.send(channel("minimize")),
32
+ toggleMaximizeWindow: () => import_electron.ipcRenderer.send(channel("toggleMaximize")),
33
+ closeWindow: () => import_electron.ipcRenderer.send(channel("close")),
34
+ hideWindow: () => import_electron.ipcRenderer.send(channel("hide")),
35
+ showWindow: () => import_electron.ipcRenderer.send(channel("show")),
36
+ onMaximizeChange: (callback) => {
37
+ const handler = (_event, isMaximized) => {
38
+ callback(isMaximized);
39
+ };
40
+ import_electron.ipcRenderer.on(channel("maximizeChange"), handler);
41
+ return () => import_electron.ipcRenderer.removeListener(channel("maximizeChange"), handler);
42
+ }
43
+ };
44
+ }
45
+ function exposePreviewWindowAPI() {
46
+ const api = createPreviewWindowAPI();
47
+ import_electron.contextBridge.exposeInMainWorld("electronAPI", api);
48
+ console.log("\u2705 Preview Window API exposed as window.electronAPI");
49
+ }
50
+ exposePreviewWindowAPI();
51
+ // Annotate the CommonJS export names for ESM import in node:
52
+ 0 && (module.exports = {
53
+ exposePreviewWindowAPI
54
+ });
@@ -0,0 +1,28 @@
1
+ /**
2
+ * File Explorer Electron Bridge - Preview Window Preload Script
3
+ *
4
+ * 专门用于预览窗口的 preload 脚本,提供窗口控制 API
5
+ */
6
+ /**
7
+ * 预览窗口 API 类型
8
+ */
9
+ interface PreviewWindowAPI {
10
+ /** 最小化窗口 */
11
+ minimizeWindow: () => void;
12
+ /** 切换最大化/还原 */
13
+ toggleMaximizeWindow: () => void;
14
+ /** 关闭窗口 */
15
+ closeWindow: () => void;
16
+ /** 隐藏窗口 */
17
+ hideWindow: () => void;
18
+ /** 显示窗口 */
19
+ showWindow: () => void;
20
+ /** 监听窗口最大化状态变化 */
21
+ onMaximizeChange: (callback: (isMaximized: boolean) => void) => () => void;
22
+ }
23
+ /**
24
+ * 暴露预览窗口 API
25
+ */
26
+ declare function exposePreviewWindowAPI(): void;
27
+
28
+ export { type PreviewWindowAPI, exposePreviewWindowAPI };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * File Explorer Electron Bridge - Preview Window Preload Script
3
+ *
4
+ * 专门用于预览窗口的 preload 脚本,提供窗口控制 API
5
+ */
6
+ /**
7
+ * 预览窗口 API 类型
8
+ */
9
+ interface PreviewWindowAPI {
10
+ /** 最小化窗口 */
11
+ minimizeWindow: () => void;
12
+ /** 切换最大化/还原 */
13
+ toggleMaximizeWindow: () => void;
14
+ /** 关闭窗口 */
15
+ closeWindow: () => void;
16
+ /** 隐藏窗口 */
17
+ hideWindow: () => void;
18
+ /** 显示窗口 */
19
+ showWindow: () => void;
20
+ /** 监听窗口最大化状态变化 */
21
+ onMaximizeChange: (callback: (isMaximized: boolean) => void) => () => void;
22
+ }
23
+ /**
24
+ * 暴露预览窗口 API
25
+ */
26
+ declare function exposePreviewWindowAPI(): void;
27
+
28
+ export { type PreviewWindowAPI, exposePreviewWindowAPI };
@@ -0,0 +1,29 @@
1
+ // src/preload/preview.ts
2
+ import { contextBridge, ipcRenderer } from "electron";
3
+ var CHANNEL_PREFIX = "file-explorer-preview";
4
+ var channel = (name) => `${CHANNEL_PREFIX}:${name}`;
5
+ function createPreviewWindowAPI() {
6
+ return {
7
+ minimizeWindow: () => ipcRenderer.send(channel("minimize")),
8
+ toggleMaximizeWindow: () => ipcRenderer.send(channel("toggleMaximize")),
9
+ closeWindow: () => ipcRenderer.send(channel("close")),
10
+ hideWindow: () => ipcRenderer.send(channel("hide")),
11
+ showWindow: () => ipcRenderer.send(channel("show")),
12
+ onMaximizeChange: (callback) => {
13
+ const handler = (_event, isMaximized) => {
14
+ callback(isMaximized);
15
+ };
16
+ ipcRenderer.on(channel("maximizeChange"), handler);
17
+ return () => ipcRenderer.removeListener(channel("maximizeChange"), handler);
18
+ }
19
+ };
20
+ }
21
+ function exposePreviewWindowAPI() {
22
+ const api = createPreviewWindowAPI();
23
+ contextBridge.exposeInMainWorld("electronAPI", api);
24
+ console.log("\u2705 Preview Window API exposed as window.electronAPI");
25
+ }
26
+ exposePreviewWindowAPI();
27
+ export {
28
+ exposePreviewWindowAPI
29
+ };
@@ -52,6 +52,28 @@ function createElectronAdapter() {
52
52
  pasteFiles: (targetDir, sourcePaths) => api.pasteFiles(targetDir, sourcePaths),
53
53
  searchFiles: (searchPath, pattern, maxDepth) => api.searchFiles(searchPath, pattern, maxDepth),
54
54
  searchFilesStream: (searchPath, pattern, searchId) => api.searchFilesStream(searchPath, pattern, searchId),
55
- onSearchResults: (callback) => api.onSearchResults(callback)
55
+ onSearchResults: (callback) => api.onSearchResults(callback),
56
+ compressFiles: (sources, options) => api.compressFiles(sources, options),
57
+ extractArchive: (archivePath, options) => api.extractArchive(archivePath, options),
58
+ isArchiveFile: (filePath) => api.isArchiveFile(filePath),
59
+ onCompressProgress: (callback) => api.onCompressProgress(callback),
60
+ onExtractProgress: (callback) => api.onExtractProgress(callback),
61
+ watchDirectory: (dirPath, watchId) => api.watchDirectory(dirPath, watchId),
62
+ unwatchDirectory: (watchId) => api.unwatchDirectory(watchId),
63
+ onWatchEvent: (callback) => api.onWatchEvent(callback),
64
+ showFileInfo: (filePath) => api.showFileInfo(filePath),
65
+ openInTerminal: (dirPath) => api.openInTerminal(dirPath),
66
+ openInEditor: (targetPath) => api.openInEditor(targetPath),
67
+ openInNewWindow: (folderPath) => api.openInNewWindow(folderPath),
68
+ requestWindowFocus: () => api.requestWindowFocus(),
69
+ // 媒体服务
70
+ mediaNeedsTranscode: (filePath) => api.mediaNeedsTranscode(filePath),
71
+ mediaGetPlayableUrl: (filePath) => api.mediaGetPlayableUrl(filePath),
72
+ mediaGetMetadata: (filePath) => api.mediaGetMetadata(filePath),
73
+ onMediaTranscodeProgress: (callback) => api.onMediaTranscodeProgress(callback),
74
+ mediaCleanupFile: (filePath) => api.mediaCleanupFile(filePath),
75
+ // 媒体预览窗口
76
+ openMediaPreviewWindow: (filePath, mediaType) => api.openMediaPreviewWindow(filePath, mediaType),
77
+ closeMediaPreviewWindow: (filePath) => api.closeMediaPreviewWindow(filePath)
56
78
  };
57
79
  }