@huyooo/file-explorer-bridge-electron 0.4.18 → 0.4.21
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/main/index.js +1 -522
- package/dist/preload/index.js +1 -92
- package/dist/preload/preview.cjs +1 -54
- package/dist/renderer/index.js +1 -14
- package/package.json +5 -4
package/dist/main/index.js
CHANGED
|
@@ -1,522 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { ipcMain, shell, BrowserWindow } from "electron";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import { fileURLToPath } from "url";
|
|
5
|
-
import fsSync from "fs";
|
|
6
|
-
import {
|
|
7
|
-
readDirectory,
|
|
8
|
-
readFileContent,
|
|
9
|
-
readImageAsBase64,
|
|
10
|
-
writeFileContent,
|
|
11
|
-
createFolder,
|
|
12
|
-
createFile,
|
|
13
|
-
deleteFiles,
|
|
14
|
-
renameFile,
|
|
15
|
-
copyFiles,
|
|
16
|
-
moveFiles,
|
|
17
|
-
getFileInfo,
|
|
18
|
-
getSystemPath,
|
|
19
|
-
getThumbnailService,
|
|
20
|
-
getApplicationIcon,
|
|
21
|
-
copyFilesToClipboard,
|
|
22
|
-
getClipboardFiles,
|
|
23
|
-
pasteFiles,
|
|
24
|
-
searchFiles,
|
|
25
|
-
searchFilesStream,
|
|
26
|
-
compressFiles,
|
|
27
|
-
extractArchive,
|
|
28
|
-
isArchiveFile,
|
|
29
|
-
getWatchManager,
|
|
30
|
-
showFileInfo,
|
|
31
|
-
openInTerminal,
|
|
32
|
-
openInEditor,
|
|
33
|
-
getFileType,
|
|
34
|
-
formatFileSize,
|
|
35
|
-
formatDateTime,
|
|
36
|
-
encodeFileUrl,
|
|
37
|
-
getMediaService
|
|
38
|
-
} from "@huyooo/file-explorer-core";
|
|
39
|
-
import { promises as fs } from "fs";
|
|
40
|
-
import { getPreviewHtmlPath } from "@huyooo/file-explorer-preview/path";
|
|
41
|
-
var DEFAULT_CHANNEL_PREFIX = "file-explorer";
|
|
42
|
-
var DEFAULT_PREVIEW_CHANNEL_PREFIX = "file-explorer-preview";
|
|
43
|
-
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
44
|
-
var clipboardAdapter = null;
|
|
45
|
-
function setClipboardAdapter(adapter) {
|
|
46
|
-
clipboardAdapter = adapter;
|
|
47
|
-
}
|
|
48
|
-
function createElectronAdapter() {
|
|
49
|
-
return {
|
|
50
|
-
trashItem: async (filePath) => {
|
|
51
|
-
await shell.trashItem(filePath);
|
|
52
|
-
},
|
|
53
|
-
openPath: async (filePath) => {
|
|
54
|
-
await shell.openPath(filePath);
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
var electronUrlEncoder = encodeFileUrl;
|
|
59
|
-
var explorerOptions = {};
|
|
60
|
-
var mediaPreviewWindows = /* @__PURE__ */ new Map();
|
|
61
|
-
function registerFileExplorerHandlers(options = {}) {
|
|
62
|
-
explorerOptions = options;
|
|
63
|
-
const channelPrefix = options.channelPrefix || DEFAULT_CHANNEL_PREFIX;
|
|
64
|
-
const previewChannelPrefix = options.previewChannelPrefix || DEFAULT_PREVIEW_CHANNEL_PREFIX;
|
|
65
|
-
const channel = (name) => `${channelPrefix}:${name}`;
|
|
66
|
-
const previewChannel = (name) => `${previewChannelPrefix}:${name}`;
|
|
67
|
-
const adapter = createElectronAdapter();
|
|
68
|
-
ipcMain.handle(channel("readDirectory"), async (_event, dirPath) => {
|
|
69
|
-
const thumbnailService = getThumbnailService();
|
|
70
|
-
return await readDirectory(dirPath, {
|
|
71
|
-
urlEncoder: electronUrlEncoder,
|
|
72
|
-
getThumbnailUrl: thumbnailService ? (filePath) => thumbnailService.getThumbnailUrl(filePath) : void 0
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
ipcMain.handle(channel("readSystemPath"), async (_event, pathId) => {
|
|
76
|
-
const systemPath = getSystemPath(pathId);
|
|
77
|
-
if (!systemPath) return [];
|
|
78
|
-
const thumbnailService = getThumbnailService();
|
|
79
|
-
return await readDirectory(systemPath, {
|
|
80
|
-
urlEncoder: electronUrlEncoder,
|
|
81
|
-
getThumbnailUrl: thumbnailService ? (filePath) => thumbnailService.getThumbnailUrl(filePath) : void 0
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
ipcMain.handle(channel("getSystemPath"), async (_event, pathId) => {
|
|
85
|
-
return getSystemPath(pathId);
|
|
86
|
-
});
|
|
87
|
-
ipcMain.handle(channel("readFileContent"), async (_event, filePath) => {
|
|
88
|
-
return await readFileContent(filePath);
|
|
89
|
-
});
|
|
90
|
-
ipcMain.handle(channel("writeFileContent"), async (_event, filePath, content) => {
|
|
91
|
-
return await writeFileContent(filePath, content);
|
|
92
|
-
});
|
|
93
|
-
ipcMain.handle(channel("createFolder"), async (_event, parentDir, folderName) => {
|
|
94
|
-
const folderPath = path.join(parentDir, folderName);
|
|
95
|
-
return await createFolder(folderPath);
|
|
96
|
-
});
|
|
97
|
-
ipcMain.handle(channel("createFile"), async (_event, parentDir, fileName, content) => {
|
|
98
|
-
const filePath = path.join(parentDir, fileName);
|
|
99
|
-
return await createFile(filePath, content);
|
|
100
|
-
});
|
|
101
|
-
ipcMain.handle(channel("deleteFiles"), async (_event, paths) => {
|
|
102
|
-
const thumbnailService = getThumbnailService();
|
|
103
|
-
return await deleteFiles(paths, {
|
|
104
|
-
adapter,
|
|
105
|
-
useTrash: true,
|
|
106
|
-
onDeleted: (p) => thumbnailService?.deleteThumbnail(p)
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
ipcMain.handle(channel("renameFile"), async (_event, oldPath, newPath) => {
|
|
110
|
-
const thumbnailService = getThumbnailService();
|
|
111
|
-
return await renameFile(oldPath, newPath, {
|
|
112
|
-
onRenamed: (old) => thumbnailService?.deleteThumbnail(old)
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
ipcMain.handle(channel("copyFiles"), async (_event, sourcePaths, targetDir) => {
|
|
116
|
-
return await copyFiles(sourcePaths, targetDir);
|
|
117
|
-
});
|
|
118
|
-
ipcMain.handle(channel("moveFiles"), async (_event, sourcePaths, targetDir) => {
|
|
119
|
-
return await moveFiles(sourcePaths, targetDir);
|
|
120
|
-
});
|
|
121
|
-
ipcMain.handle(channel("getFileInfo"), async (_event, filePath) => {
|
|
122
|
-
return await getFileInfo(filePath);
|
|
123
|
-
});
|
|
124
|
-
ipcMain.handle(channel("readImageAsBase64"), async (_event, imagePath) => {
|
|
125
|
-
return await readImageAsBase64(imagePath);
|
|
126
|
-
});
|
|
127
|
-
ipcMain.handle(channel("openPath"), async (_event, filePath) => {
|
|
128
|
-
try {
|
|
129
|
-
await shell.openPath(filePath);
|
|
130
|
-
return { success: true };
|
|
131
|
-
} catch (error) {
|
|
132
|
-
return { success: false, error: String(error) };
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
ipcMain.handle(channel("getApplicationIcon"), async (_event, appPath) => {
|
|
136
|
-
return await getApplicationIcon(appPath);
|
|
137
|
-
});
|
|
138
|
-
ipcMain.handle(channel("getThumbnailUrl"), async (_event, filePath) => {
|
|
139
|
-
const thumbnailService = getThumbnailService();
|
|
140
|
-
if (!thumbnailService) return null;
|
|
141
|
-
return await thumbnailService.getThumbnailUrl(filePath);
|
|
142
|
-
});
|
|
143
|
-
ipcMain.handle(channel("copyFilesToClipboard"), async (_event, filePaths) => {
|
|
144
|
-
if (!clipboardAdapter) {
|
|
145
|
-
return { success: false, error: "\u526A\u8D34\u677F\u9002\u914D\u5668\u672A\u521D\u59CB\u5316" };
|
|
146
|
-
}
|
|
147
|
-
return await copyFilesToClipboard(filePaths, clipboardAdapter);
|
|
148
|
-
});
|
|
149
|
-
ipcMain.handle(channel("getClipboardFiles"), async () => {
|
|
150
|
-
if (!clipboardAdapter) {
|
|
151
|
-
return { success: false, error: "\u526A\u8D34\u677F\u9002\u914D\u5668\u672A\u521D\u59CB\u5316" };
|
|
152
|
-
}
|
|
153
|
-
return getClipboardFiles(clipboardAdapter);
|
|
154
|
-
});
|
|
155
|
-
ipcMain.handle(channel("pasteFiles"), async (_event, targetDir, sourcePaths) => {
|
|
156
|
-
return await pasteFiles(targetDir, sourcePaths);
|
|
157
|
-
});
|
|
158
|
-
ipcMain.handle(channel("searchFiles"), async (_event, searchPath, pattern, maxDepth) => {
|
|
159
|
-
try {
|
|
160
|
-
const filePaths = await searchFiles(searchPath, pattern, maxDepth);
|
|
161
|
-
const thumbnailService = getThumbnailService();
|
|
162
|
-
const maxResults = 100;
|
|
163
|
-
const results = [];
|
|
164
|
-
for (const filePath of filePaths.slice(0, maxResults)) {
|
|
165
|
-
try {
|
|
166
|
-
const stats = await fs.stat(filePath);
|
|
167
|
-
const fileType = getFileType(filePath, stats);
|
|
168
|
-
const item = {
|
|
169
|
-
id: filePath,
|
|
170
|
-
name: path.basename(filePath),
|
|
171
|
-
type: fileType,
|
|
172
|
-
size: stats.isDirectory() ? void 0 : formatFileSize(stats.size),
|
|
173
|
-
dateModified: formatDateTime(stats.mtime),
|
|
174
|
-
url: electronUrlEncoder(filePath)
|
|
175
|
-
};
|
|
176
|
-
if (thumbnailService) {
|
|
177
|
-
const thumbnailUrl = await thumbnailService.getThumbnailUrl(filePath);
|
|
178
|
-
if (thumbnailUrl) {
|
|
179
|
-
item.thumbnailUrl = thumbnailUrl;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
results.push(item);
|
|
183
|
-
} catch {
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
return { success: true, data: { items: results, total: filePaths.length } };
|
|
187
|
-
} catch (error) {
|
|
188
|
-
return { success: false, error: String(error) };
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
ipcMain.handle(channel("searchFilesStream"), async (event, searchPath, pattern, searchId) => {
|
|
192
|
-
const thumbnailService = getThumbnailService();
|
|
193
|
-
const pathToItem = async (filePath) => {
|
|
194
|
-
try {
|
|
195
|
-
const stats = await fs.stat(filePath);
|
|
196
|
-
const fileType = getFileType(filePath, stats);
|
|
197
|
-
const item = {
|
|
198
|
-
id: filePath,
|
|
199
|
-
name: path.basename(filePath),
|
|
200
|
-
type: fileType,
|
|
201
|
-
size: stats.isDirectory() ? void 0 : formatFileSize(stats.size),
|
|
202
|
-
dateModified: formatDateTime(stats.mtime),
|
|
203
|
-
url: electronUrlEncoder(filePath)
|
|
204
|
-
};
|
|
205
|
-
if (thumbnailService) {
|
|
206
|
-
const thumbnailUrl = await thumbnailService.getThumbnailUrl(filePath);
|
|
207
|
-
if (thumbnailUrl) {
|
|
208
|
-
item.thumbnailUrl = thumbnailUrl;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return item;
|
|
212
|
-
} catch {
|
|
213
|
-
return null;
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
searchFilesStream(searchPath, pattern, async (paths, done) => {
|
|
217
|
-
const items = [];
|
|
218
|
-
for (const p of paths) {
|
|
219
|
-
const item = await pathToItem(p);
|
|
220
|
-
if (item) items.push(item);
|
|
221
|
-
}
|
|
222
|
-
event.sender.send(channel("searchResults"), {
|
|
223
|
-
searchId,
|
|
224
|
-
items,
|
|
225
|
-
done
|
|
226
|
-
});
|
|
227
|
-
}, 100);
|
|
228
|
-
return { success: true };
|
|
229
|
-
});
|
|
230
|
-
ipcMain.handle(channel("compressFiles"), async (event, sources, options2) => {
|
|
231
|
-
try {
|
|
232
|
-
const result = await compressFiles(sources, options2, (progress) => {
|
|
233
|
-
event.sender.send(channel("compressProgress"), progress);
|
|
234
|
-
});
|
|
235
|
-
return result;
|
|
236
|
-
} catch (error) {
|
|
237
|
-
return { success: false, error: String(error) };
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
ipcMain.handle(channel("extractArchive"), async (event, archivePath, options2) => {
|
|
241
|
-
try {
|
|
242
|
-
const result = await extractArchive(archivePath, options2, (progress) => {
|
|
243
|
-
event.sender.send(channel("extractProgress"), progress);
|
|
244
|
-
});
|
|
245
|
-
return result;
|
|
246
|
-
} catch (error) {
|
|
247
|
-
return { success: false, error: String(error) };
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
ipcMain.handle(channel("isArchiveFile"), async (_event, filePath) => {
|
|
251
|
-
return isArchiveFile(filePath);
|
|
252
|
-
});
|
|
253
|
-
const watchUnsubscribers = /* @__PURE__ */ new Map();
|
|
254
|
-
ipcMain.handle(channel("watchDirectory"), async (event, dirPath, watchId) => {
|
|
255
|
-
try {
|
|
256
|
-
const existingUnsubscribe = watchUnsubscribers.get(watchId);
|
|
257
|
-
if (existingUnsubscribe) {
|
|
258
|
-
existingUnsubscribe();
|
|
259
|
-
watchUnsubscribers.delete(watchId);
|
|
260
|
-
}
|
|
261
|
-
const watchManager = getWatchManager();
|
|
262
|
-
const unsubscribe = watchManager.watch(dirPath, (watchEvent) => {
|
|
263
|
-
event.sender.send(channel("watchEvent"), {
|
|
264
|
-
watchId,
|
|
265
|
-
event: watchEvent
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
watchUnsubscribers.set(watchId, unsubscribe);
|
|
269
|
-
return { success: true };
|
|
270
|
-
} catch (error) {
|
|
271
|
-
return { success: false, error: String(error) };
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
ipcMain.handle(channel("unwatchDirectory"), async (_event, watchId) => {
|
|
275
|
-
const unsubscribe = watchUnsubscribers.get(watchId);
|
|
276
|
-
if (unsubscribe) {
|
|
277
|
-
unsubscribe();
|
|
278
|
-
watchUnsubscribers.delete(watchId);
|
|
279
|
-
}
|
|
280
|
-
return { success: true };
|
|
281
|
-
});
|
|
282
|
-
ipcMain.handle(channel("showFileInfo"), async (_event, filePath) => {
|
|
283
|
-
return await showFileInfo(filePath);
|
|
284
|
-
});
|
|
285
|
-
ipcMain.handle(channel("openInTerminal"), async (_event, dirPath) => {
|
|
286
|
-
return await openInTerminal(dirPath);
|
|
287
|
-
});
|
|
288
|
-
ipcMain.handle(channel("openInEditor"), async (_event, targetPath) => {
|
|
289
|
-
return await openInEditor(targetPath);
|
|
290
|
-
});
|
|
291
|
-
ipcMain.handle(channel("openInNewWindow"), async (_event, folderPath) => {
|
|
292
|
-
try {
|
|
293
|
-
if (explorerOptions.onOpenInNewWindow) {
|
|
294
|
-
explorerOptions.onOpenInNewWindow(folderPath);
|
|
295
|
-
} else {
|
|
296
|
-
await shell.openPath(folderPath);
|
|
297
|
-
}
|
|
298
|
-
return { success: true };
|
|
299
|
-
} catch (error) {
|
|
300
|
-
return { success: false, error: String(error) };
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
ipcMain.on(channel("requestWindowFocus"), (event) => {
|
|
304
|
-
const win = BrowserWindow.fromWebContents(event.sender);
|
|
305
|
-
if (win && !win.isFocused()) {
|
|
306
|
-
win.focus();
|
|
307
|
-
}
|
|
308
|
-
});
|
|
309
|
-
ipcMain.handle(channel("mediaNeedsTranscode"), async (_event, filePath) => {
|
|
310
|
-
const mediaService = getMediaService();
|
|
311
|
-
if (!mediaService) {
|
|
312
|
-
return { success: false, error: "\u5A92\u4F53\u670D\u52A1\u672A\u521D\u59CB\u5316" };
|
|
313
|
-
}
|
|
314
|
-
try {
|
|
315
|
-
const info = await mediaService.needsTranscode(filePath);
|
|
316
|
-
return { success: true, data: info };
|
|
317
|
-
} catch (error) {
|
|
318
|
-
return { success: false, error: String(error) };
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
ipcMain.handle(channel("mediaGetPlayableUrl"), async (event, filePath) => {
|
|
322
|
-
const mediaService = getMediaService();
|
|
323
|
-
if (!mediaService) {
|
|
324
|
-
return { success: false, error: "\u5A92\u4F53\u670D\u52A1\u672A\u521D\u59CB\u5316" };
|
|
325
|
-
}
|
|
326
|
-
try {
|
|
327
|
-
const url = await mediaService.getPlayableUrl(filePath, (progress) => {
|
|
328
|
-
event.sender.send(channel("mediaTranscodeProgress"), {
|
|
329
|
-
filePath,
|
|
330
|
-
progress
|
|
331
|
-
});
|
|
332
|
-
});
|
|
333
|
-
return { success: true, url };
|
|
334
|
-
} catch (error) {
|
|
335
|
-
return { success: false, error: String(error) };
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
ipcMain.handle(channel("mediaGetMetadata"), async (_event, filePath) => {
|
|
339
|
-
const mediaService = getMediaService();
|
|
340
|
-
if (!mediaService) {
|
|
341
|
-
return { success: false, error: "\u5A92\u4F53\u670D\u52A1\u672A\u521D\u59CB\u5316" };
|
|
342
|
-
}
|
|
343
|
-
try {
|
|
344
|
-
const metadata = await mediaService.getMetadata(filePath);
|
|
345
|
-
return { success: true, data: metadata };
|
|
346
|
-
} catch (error) {
|
|
347
|
-
return { success: false, error: String(error) };
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
|
-
ipcMain.handle(channel("mediaCleanupFile"), async (_event, filePath) => {
|
|
351
|
-
const mediaService = getMediaService();
|
|
352
|
-
if (!mediaService) {
|
|
353
|
-
return { success: false, error: "\u5A92\u4F53\u670D\u52A1\u672A\u521D\u59CB\u5316" };
|
|
354
|
-
}
|
|
355
|
-
try {
|
|
356
|
-
await mediaService.cleanupFile(filePath);
|
|
357
|
-
return { success: true };
|
|
358
|
-
} catch (error) {
|
|
359
|
-
return { success: false, error: String(error) };
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
ipcMain.handle(channel("openMediaPreviewWindow"), async (event, filePath, mediaType) => {
|
|
363
|
-
try {
|
|
364
|
-
const fileName = path.basename(filePath);
|
|
365
|
-
const mediaService = getMediaService();
|
|
366
|
-
let fileUrl;
|
|
367
|
-
if (mediaType === "image") {
|
|
368
|
-
fileUrl = electronUrlEncoder(filePath);
|
|
369
|
-
} else if (mediaService) {
|
|
370
|
-
const playableUrl = await mediaService.getPlayableUrl(filePath, (progress) => {
|
|
371
|
-
event.sender.send(channel("mediaTranscodeProgress"), {
|
|
372
|
-
filePath,
|
|
373
|
-
progress
|
|
374
|
-
});
|
|
375
|
-
});
|
|
376
|
-
fileUrl = playableUrl || electronUrlEncoder(filePath);
|
|
377
|
-
} else {
|
|
378
|
-
fileUrl = electronUrlEncoder(filePath);
|
|
379
|
-
}
|
|
380
|
-
const existingWindow = mediaPreviewWindows.get(filePath);
|
|
381
|
-
if (existingWindow && !existingWindow.isDestroyed()) {
|
|
382
|
-
existingWindow.focus();
|
|
383
|
-
return { success: true };
|
|
384
|
-
}
|
|
385
|
-
const isMac = process.platform === "darwin";
|
|
386
|
-
const isWin = process.platform === "win32";
|
|
387
|
-
const titleBarHeight = isMac ? 38 : 32;
|
|
388
|
-
let contentWidth = 720;
|
|
389
|
-
let contentHeight = 405;
|
|
390
|
-
let minContentWidth = 720;
|
|
391
|
-
let minContentHeight = 405;
|
|
392
|
-
if (mediaType === "audio") {
|
|
393
|
-
contentWidth = 720;
|
|
394
|
-
contentHeight = 405;
|
|
395
|
-
minContentWidth = 720;
|
|
396
|
-
minContentHeight = 405;
|
|
397
|
-
} else if (mediaType === "image") {
|
|
398
|
-
contentWidth = 1e3;
|
|
399
|
-
contentHeight = 700;
|
|
400
|
-
minContentWidth = 600;
|
|
401
|
-
minContentHeight = 400;
|
|
402
|
-
}
|
|
403
|
-
const width = contentWidth;
|
|
404
|
-
const height = contentHeight + titleBarHeight;
|
|
405
|
-
const minWidth = minContentWidth;
|
|
406
|
-
const minHeight = minContentHeight + titleBarHeight;
|
|
407
|
-
const previewPreloadPath = path.join(__dirname, "../preload/preview.cjs");
|
|
408
|
-
const previewHtmlPath = getPreviewHtmlPath();
|
|
409
|
-
if (!fsSync.existsSync(previewPreloadPath)) {
|
|
410
|
-
return { success: false, error: `Preview preload not found: ${previewPreloadPath}` };
|
|
411
|
-
}
|
|
412
|
-
if (!fsSync.existsSync(previewHtmlPath)) {
|
|
413
|
-
return { success: false, error: `Preview html not found: ${previewHtmlPath}` };
|
|
414
|
-
}
|
|
415
|
-
const previewWindow = new BrowserWindow({
|
|
416
|
-
width,
|
|
417
|
-
height,
|
|
418
|
-
minWidth,
|
|
419
|
-
minHeight,
|
|
420
|
-
title: fileName,
|
|
421
|
-
modal: false,
|
|
422
|
-
show: false,
|
|
423
|
-
backgroundColor: "#27292c",
|
|
424
|
-
// 窗口功能
|
|
425
|
-
resizable: true,
|
|
426
|
-
maximizable: true,
|
|
427
|
-
fullscreenable: true,
|
|
428
|
-
// Windows 和 macOS 都使用无边框样式,自定义标题栏
|
|
429
|
-
frame: isMac ? true : false,
|
|
430
|
-
// macOS 用 hiddenInset,Windows 完全无边框
|
|
431
|
-
titleBarStyle: isMac ? "hiddenInset" : void 0,
|
|
432
|
-
trafficLightPosition: isMac ? { x: 12, y: 12 } : void 0,
|
|
433
|
-
webPreferences: {
|
|
434
|
-
preload: previewPreloadPath,
|
|
435
|
-
nodeIntegration: false,
|
|
436
|
-
contextIsolation: true,
|
|
437
|
-
// 注意:以下设置会触发安全警告,但这是必要的
|
|
438
|
-
// - sandbox: false - 需要加载本地媒体文件(file:// 协议)
|
|
439
|
-
// - webSecurity: false - 允许加载本地文件和 Iconify CDN
|
|
440
|
-
// 这些警告在开发环境中显示,打包后不会显示
|
|
441
|
-
sandbox: false,
|
|
442
|
-
webSecurity: false
|
|
443
|
-
}
|
|
444
|
-
});
|
|
445
|
-
const searchParams = new URLSearchParams({
|
|
446
|
-
type: mediaType,
|
|
447
|
-
url: encodeURIComponent(fileUrl),
|
|
448
|
-
name: encodeURIComponent(fileName),
|
|
449
|
-
platform: isMac ? "darwin" : isWin ? "win32" : "linux"
|
|
450
|
-
});
|
|
451
|
-
previewWindow.loadFile(previewHtmlPath, { search: searchParams.toString() });
|
|
452
|
-
previewWindow.once("ready-to-show", () => {
|
|
453
|
-
previewWindow.show();
|
|
454
|
-
});
|
|
455
|
-
previewWindow.on("maximize", () => {
|
|
456
|
-
previewWindow.webContents.send(previewChannel("maximizeChange"), true);
|
|
457
|
-
});
|
|
458
|
-
previewWindow.on("unmaximize", () => {
|
|
459
|
-
previewWindow.webContents.send(previewChannel("maximizeChange"), false);
|
|
460
|
-
});
|
|
461
|
-
previewWindow.on("closed", () => {
|
|
462
|
-
mediaPreviewWindows.delete(filePath);
|
|
463
|
-
});
|
|
464
|
-
mediaPreviewWindows.set(filePath, previewWindow);
|
|
465
|
-
return { success: true };
|
|
466
|
-
} catch (error) {
|
|
467
|
-
return { success: false, error: String(error) };
|
|
468
|
-
}
|
|
469
|
-
});
|
|
470
|
-
ipcMain.handle(channel("closeMediaPreviewWindow"), async (_event, filePath) => {
|
|
471
|
-
const window = mediaPreviewWindows.get(filePath);
|
|
472
|
-
if (window && !window.isDestroyed()) {
|
|
473
|
-
window.close();
|
|
474
|
-
mediaPreviewWindows.delete(filePath);
|
|
475
|
-
}
|
|
476
|
-
return { success: true };
|
|
477
|
-
});
|
|
478
|
-
ipcMain.on(previewChannel("minimize"), (event) => {
|
|
479
|
-
const win = BrowserWindow.fromWebContents(event.sender);
|
|
480
|
-
if (win) {
|
|
481
|
-
win.minimize();
|
|
482
|
-
}
|
|
483
|
-
});
|
|
484
|
-
ipcMain.on(previewChannel("toggleMaximize"), (event) => {
|
|
485
|
-
const win = BrowserWindow.fromWebContents(event.sender);
|
|
486
|
-
if (win) {
|
|
487
|
-
if (win.isMaximized()) {
|
|
488
|
-
win.unmaximize();
|
|
489
|
-
} else {
|
|
490
|
-
win.maximize();
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
});
|
|
494
|
-
ipcMain.on(previewChannel("close"), (event) => {
|
|
495
|
-
const win = BrowserWindow.fromWebContents(event.sender);
|
|
496
|
-
if (win) {
|
|
497
|
-
win.close();
|
|
498
|
-
}
|
|
499
|
-
});
|
|
500
|
-
ipcMain.on(previewChannel("hide"), (event) => {
|
|
501
|
-
const win = BrowserWindow.fromWebContents(event.sender);
|
|
502
|
-
if (win) {
|
|
503
|
-
win.hide();
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
ipcMain.on(previewChannel("show"), (event) => {
|
|
507
|
-
const win = BrowserWindow.fromWebContents(event.sender);
|
|
508
|
-
if (win) {
|
|
509
|
-
win.show();
|
|
510
|
-
}
|
|
511
|
-
});
|
|
512
|
-
console.log("\u2705 File Explorer IPC handlers registered");
|
|
513
|
-
}
|
|
514
|
-
function registerFileExplorer(options = {}) {
|
|
515
|
-
if (options.clipboardAdapter) {
|
|
516
|
-
setClipboardAdapter(options.clipboardAdapter);
|
|
517
|
-
}
|
|
518
|
-
registerFileExplorerHandlers(options);
|
|
519
|
-
}
|
|
520
|
-
export {
|
|
521
|
-
registerFileExplorer
|
|
522
|
-
};
|
|
1
|
+
import{ipcMain as e,shell as n,BrowserWindow as r}from"electron";import t from"path";import{fileURLToPath as a}from"url";import s from"fs";import{readDirectory as c,readFileContent as o,readImageAsBase64 as i,writeFileContent as l,createFolder as d,createFile as u,deleteFiles as h,renameFile as m,copyFiles as w,moveFiles as y,getFileInfo as p,getSystemPath as f,getThumbnailService as g,getApplicationIcon as b,copyFilesToClipboard as P,getClipboardFiles as x,pasteFiles as v,searchFiles as F,searchFilesStream as S,compressFiles as C,extractArchive as I,isArchiveFile as T,getWatchManager as z,showFileInfo as U,openInTerminal as W,openInEditor as M,getFileType as D,formatFileSize as A,formatDateTime as $,encodeFileUrl as R,getMediaService as j}from"@huyooo/file-explorer-core";import{promises as E}from"fs";import{getPreviewHtmlPath as N}from"@huyooo/file-explorer-preview/path";var B=t.dirname(a(import.meta.url)),G=null;var L=R,O={},k=new Map;function q(a={}){O=a;const R=a.channelPrefix||"file-explorer",q=a.previewChannelPrefix||"file-explorer-preview",H=e=>`${R}:${e}`,J=e=>`${q}:${e}`,K={trashItem:async e=>{await n.trashItem(e)},openPath:async e=>{await n.openPath(e)}};e.handle(H("readDirectory"),async(e,n)=>{const r=g();return await c(n,{urlEncoder:L,getThumbnailUrl:r?e=>r.getThumbnailUrl(e):void 0})}),e.handle(H("readSystemPath"),async(e,n)=>{const r=f(n);if(!r)return[];const t=g();return await c(r,{urlEncoder:L,getThumbnailUrl:t?e=>t.getThumbnailUrl(e):void 0})}),e.handle(H("getSystemPath"),async(e,n)=>f(n)),e.handle(H("readFileContent"),async(e,n)=>await o(n)),e.handle(H("writeFileContent"),async(e,n,r)=>await l(n,r)),e.handle(H("createFolder"),async(e,n,r)=>{const a=t.join(n,r);return await d(a)}),e.handle(H("createFile"),async(e,n,r,a)=>{const s=t.join(n,r);return await u(s,a)}),e.handle(H("deleteFiles"),async(e,n)=>{const r=g();return await h(n,{adapter:K,useTrash:!0,onDeleted:e=>r?.deleteThumbnail(e)})}),e.handle(H("renameFile"),async(e,n,r)=>{const t=g();return await m(n,r,{onRenamed:e=>t?.deleteThumbnail(e)})}),e.handle(H("copyFiles"),async(e,n,r)=>await w(n,r)),e.handle(H("moveFiles"),async(e,n,r)=>await y(n,r)),e.handle(H("getFileInfo"),async(e,n)=>await p(n)),e.handle(H("readImageAsBase64"),async(e,n)=>await i(n)),e.handle(H("openPath"),async(e,r)=>{try{return await n.openPath(r),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("getApplicationIcon"),async(e,n)=>await b(n)),e.handle(H("getThumbnailUrl"),async(e,n)=>{const r=g();return r?await r.getThumbnailUrl(n):null}),e.handle(H("copyFilesToClipboard"),async(e,n)=>G?await P(n,G):{success:!1,error:"剪贴板适配器未初始化"}),e.handle(H("getClipboardFiles"),async()=>G?x(G):{success:!1,error:"剪贴板适配器未初始化"}),e.handle(H("pasteFiles"),async(e,n,r)=>await v(n,r)),e.handle(H("searchFiles"),async(e,n,r,a)=>{try{const e=await F(n,r,a),s=g(),c=100,o=[];for(const n of e.slice(0,c))try{const e=await E.stat(n),r=D(n,e),a={id:n,name:t.basename(n),type:r,size:e.isDirectory()?void 0:A(e.size),dateModified:$(e.mtime),url:L(n)};if(s){const e=await s.getThumbnailUrl(n);e&&(a.thumbnailUrl=e)}o.push(a)}catch{}return{success:!0,data:{items:o,total:e.length}}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("searchFilesStream"),async(e,n,r,a)=>{const s=g(),c=async e=>{try{const n=await E.stat(e),r=D(e,n),a={id:e,name:t.basename(e),type:r,size:n.isDirectory()?void 0:A(n.size),dateModified:$(n.mtime),url:L(e)};if(s){const n=await s.getThumbnailUrl(e);n&&(a.thumbnailUrl=n)}return a}catch{return null}};return S(n,r,async(n,r)=>{const t=[];for(const e of n){const n=await c(e);n&&t.push(n)}e.sender.send(H("searchResults"),{searchId:a,items:t,done:r})},100),{success:!0}}),e.handle(H("compressFiles"),async(e,n,r)=>{try{return await C(n,r,n=>{e.sender.send(H("compressProgress"),n)})}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("extractArchive"),async(e,n,r)=>{try{return await I(n,r,n=>{e.sender.send(H("extractProgress"),n)})}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("isArchiveFile"),async(e,n)=>T(n));const Q=new Map;e.handle(H("watchDirectory"),async(e,n,r)=>{try{const t=Q.get(r);t&&(t(),Q.delete(r));const a=z().watch(n,n=>{e.sender.send(H("watchEvent"),{watchId:r,event:n})});return Q.set(r,a),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("unwatchDirectory"),async(e,n)=>{const r=Q.get(n);return r&&(r(),Q.delete(n)),{success:!0}}),e.handle(H("showFileInfo"),async(e,n)=>await U(n)),e.handle(H("openInTerminal"),async(e,n)=>await W(n)),e.handle(H("openInEditor"),async(e,n)=>await M(n)),e.handle(H("openInNewWindow"),async(e,r)=>{try{return O.onOpenInNewWindow?O.onOpenInNewWindow(r):await n.openPath(r),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.on(H("requestWindowFocus"),e=>{const n=r.fromWebContents(e.sender);n&&!n.isFocused()&&n.focus()}),e.handle(H("mediaNeedsTranscode"),async(e,n)=>{const r=j();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return{success:!0,data:await r.needsTranscode(n)}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("mediaGetPlayableUrl"),async(e,n)=>{const r=j();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return{success:!0,url:await r.getPlayableUrl(n,r=>{e.sender.send(H("mediaTranscodeProgress"),{filePath:n,progress:r})})}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("mediaGetMetadata"),async(e,n)=>{const r=j();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return{success:!0,data:await r.getMetadata(n)}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("mediaCleanupFile"),async(e,n)=>{const r=j();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return await r.cleanupFile(n),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("openMediaPreviewWindow"),async(e,n,a)=>{try{const c=t.basename(n),o=j();let i;if("image"===a)i=L(n);else if(o){i=await o.getPlayableUrl(n,r=>{e.sender.send(H("mediaTranscodeProgress"),{filePath:n,progress:r})})||L(n)}else i=L(n);const l=k.get(n);if(l&&!l.isDestroyed())return l.focus(),{success:!0};const d="darwin"===process.platform,u="win32"===process.platform,h=d?38:32;let m=720,w=405,y=720,p=405;"audio"===a?(m=720,w=405,y=720,p=405):"image"===a&&(m=1e3,w=700,y=600,p=400);const f=m,g=w+h,b=y,P=p+h,x=t.join(B,"../preload/preview.cjs"),v=N();if(!s.existsSync(x))return{success:!1,error:`Preview preload not found: ${x}`};if(!s.existsSync(v))return{success:!1,error:`Preview html not found: ${v}`};const F=new r({width:f,height:g,minWidth:b,minHeight:P,title:c,modal:!1,show:!1,backgroundColor:"#27292c",resizable:!0,maximizable:!0,fullscreenable:!0,frame:!!d,titleBarStyle:d?"hiddenInset":void 0,trafficLightPosition:d?{x:12,y:12}:void 0,webPreferences:{preload:x,nodeIntegration:!1,contextIsolation:!0,sandbox:!1,webSecurity:!1}}),S=new URLSearchParams({type:a,url:encodeURIComponent(i),name:encodeURIComponent(c),platform:d?"darwin":u?"win32":"linux"});return F.loadFile(v,{search:S.toString()}),F.once("ready-to-show",()=>{F.show()}),F.on("maximize",()=>{F.webContents.send(J("maximizeChange"),!0)}),F.on("unmaximize",()=>{F.webContents.send(J("maximizeChange"),!1)}),F.on("closed",()=>{k.delete(n)}),k.set(n,F),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("closeMediaPreviewWindow"),async(e,n)=>{const r=k.get(n);return r&&!r.isDestroyed()&&(r.close(),k.delete(n)),{success:!0}}),e.on(J("minimize"),e=>{const n=r.fromWebContents(e.sender);n&&n.minimize()}),e.on(J("toggleMaximize"),e=>{const n=r.fromWebContents(e.sender);n&&(n.isMaximized()?n.unmaximize():n.maximize())}),e.on(J("close"),e=>{const n=r.fromWebContents(e.sender);n&&n.close()}),e.on(J("hide"),e=>{const n=r.fromWebContents(e.sender);n&&n.hide()}),e.on(J("show"),e=>{const n=r.fromWebContents(e.sender);n&&n.show()})}function H(e={}){var n;e.clipboardAdapter&&(n=e.clipboardAdapter,G=n),q(e)}export{H as registerFileExplorer};
|
package/dist/preload/index.js
CHANGED
|
@@ -1,92 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { contextBridge, ipcRenderer } from "electron";
|
|
3
|
-
var DEFAULT_CHANNEL_PREFIX = "file-explorer";
|
|
4
|
-
function createFileExplorerAPI(options = {}) {
|
|
5
|
-
const channelPrefix = options.channelPrefix || DEFAULT_CHANNEL_PREFIX;
|
|
6
|
-
const channel = (name) => `${channelPrefix}:${name}`;
|
|
7
|
-
return {
|
|
8
|
-
readDirectory: (dirPath) => ipcRenderer.invoke(channel("readDirectory"), dirPath),
|
|
9
|
-
readSystemPath: (pathId) => ipcRenderer.invoke(channel("readSystemPath"), pathId),
|
|
10
|
-
getSystemPath: (pathId) => ipcRenderer.invoke(channel("getSystemPath"), pathId),
|
|
11
|
-
readFileContent: (filePath) => ipcRenderer.invoke(channel("readFileContent"), filePath),
|
|
12
|
-
writeFileContent: (filePath, content) => ipcRenderer.invoke(channel("writeFileContent"), filePath, content),
|
|
13
|
-
createFolder: (parentDir, folderName) => ipcRenderer.invoke(channel("createFolder"), parentDir, folderName),
|
|
14
|
-
createFile: (parentDir, fileName, content) => ipcRenderer.invoke(channel("createFile"), parentDir, fileName, content),
|
|
15
|
-
deleteFiles: (paths) => ipcRenderer.invoke(channel("deleteFiles"), paths),
|
|
16
|
-
renameFile: (oldPath, newPath) => ipcRenderer.invoke(channel("renameFile"), oldPath, newPath),
|
|
17
|
-
copyFiles: (sourcePaths, targetDir) => ipcRenderer.invoke(channel("copyFiles"), sourcePaths, targetDir),
|
|
18
|
-
moveFiles: (sourcePaths, targetDir) => ipcRenderer.invoke(channel("moveFiles"), sourcePaths, targetDir),
|
|
19
|
-
getFileInfo: (filePath) => ipcRenderer.invoke(channel("getFileInfo"), filePath),
|
|
20
|
-
readImageAsBase64: (imagePath) => ipcRenderer.invoke(channel("readImageAsBase64"), imagePath),
|
|
21
|
-
openPath: (filePath) => ipcRenderer.invoke(channel("openPath"), filePath),
|
|
22
|
-
getApplicationIcon: (appPath) => ipcRenderer.invoke(channel("getApplicationIcon"), appPath),
|
|
23
|
-
getThumbnailUrl: (filePath) => ipcRenderer.invoke(channel("getThumbnailUrl"), filePath),
|
|
24
|
-
copyFilesToClipboard: (filePaths) => ipcRenderer.invoke(channel("copyFilesToClipboard"), filePaths),
|
|
25
|
-
getClipboardFiles: () => ipcRenderer.invoke(channel("getClipboardFiles")),
|
|
26
|
-
pasteFiles: (targetDir, sourcePaths) => ipcRenderer.invoke(channel("pasteFiles"), targetDir, sourcePaths),
|
|
27
|
-
searchFiles: (searchPath, pattern, maxDepth) => ipcRenderer.invoke(channel("searchFiles"), searchPath, pattern, maxDepth),
|
|
28
|
-
searchFilesStream: (searchPath, pattern, searchId) => ipcRenderer.invoke(channel("searchFilesStream"), searchPath, pattern, searchId),
|
|
29
|
-
onSearchResults: (callback) => {
|
|
30
|
-
const handler = (_event, data) => {
|
|
31
|
-
callback(data);
|
|
32
|
-
};
|
|
33
|
-
ipcRenderer.on(channel("searchResults"), handler);
|
|
34
|
-
return () => ipcRenderer.removeListener(channel("searchResults"), handler);
|
|
35
|
-
},
|
|
36
|
-
compressFiles: (sources, options2) => ipcRenderer.invoke(channel("compressFiles"), sources, options2),
|
|
37
|
-
extractArchive: (archivePath, options2) => ipcRenderer.invoke(channel("extractArchive"), archivePath, options2),
|
|
38
|
-
isArchiveFile: (filePath) => ipcRenderer.invoke(channel("isArchiveFile"), filePath),
|
|
39
|
-
onCompressProgress: (callback) => {
|
|
40
|
-
const handler = (_event, data) => {
|
|
41
|
-
callback(data);
|
|
42
|
-
};
|
|
43
|
-
ipcRenderer.on(channel("compressProgress"), handler);
|
|
44
|
-
return () => ipcRenderer.removeListener(channel("compressProgress"), handler);
|
|
45
|
-
},
|
|
46
|
-
onExtractProgress: (callback) => {
|
|
47
|
-
const handler = (_event, data) => {
|
|
48
|
-
callback(data);
|
|
49
|
-
};
|
|
50
|
-
ipcRenderer.on(channel("extractProgress"), handler);
|
|
51
|
-
return () => ipcRenderer.removeListener(channel("extractProgress"), handler);
|
|
52
|
-
},
|
|
53
|
-
watchDirectory: (dirPath, watchId) => ipcRenderer.invoke(channel("watchDirectory"), dirPath, watchId),
|
|
54
|
-
unwatchDirectory: (watchId) => ipcRenderer.invoke(channel("unwatchDirectory"), watchId),
|
|
55
|
-
onWatchEvent: (callback) => {
|
|
56
|
-
const handler = (_event, data) => {
|
|
57
|
-
callback(data);
|
|
58
|
-
};
|
|
59
|
-
ipcRenderer.on(channel("watchEvent"), handler);
|
|
60
|
-
return () => ipcRenderer.removeListener(channel("watchEvent"), handler);
|
|
61
|
-
},
|
|
62
|
-
showFileInfo: (filePath) => ipcRenderer.invoke(channel("showFileInfo"), filePath),
|
|
63
|
-
openInTerminal: (dirPath) => ipcRenderer.invoke(channel("openInTerminal"), dirPath),
|
|
64
|
-
openInEditor: (targetPath) => ipcRenderer.invoke(channel("openInEditor"), targetPath),
|
|
65
|
-
openInNewWindow: (folderPath) => ipcRenderer.invoke(channel("openInNewWindow"), folderPath),
|
|
66
|
-
requestWindowFocus: () => ipcRenderer.send(channel("requestWindowFocus")),
|
|
67
|
-
// ===== 媒体服务 API =====
|
|
68
|
-
mediaNeedsTranscode: (filePath) => ipcRenderer.invoke(channel("mediaNeedsTranscode"), filePath),
|
|
69
|
-
mediaGetPlayableUrl: (filePath) => ipcRenderer.invoke(channel("mediaGetPlayableUrl"), filePath),
|
|
70
|
-
mediaGetMetadata: (filePath) => ipcRenderer.invoke(channel("mediaGetMetadata"), filePath),
|
|
71
|
-
onMediaTranscodeProgress: (callback) => {
|
|
72
|
-
const handler = (_event, data) => {
|
|
73
|
-
callback(data);
|
|
74
|
-
};
|
|
75
|
-
ipcRenderer.on(channel("mediaTranscodeProgress"), handler);
|
|
76
|
-
return () => ipcRenderer.removeListener(channel("mediaTranscodeProgress"), handler);
|
|
77
|
-
},
|
|
78
|
-
mediaCleanupFile: (filePath) => ipcRenderer.invoke(channel("mediaCleanupFile"), filePath),
|
|
79
|
-
// ===== 媒体预览窗口 API =====
|
|
80
|
-
openMediaPreviewWindow: (filePath, mediaType) => ipcRenderer.invoke(channel("openMediaPreviewWindow"), filePath, mediaType),
|
|
81
|
-
closeMediaPreviewWindow: (filePath) => ipcRenderer.invoke(channel("closeMediaPreviewWindow"), filePath)
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
function exposeFileExplorerAPI(options = {}) {
|
|
85
|
-
const apiName = options.apiName || "fileExplorerAPI";
|
|
86
|
-
const api = createFileExplorerAPI({ channelPrefix: options.channelPrefix });
|
|
87
|
-
contextBridge.exposeInMainWorld(apiName, api);
|
|
88
|
-
console.log(`\u2705 File Explorer API exposed as window.${apiName}`);
|
|
89
|
-
}
|
|
90
|
-
export {
|
|
91
|
-
exposeFileExplorerAPI
|
|
92
|
-
};
|
|
1
|
+
import{contextBridge as e,ipcRenderer as o}from"electron";function i(i={}){const n=i.apiName||"fileExplorerAPI",r=function(e={}){const i=e.channelPrefix||"file-explorer",n=e=>`${i}:${e}`;return{readDirectory:e=>o.invoke(n("readDirectory"),e),readSystemPath:e=>o.invoke(n("readSystemPath"),e),getSystemPath:e=>o.invoke(n("getSystemPath"),e),readFileContent:e=>o.invoke(n("readFileContent"),e),writeFileContent:(e,i)=>o.invoke(n("writeFileContent"),e,i),createFolder:(e,i)=>o.invoke(n("createFolder"),e,i),createFile:(e,i,r)=>o.invoke(n("createFile"),e,i,r),deleteFiles:e=>o.invoke(n("deleteFiles"),e),renameFile:(e,i)=>o.invoke(n("renameFile"),e,i),copyFiles:(e,i)=>o.invoke(n("copyFiles"),e,i),moveFiles:(e,i)=>o.invoke(n("moveFiles"),e,i),getFileInfo:e=>o.invoke(n("getFileInfo"),e),readImageAsBase64:e=>o.invoke(n("readImageAsBase64"),e),openPath:e=>o.invoke(n("openPath"),e),getApplicationIcon:e=>o.invoke(n("getApplicationIcon"),e),getThumbnailUrl:e=>o.invoke(n("getThumbnailUrl"),e),copyFilesToClipboard:e=>o.invoke(n("copyFilesToClipboard"),e),getClipboardFiles:()=>o.invoke(n("getClipboardFiles")),pasteFiles:(e,i)=>o.invoke(n("pasteFiles"),e,i),searchFiles:(e,i,r)=>o.invoke(n("searchFiles"),e,i,r),searchFilesStream:(e,i,r)=>o.invoke(n("searchFilesStream"),e,i,r),onSearchResults:e=>{const i=(o,i)=>{e(i)};return o.on(n("searchResults"),i),()=>o.removeListener(n("searchResults"),i)},compressFiles:(e,i)=>o.invoke(n("compressFiles"),e,i),extractArchive:(e,i)=>o.invoke(n("extractArchive"),e,i),isArchiveFile:e=>o.invoke(n("isArchiveFile"),e),onCompressProgress:e=>{const i=(o,i)=>{e(i)};return o.on(n("compressProgress"),i),()=>o.removeListener(n("compressProgress"),i)},onExtractProgress:e=>{const i=(o,i)=>{e(i)};return o.on(n("extractProgress"),i),()=>o.removeListener(n("extractProgress"),i)},watchDirectory:(e,i)=>o.invoke(n("watchDirectory"),e,i),unwatchDirectory:e=>o.invoke(n("unwatchDirectory"),e),onWatchEvent:e=>{const i=(o,i)=>{e(i)};return o.on(n("watchEvent"),i),()=>o.removeListener(n("watchEvent"),i)},showFileInfo:e=>o.invoke(n("showFileInfo"),e),openInTerminal:e=>o.invoke(n("openInTerminal"),e),openInEditor:e=>o.invoke(n("openInEditor"),e),openInNewWindow:e=>o.invoke(n("openInNewWindow"),e),requestWindowFocus:()=>o.send(n("requestWindowFocus")),mediaNeedsTranscode:e=>o.invoke(n("mediaNeedsTranscode"),e),mediaGetPlayableUrl:e=>o.invoke(n("mediaGetPlayableUrl"),e),mediaGetMetadata:e=>o.invoke(n("mediaGetMetadata"),e),onMediaTranscodeProgress:e=>{const i=(o,i)=>{e(i)};return o.on(n("mediaTranscodeProgress"),i),()=>o.removeListener(n("mediaTranscodeProgress"),i)},mediaCleanupFile:e=>o.invoke(n("mediaCleanupFile"),e),openMediaPreviewWindow:(e,i)=>o.invoke(n("openMediaPreviewWindow"),e,i),closeMediaPreviewWindow:e=>o.invoke(n("closeMediaPreviewWindow"),e)}}({channelPrefix:i.channelPrefix});e.exposeInMainWorld(n,r)}export{i as exposeFileExplorerAPI};
|
package/dist/preload/preview.cjs
CHANGED
|
@@ -1,54 +1 @@
|
|
|
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
|
-
});
|
|
1
|
+
"use strict";var e,r=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,t={};((e,n)=>{for(var i in n)r(e,i,{get:n[i],enumerable:!0})})(t,{exposePreviewWindowAPI:()=>p}),module.exports=(e=t,((e,t,d,c)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let p of i(t))o.call(e,p)||p===d||r(e,p,{get:()=>t[p],enumerable:!(c=n(t,p))||c.enumerable});return e})(r({},"__esModule",{value:!0}),e));var d=require("electron"),c=e=>`file-explorer-preview:${e}`;function p(){const e={minimizeWindow:()=>d.ipcRenderer.send(c("minimize")),toggleMaximizeWindow:()=>d.ipcRenderer.send(c("toggleMaximize")),closeWindow:()=>d.ipcRenderer.send(c("close")),hideWindow:()=>d.ipcRenderer.send(c("hide")),showWindow:()=>d.ipcRenderer.send(c("show")),onMaximizeChange:e=>{const r=(r,n)=>{e(n)};return d.ipcRenderer.on(c("maximizeChange"),r),()=>d.ipcRenderer.removeListener(c("maximizeChange"),r)}};d.contextBridge.exposeInMainWorld("electronAPI",e)}p();
|
package/dist/renderer/index.js
CHANGED
|
@@ -1,14 +1 @@
|
|
|
1
|
-
|
|
2
|
-
function createFileExplorerClient(apiName = "fileExplorerAPI") {
|
|
3
|
-
const api = apiName === "fileExplorerAPI" ? window.fileExplorerAPI : window[apiName];
|
|
4
|
-
if (!api) {
|
|
5
|
-
throw new Error(
|
|
6
|
-
`window.${apiName} not found. Make sure to call exposeFileExplorerAPI({ apiName }) in your preload script.`
|
|
7
|
-
);
|
|
8
|
-
}
|
|
9
|
-
const typedApi = api;
|
|
10
|
-
return typedApi;
|
|
11
|
-
}
|
|
12
|
-
export {
|
|
13
|
-
createFileExplorerClient
|
|
14
|
-
};
|
|
1
|
+
function r(r="fileExplorerAPI"){const o="fileExplorerAPI"===r?window.fileExplorerAPI:window[r];if(!o)throw new Error(`window.${r} not found. Make sure to call exposeFileExplorerAPI({ apiName }) in your preload script.`);return o}export{r as createFileExplorerClient};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huyooo/file-explorer-bridge-electron",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.21",
|
|
4
4
|
"description": "File Explorer Electron Bridge - IPC integration for Electron apps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/main/index.js",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"clean": "rm -rf dist"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@huyooo/file-explorer-core": "^0.4.
|
|
37
|
-
"@huyooo/file-explorer-preview": "^0.4.
|
|
36
|
+
"@huyooo/file-explorer-core": "^0.4.21",
|
|
37
|
+
"@huyooo/file-explorer-preview": "^0.4.21"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"electron": ">=20.0.0"
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"@types/better-sqlite3": "^7.6.0",
|
|
49
49
|
"@types/node": "^22.0.0",
|
|
50
50
|
"electron": "^33.0.0",
|
|
51
|
+
"terser": "^5.44.1",
|
|
51
52
|
"tsup": "^8.0.0",
|
|
52
53
|
"typescript": "^5.0.0"
|
|
53
54
|
},
|
|
@@ -59,7 +60,7 @@
|
|
|
59
60
|
"bridge"
|
|
60
61
|
],
|
|
61
62
|
"author": "huyooo",
|
|
62
|
-
"license": "
|
|
63
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
63
64
|
"publishConfig": {
|
|
64
65
|
"access": "public"
|
|
65
66
|
}
|