@huyooo/file-explorer-frontend-react 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +1740 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +562 -0
- package/dist/index.js +3453 -0
- package/dist/index.js.map +1 -0
- package/dist/style.css +3 -0
- package/package.json +58 -0
- package/src/components/Breadcrumb.css +61 -0
- package/src/components/Breadcrumb.tsx +38 -0
- package/src/components/CompressDialog.css +264 -0
- package/src/components/CompressDialog.tsx +222 -0
- package/src/components/ContextMenu.css +155 -0
- package/src/components/ContextMenu.tsx +375 -0
- package/src/components/FileGrid.css +267 -0
- package/src/components/FileGrid.tsx +277 -0
- package/src/components/FileIcon.css +41 -0
- package/src/components/FileIcon.tsx +86 -0
- package/src/components/FileInfoDialog.css +252 -0
- package/src/components/FileInfoDialog.tsx +202 -0
- package/src/components/FileList.css +226 -0
- package/src/components/FileList.tsx +228 -0
- package/src/components/FileListView.css +36 -0
- package/src/components/FileListView.tsx +355 -0
- package/src/components/FileSidebar.css +94 -0
- package/src/components/FileSidebar.tsx +66 -0
- package/src/components/ProgressDialog.css +211 -0
- package/src/components/ProgressDialog.tsx +183 -0
- package/src/components/SortIndicator.css +7 -0
- package/src/components/SortIndicator.tsx +19 -0
- package/src/components/StatusBar.css +20 -0
- package/src/components/StatusBar.tsx +21 -0
- package/src/components/Toolbar.css +150 -0
- package/src/components/Toolbar.tsx +127 -0
- package/src/components/Window.css +246 -0
- package/src/components/Window.tsx +335 -0
- package/src/hooks/useApplicationIcon.ts +80 -0
- package/src/hooks/useDragAndDrop.ts +104 -0
- package/src/hooks/useMediaPlayer.ts +164 -0
- package/src/hooks/useSelection.ts +112 -0
- package/src/hooks/useWindowDrag.ts +60 -0
- package/src/hooks/useWindowResize.ts +126 -0
- package/src/index.css +3 -0
- package/src/index.ts +34 -0
- package/src/types/index.ts +274 -0
- package/src/utils/fileTypeIcon.ts +309 -0
- package/src/utils/folderTypeIcon.ts +132 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 文件类型(使用 const object 而非 enum,更好的 tree-shaking)
|
|
6
|
+
*/
|
|
7
|
+
declare const FileType: {
|
|
8
|
+
readonly FOLDER: "folder";
|
|
9
|
+
readonly FILE: "file";
|
|
10
|
+
readonly IMAGE: "image";
|
|
11
|
+
readonly VIDEO: "video";
|
|
12
|
+
readonly MUSIC: "music";
|
|
13
|
+
readonly DOCUMENT: "document";
|
|
14
|
+
readonly CODE: "code";
|
|
15
|
+
readonly TEXT: "text";
|
|
16
|
+
readonly PDF: "pdf";
|
|
17
|
+
readonly ARCHIVE: "archive";
|
|
18
|
+
readonly APPLICATION: "application";
|
|
19
|
+
readonly UNKNOWN: "unknown";
|
|
20
|
+
};
|
|
21
|
+
type FileType = typeof FileType[keyof typeof FileType];
|
|
22
|
+
/**
|
|
23
|
+
* 文件系统项
|
|
24
|
+
*/
|
|
25
|
+
interface FileItem {
|
|
26
|
+
/** 唯一标识(通常是完整路径) */
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
type: FileType;
|
|
30
|
+
size?: string;
|
|
31
|
+
dateModified?: string;
|
|
32
|
+
url?: string;
|
|
33
|
+
thumbnailUrl?: string;
|
|
34
|
+
children?: FileItem[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 视图模式
|
|
38
|
+
*/
|
|
39
|
+
type ViewMode = 'grid' | 'list' | 'columns';
|
|
40
|
+
/**
|
|
41
|
+
* 排序配置
|
|
42
|
+
*/
|
|
43
|
+
interface SortConfig {
|
|
44
|
+
field: 'name' | 'dateModified' | 'size' | 'type';
|
|
45
|
+
direction: 'asc' | 'desc';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 侧边栏项目
|
|
49
|
+
*/
|
|
50
|
+
interface SidebarItem {
|
|
51
|
+
id: string;
|
|
52
|
+
label: string;
|
|
53
|
+
icon?: string;
|
|
54
|
+
path?: string;
|
|
55
|
+
children?: SidebarItem[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 面包屑项
|
|
59
|
+
*/
|
|
60
|
+
interface BreadcrumbItem {
|
|
61
|
+
id: string;
|
|
62
|
+
name: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 操作结果
|
|
66
|
+
*/
|
|
67
|
+
interface OperationResult<T = void> {
|
|
68
|
+
success: boolean;
|
|
69
|
+
data?: T;
|
|
70
|
+
error?: string;
|
|
71
|
+
}
|
|
72
|
+
/** 压缩格式 */
|
|
73
|
+
type CompressFormat = 'zip' | 'tar' | 'tgz' | 'tarbz2';
|
|
74
|
+
/** 压缩级别 */
|
|
75
|
+
type CompressLevel = 'fast' | 'normal' | 'best';
|
|
76
|
+
/** 压缩选项 */
|
|
77
|
+
interface CompressOptions {
|
|
78
|
+
format: CompressFormat;
|
|
79
|
+
level?: CompressLevel;
|
|
80
|
+
outputName: string;
|
|
81
|
+
outputDir: string;
|
|
82
|
+
deleteSource?: boolean;
|
|
83
|
+
}
|
|
84
|
+
/** 解压选项 */
|
|
85
|
+
interface ExtractOptions {
|
|
86
|
+
targetDir: string;
|
|
87
|
+
deleteArchive?: boolean;
|
|
88
|
+
}
|
|
89
|
+
/** 压缩进度 */
|
|
90
|
+
interface CompressProgress {
|
|
91
|
+
currentFile: string;
|
|
92
|
+
processedCount: number;
|
|
93
|
+
totalCount: number;
|
|
94
|
+
percent: number;
|
|
95
|
+
}
|
|
96
|
+
/** 压缩结果 */
|
|
97
|
+
interface CompressResult {
|
|
98
|
+
success: boolean;
|
|
99
|
+
outputPath?: string;
|
|
100
|
+
error?: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* 文件操作适配器接口
|
|
104
|
+
*/
|
|
105
|
+
interface FileExplorerAdapter {
|
|
106
|
+
/** 读取目录 */
|
|
107
|
+
readDirectory(dirPath: string): Promise<FileItem[]>;
|
|
108
|
+
/** 读取系统路径目录 */
|
|
109
|
+
readSystemPath(pathId: string): Promise<FileItem[]>;
|
|
110
|
+
/** 获取系统路径 */
|
|
111
|
+
getSystemPath(pathId: string): Promise<string | null>;
|
|
112
|
+
/** 读取文件内容 */
|
|
113
|
+
readFileContent(filePath: string): Promise<string>;
|
|
114
|
+
/** 写入文件内容 */
|
|
115
|
+
writeFileContent(filePath: string, content: string): Promise<OperationResult>;
|
|
116
|
+
/** 创建文件夹 */
|
|
117
|
+
createFolder(parentDir: string, folderName: string): Promise<OperationResult<{
|
|
118
|
+
finalPath: string;
|
|
119
|
+
}>>;
|
|
120
|
+
/** 创建文件 */
|
|
121
|
+
createFile(parentDir: string, fileName: string, content?: string): Promise<OperationResult<{
|
|
122
|
+
finalPath: string;
|
|
123
|
+
}>>;
|
|
124
|
+
/** 删除文件 */
|
|
125
|
+
deleteFiles(paths: string[]): Promise<OperationResult>;
|
|
126
|
+
/** 重命名文件 */
|
|
127
|
+
renameFile(oldPath: string, newPath: string): Promise<OperationResult>;
|
|
128
|
+
/** 复制文件 */
|
|
129
|
+
copyFiles(sourcePaths: string[], targetDir: string): Promise<OperationResult<{
|
|
130
|
+
copiedPaths: string[];
|
|
131
|
+
}>>;
|
|
132
|
+
/** 移动文件 */
|
|
133
|
+
moveFiles(sourcePaths: string[], targetDir: string): Promise<OperationResult<{
|
|
134
|
+
movedPaths: string[];
|
|
135
|
+
}>>;
|
|
136
|
+
/** 使用系统默认应用打开 */
|
|
137
|
+
openPath(filePath: string): Promise<OperationResult>;
|
|
138
|
+
/** 复制文件到剪贴板 */
|
|
139
|
+
copyFilesToClipboard(filePaths: string[]): Promise<OperationResult>;
|
|
140
|
+
/** 获取剪贴板文件 */
|
|
141
|
+
getClipboardFiles(): Promise<OperationResult<{
|
|
142
|
+
files: string[];
|
|
143
|
+
}>>;
|
|
144
|
+
/** 粘贴文件 */
|
|
145
|
+
pasteFiles(targetDir: string, sourcePaths: string[]): Promise<OperationResult<{
|
|
146
|
+
pastedPaths: string[];
|
|
147
|
+
}>>;
|
|
148
|
+
/** 流式搜索文件 */
|
|
149
|
+
searchFilesStream(searchPath: string, pattern: string, searchId: string): Promise<OperationResult>;
|
|
150
|
+
/** 监听搜索结果 */
|
|
151
|
+
onSearchResults(callback: (data: {
|
|
152
|
+
searchId: string;
|
|
153
|
+
items: FileItem[];
|
|
154
|
+
done: boolean;
|
|
155
|
+
}) => void): () => void;
|
|
156
|
+
/** 压缩文件 */
|
|
157
|
+
compressFiles(sources: string[], options: CompressOptions): Promise<CompressResult>;
|
|
158
|
+
/** 解压文件 */
|
|
159
|
+
extractArchive(archivePath: string, options: ExtractOptions): Promise<CompressResult>;
|
|
160
|
+
/** 判断是否为压缩文件 */
|
|
161
|
+
isArchiveFile(filePath: string): Promise<boolean>;
|
|
162
|
+
/** 监听压缩进度 */
|
|
163
|
+
onCompressProgress(callback: (data: CompressProgress) => void): () => void;
|
|
164
|
+
/** 监听解压进度 */
|
|
165
|
+
onExtractProgress(callback: (data: CompressProgress) => void): () => void;
|
|
166
|
+
/** 监听目录变化 */
|
|
167
|
+
watchDirectory(dirPath: string, watchId: string): Promise<OperationResult>;
|
|
168
|
+
/** 停止监听目录 */
|
|
169
|
+
unwatchDirectory(watchId: string): Promise<OperationResult>;
|
|
170
|
+
/** 监听文件变化事件 */
|
|
171
|
+
onWatchEvent(callback: (data: {
|
|
172
|
+
watchId: string;
|
|
173
|
+
event: WatchEvent;
|
|
174
|
+
}) => void): () => void;
|
|
175
|
+
/** 显示文件/文件夹的系统属性窗口 */
|
|
176
|
+
showFileInfo(filePath: string): Promise<OperationResult>;
|
|
177
|
+
/** 在终端中打开目录 */
|
|
178
|
+
openInTerminal(dirPath: string): Promise<OperationResult>;
|
|
179
|
+
/** 通过 Cursor 打开 */
|
|
180
|
+
openInEditor(targetPath: string): Promise<OperationResult>;
|
|
181
|
+
/** 在新窗口中打开文件夹(使用系统文件管理器) */
|
|
182
|
+
openInNewWindow(folderPath: string): Promise<OperationResult>;
|
|
183
|
+
/** 请求窗口聚焦(用于右键打开菜单前激活窗口) */
|
|
184
|
+
requestWindowFocus(): void;
|
|
185
|
+
/** 检测媒体文件是否需要转码 */
|
|
186
|
+
mediaNeedsTranscode?(filePath: string): Promise<OperationResult<TranscodeInfo>>;
|
|
187
|
+
/** 获取可播放的媒体 URL(自动转码) */
|
|
188
|
+
mediaGetPlayableUrl?(filePath: string): Promise<{
|
|
189
|
+
success: boolean;
|
|
190
|
+
url?: string;
|
|
191
|
+
error?: string;
|
|
192
|
+
}>;
|
|
193
|
+
/** 获取媒体元数据 */
|
|
194
|
+
mediaGetMetadata?(filePath: string): Promise<OperationResult<MediaMetadata>>;
|
|
195
|
+
/** 监听转码进度 */
|
|
196
|
+
onMediaTranscodeProgress?(callback: (data: {
|
|
197
|
+
filePath: string;
|
|
198
|
+
progress: MediaTranscodeProgress;
|
|
199
|
+
}) => void): () => void;
|
|
200
|
+
/** 清理指定文件的转码缓存 */
|
|
201
|
+
mediaCleanupFile?(filePath: string): Promise<OperationResult>;
|
|
202
|
+
/** 打开媒体预览窗口(原生窗口) */
|
|
203
|
+
openMediaPreviewWindow?(filePath: string, mediaType: 'image' | 'video' | 'audio'): Promise<OperationResult>;
|
|
204
|
+
/** 关闭媒体预览窗口 */
|
|
205
|
+
closeMediaPreviewWindow?(filePath: string): Promise<OperationResult>;
|
|
206
|
+
}
|
|
207
|
+
/** 文件变化事件类型 */
|
|
208
|
+
type WatchEventType = 'add' | 'change' | 'remove' | 'rename';
|
|
209
|
+
/** 文件变化事件 */
|
|
210
|
+
interface WatchEvent {
|
|
211
|
+
type: WatchEventType;
|
|
212
|
+
path: string;
|
|
213
|
+
filename: string;
|
|
214
|
+
}
|
|
215
|
+
/** 媒体转码方式 */
|
|
216
|
+
type TranscodeMethod = 'direct' | 'remux' | 'transcode';
|
|
217
|
+
/** 媒体转码状态 */
|
|
218
|
+
type TranscodeStatus = 'idle' | 'checking' | 'transcoding' | 'ready' | 'error';
|
|
219
|
+
/** 媒体转码信息 */
|
|
220
|
+
interface TranscodeInfo {
|
|
221
|
+
type: 'video' | 'audio';
|
|
222
|
+
needsTranscode: boolean;
|
|
223
|
+
method: TranscodeMethod;
|
|
224
|
+
estimatedTime?: number;
|
|
225
|
+
targetFormat?: string;
|
|
226
|
+
}
|
|
227
|
+
/** 媒体转码进度 */
|
|
228
|
+
interface MediaTranscodeProgress {
|
|
229
|
+
percent: number;
|
|
230
|
+
time?: number;
|
|
231
|
+
duration?: number;
|
|
232
|
+
speed?: string;
|
|
233
|
+
}
|
|
234
|
+
/** 媒体元数据 */
|
|
235
|
+
interface MediaMetadata {
|
|
236
|
+
filePath: string;
|
|
237
|
+
type: 'video' | 'audio';
|
|
238
|
+
duration: number;
|
|
239
|
+
title?: string;
|
|
240
|
+
artist?: string;
|
|
241
|
+
album?: string;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* 右键菜单项
|
|
245
|
+
*/
|
|
246
|
+
interface ContextMenuItem {
|
|
247
|
+
id: string;
|
|
248
|
+
label: string;
|
|
249
|
+
icon?: string;
|
|
250
|
+
shortcut?: string;
|
|
251
|
+
disabled?: boolean;
|
|
252
|
+
separator?: boolean;
|
|
253
|
+
danger?: boolean;
|
|
254
|
+
checked?: boolean;
|
|
255
|
+
action?: () => void;
|
|
256
|
+
children?: ContextMenuItem[];
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
interface FileListViewProps {
|
|
260
|
+
items: FileItem[];
|
|
261
|
+
viewMode?: 'grid' | 'list';
|
|
262
|
+
loading?: boolean;
|
|
263
|
+
adapter?: FileExplorerAdapter;
|
|
264
|
+
currentPath?: string;
|
|
265
|
+
getAppIconUrl?: (item: FileItem) => string | undefined;
|
|
266
|
+
onOpen?: (item: FileItem) => void;
|
|
267
|
+
onSelectionChange?: (ids: Set<string>, items: FileItem[]) => void;
|
|
268
|
+
onContextMenu?: (event: React.MouseEvent, item: FileItem) => void;
|
|
269
|
+
onContextMenuEmpty?: (event: React.MouseEvent) => void;
|
|
270
|
+
onRename?: (item: FileItem, newName: string) => void;
|
|
271
|
+
onSortChange?: (config: SortConfig) => void;
|
|
272
|
+
onMove?: (sourceIds: string[], targetId: string) => void;
|
|
273
|
+
}
|
|
274
|
+
interface FileListViewHandle {
|
|
275
|
+
clearSelection: () => void;
|
|
276
|
+
startRename: (id: string) => void;
|
|
277
|
+
selectAll: () => void;
|
|
278
|
+
selectedIds: Set<string>;
|
|
279
|
+
selectedItems: FileItem[];
|
|
280
|
+
}
|
|
281
|
+
declare const FileListView: react.ForwardRefExoticComponent<FileListViewProps & react.RefAttributes<FileListViewHandle>>;
|
|
282
|
+
|
|
283
|
+
interface SidebarSection {
|
|
284
|
+
id: string;
|
|
285
|
+
title: string;
|
|
286
|
+
items: SidebarItem[];
|
|
287
|
+
}
|
|
288
|
+
interface FileSidebarProps {
|
|
289
|
+
sections: SidebarSection[];
|
|
290
|
+
activeId?: string;
|
|
291
|
+
onNavigate?: (item: SidebarItem) => void;
|
|
292
|
+
}
|
|
293
|
+
declare function FileSidebar({ sections, activeId, onNavigate }: FileSidebarProps): react_jsx_runtime.JSX.Element;
|
|
294
|
+
|
|
295
|
+
interface ToolbarProps {
|
|
296
|
+
canGoBack?: boolean;
|
|
297
|
+
canGoForward?: boolean;
|
|
298
|
+
breadcrumbs?: BreadcrumbItem[];
|
|
299
|
+
viewMode?: 'grid' | 'list';
|
|
300
|
+
searchQuery?: string;
|
|
301
|
+
showSearch?: boolean;
|
|
302
|
+
showViewToggle?: boolean;
|
|
303
|
+
draggable?: boolean;
|
|
304
|
+
onBack?: () => void;
|
|
305
|
+
onForward?: () => void;
|
|
306
|
+
onBreadcrumbNavigate?: (item: BreadcrumbItem) => void;
|
|
307
|
+
onViewModeChange?: (mode: 'grid' | 'list') => void;
|
|
308
|
+
onSearchQueryChange?: (query: string) => void;
|
|
309
|
+
children?: React.ReactNode;
|
|
310
|
+
breadcrumbSlot?: React.ReactNode;
|
|
311
|
+
actionsSlot?: React.ReactNode;
|
|
312
|
+
}
|
|
313
|
+
declare function Toolbar({ canGoBack, canGoForward, breadcrumbs, viewMode, searchQuery, showSearch, showViewToggle, draggable, onBack, onForward, onBreadcrumbNavigate, onViewModeChange, onSearchQueryChange, children, breadcrumbSlot, actionsSlot, }: ToolbarProps): react_jsx_runtime.JSX.Element;
|
|
314
|
+
|
|
315
|
+
interface BreadcrumbProps {
|
|
316
|
+
items: BreadcrumbItem[];
|
|
317
|
+
onNavigate?: (item: BreadcrumbItem, index: number) => void;
|
|
318
|
+
}
|
|
319
|
+
declare function Breadcrumb({ items, onNavigate }: BreadcrumbProps): react_jsx_runtime.JSX.Element;
|
|
320
|
+
|
|
321
|
+
interface StatusBarProps {
|
|
322
|
+
itemCount?: number;
|
|
323
|
+
selectedCount?: number;
|
|
324
|
+
children?: React.ReactNode;
|
|
325
|
+
}
|
|
326
|
+
declare function StatusBar({ itemCount, selectedCount, children }: StatusBarProps): react_jsx_runtime.JSX.Element;
|
|
327
|
+
|
|
328
|
+
interface FileIconProps {
|
|
329
|
+
type: FileType;
|
|
330
|
+
name?: string;
|
|
331
|
+
className?: string;
|
|
332
|
+
size?: number;
|
|
333
|
+
}
|
|
334
|
+
declare function FileIcon({ type, name, className, size }: FileIconProps): react_jsx_runtime.JSX.Element;
|
|
335
|
+
|
|
336
|
+
interface FileGridProps {
|
|
337
|
+
items: FileItem[];
|
|
338
|
+
selectedIds: Set<string>;
|
|
339
|
+
editingId?: string | null;
|
|
340
|
+
dragOverId?: string | null;
|
|
341
|
+
getAppIconUrl?: (item: FileItem) => string | undefined;
|
|
342
|
+
onSelect?: (item: FileItem, e: React.MouseEvent) => void;
|
|
343
|
+
onOpen?: (item: FileItem) => void;
|
|
344
|
+
onContextMenu?: (item: FileItem, e: React.MouseEvent) => void;
|
|
345
|
+
onContextMenuEmpty?: (e: React.MouseEvent) => void;
|
|
346
|
+
onNameClick?: (item: FileItem, e: React.MouseEvent) => void;
|
|
347
|
+
onRename?: (item: FileItem, newName: string) => void;
|
|
348
|
+
onRenameCancel?: (item: FileItem) => void;
|
|
349
|
+
onDragStart?: (e: React.DragEvent, item: FileItem) => void;
|
|
350
|
+
onDragOver?: (e: React.DragEvent, item: FileItem) => void;
|
|
351
|
+
onDragLeave?: (e: React.DragEvent) => void;
|
|
352
|
+
onDrop?: (e: React.DragEvent, item: FileItem) => void;
|
|
353
|
+
onThumbnailError?: (item: FileItem, e: React.SyntheticEvent<HTMLImageElement, Event>) => void;
|
|
354
|
+
}
|
|
355
|
+
declare function FileGrid({ items, selectedIds, editingId, dragOverId, getAppIconUrl, onSelect, onOpen, onContextMenu, onContextMenuEmpty, onNameClick, onRename, onRenameCancel, onDragStart, onDragOver, onDragLeave, onDrop, onThumbnailError, }: FileGridProps): react_jsx_runtime.JSX.Element;
|
|
356
|
+
|
|
357
|
+
interface FileListProps {
|
|
358
|
+
items: FileItem[];
|
|
359
|
+
selectedIds: Set<string>;
|
|
360
|
+
sortConfig?: SortConfig;
|
|
361
|
+
editingId?: string | null;
|
|
362
|
+
dragOverId?: string | null;
|
|
363
|
+
onSelect?: (item: FileItem, e: React.MouseEvent) => void;
|
|
364
|
+
onOpen?: (item: FileItem) => void;
|
|
365
|
+
onContextMenu?: (item: FileItem, e: React.MouseEvent) => void;
|
|
366
|
+
onContextMenuEmpty?: (e: React.MouseEvent) => void;
|
|
367
|
+
onNameClick?: (item: FileItem, e: React.MouseEvent) => void;
|
|
368
|
+
onRename?: (item: FileItem, newName: string) => void;
|
|
369
|
+
onRenameCancel?: (item: FileItem) => void;
|
|
370
|
+
onSort?: (field: string) => void;
|
|
371
|
+
onDragStart?: (e: React.DragEvent, item: FileItem) => void;
|
|
372
|
+
onDragOver?: (e: React.DragEvent, item: FileItem) => void;
|
|
373
|
+
onDragLeave?: (e: React.DragEvent) => void;
|
|
374
|
+
onDrop?: (e: React.DragEvent, item: FileItem) => void;
|
|
375
|
+
}
|
|
376
|
+
declare function FileList({ items, selectedIds, sortConfig, editingId, dragOverId, onSelect, onOpen, onContextMenu, onContextMenuEmpty, onNameClick, onRename, onRenameCancel, onSort, onDragStart, onDragOver, onDragLeave, onDrop, }: FileListProps): react_jsx_runtime.JSX.Element;
|
|
377
|
+
|
|
378
|
+
interface ContextMenuProps {
|
|
379
|
+
visible: boolean;
|
|
380
|
+
x: number;
|
|
381
|
+
y: number;
|
|
382
|
+
options: ContextMenuItem[];
|
|
383
|
+
onClose?: () => void;
|
|
384
|
+
onSelect?: (option: ContextMenuItem) => void;
|
|
385
|
+
}
|
|
386
|
+
declare function ContextMenu({ visible, x, y, options, onClose, onSelect, }: ContextMenuProps): react.ReactPortal | null;
|
|
387
|
+
|
|
388
|
+
interface SortIndicatorProps {
|
|
389
|
+
direction: 'asc' | 'desc';
|
|
390
|
+
}
|
|
391
|
+
declare function SortIndicator({ direction }: SortIndicatorProps): react_jsx_runtime.JSX.Element;
|
|
392
|
+
|
|
393
|
+
interface WindowProps {
|
|
394
|
+
title?: string;
|
|
395
|
+
showTitleBar?: boolean;
|
|
396
|
+
showMinimize?: boolean;
|
|
397
|
+
showMaximize?: boolean;
|
|
398
|
+
draggable?: boolean;
|
|
399
|
+
resizable?: boolean;
|
|
400
|
+
width?: string | number;
|
|
401
|
+
height?: string | number;
|
|
402
|
+
minWidth?: string | number;
|
|
403
|
+
minHeight?: string | number;
|
|
404
|
+
maxWidth?: string | number;
|
|
405
|
+
maxHeight?: string | number;
|
|
406
|
+
closeOnBackdrop?: boolean;
|
|
407
|
+
fitContent?: boolean;
|
|
408
|
+
onClose?: () => void;
|
|
409
|
+
onMinimize?: () => void;
|
|
410
|
+
onMaximize?: () => void;
|
|
411
|
+
children?: React.ReactNode;
|
|
412
|
+
titleSlot?: React.ReactNode;
|
|
413
|
+
actionsSlot?: React.ReactNode;
|
|
414
|
+
}
|
|
415
|
+
declare function Window({ title, showTitleBar, showMinimize, showMaximize, draggable, resizable, closeOnBackdrop, width, height, minWidth, minHeight, maxWidth, maxHeight, fitContent, onClose, onMinimize, onMaximize, children, titleSlot, actionsSlot, }: WindowProps): react.ReactPortal;
|
|
416
|
+
|
|
417
|
+
type CompressDialogOptions = Omit<CompressOptions, 'outputDir'>;
|
|
418
|
+
interface CompressDialogProps {
|
|
419
|
+
visible: boolean;
|
|
420
|
+
/** 要压缩的文件/文件夹路径列表 */
|
|
421
|
+
filePaths: string[];
|
|
422
|
+
/** 输出目录 */
|
|
423
|
+
outputDir: string;
|
|
424
|
+
onConfirm: (options: CompressDialogOptions) => void;
|
|
425
|
+
onCancel: () => void;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* 压缩对话框组件
|
|
429
|
+
*/
|
|
430
|
+
declare function CompressDialog({ visible, filePaths, outputDir, onConfirm, onCancel, }: CompressDialogProps): react.ReactPortal | null;
|
|
431
|
+
|
|
432
|
+
/** 进度状态 */
|
|
433
|
+
type ProgressStatus = 'pending' | 'processing' | 'success' | 'error';
|
|
434
|
+
/** 进度信息 */
|
|
435
|
+
interface ProgressInfo {
|
|
436
|
+
/** 操作类型 */
|
|
437
|
+
type: 'compress' | 'extract';
|
|
438
|
+
/** 状态 */
|
|
439
|
+
status: ProgressStatus;
|
|
440
|
+
/** 进度百分比 0-100 */
|
|
441
|
+
percent: number;
|
|
442
|
+
/** 当前处理的文件 */
|
|
443
|
+
currentFile?: string;
|
|
444
|
+
/** 已处理文件数 */
|
|
445
|
+
processedCount?: number;
|
|
446
|
+
/** 总文件数 */
|
|
447
|
+
totalCount?: number;
|
|
448
|
+
/** 错误信息 */
|
|
449
|
+
error?: string;
|
|
450
|
+
/** 输出路径 */
|
|
451
|
+
outputPath?: string;
|
|
452
|
+
}
|
|
453
|
+
interface ProgressDialogProps {
|
|
454
|
+
visible: boolean;
|
|
455
|
+
progress: ProgressInfo;
|
|
456
|
+
onCancel?: () => void;
|
|
457
|
+
onClose?: () => void;
|
|
458
|
+
/** 打开输出文件夹 */
|
|
459
|
+
onOpenFolder?: (path: string) => void;
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* 进度对话框组件
|
|
463
|
+
*/
|
|
464
|
+
declare function ProgressDialog({ visible, progress, onCancel, onClose, onOpenFolder, }: ProgressDialogProps): react.ReactPortal | null;
|
|
465
|
+
|
|
466
|
+
interface FileInfoDialogProps {
|
|
467
|
+
/** 是否显示 */
|
|
468
|
+
visible: boolean;
|
|
469
|
+
/** 文件项 */
|
|
470
|
+
item: FileItem | null;
|
|
471
|
+
/** 关闭回调 */
|
|
472
|
+
onClose: () => void;
|
|
473
|
+
}
|
|
474
|
+
declare function FileInfoDialog({ visible, item, onClose }: FileInfoDialogProps): react_jsx_runtime.JSX.Element | null;
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* 文件选择状态管理
|
|
478
|
+
*/
|
|
479
|
+
declare function useSelection(): {
|
|
480
|
+
selectedIds: Set<string>;
|
|
481
|
+
lastSelectedId: string | null;
|
|
482
|
+
editingId: string | null;
|
|
483
|
+
clearSelection: () => void;
|
|
484
|
+
selectItem: (id: string | null, items: FileItem[], multi?: boolean, range?: boolean) => void;
|
|
485
|
+
selectAll: (items: FileItem[]) => void;
|
|
486
|
+
setEditing: (id: string | null) => void;
|
|
487
|
+
isSelected: (id: string) => boolean;
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* 拖拽操作管理
|
|
492
|
+
*/
|
|
493
|
+
declare function useDragAndDrop(getSelectedIds: () => Set<string>, onSelect: (id: string, multi: boolean, range: boolean) => void, onMove: (targetFolderId: string, itemIds: Set<string>) => void): {
|
|
494
|
+
dragOverId: string | null;
|
|
495
|
+
isDragging: boolean;
|
|
496
|
+
handleDragStart: (e: React.DragEvent, itemId: string) => void;
|
|
497
|
+
handleDragOver: (e: React.DragEvent, item: FileItem) => void;
|
|
498
|
+
handleDragLeave: () => void;
|
|
499
|
+
handleDrop: (e: React.DragEvent, targetItem: FileItem) => void;
|
|
500
|
+
handleDragEnd: () => void;
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* 媒体播放器功能管理
|
|
505
|
+
*/
|
|
506
|
+
declare function useMediaPlayer(mediaType: FileType, mediaRef: React.RefObject<HTMLVideoElement | HTMLAudioElement>): {
|
|
507
|
+
isPlaying: boolean;
|
|
508
|
+
progress: number;
|
|
509
|
+
currentTime: number;
|
|
510
|
+
duration: number;
|
|
511
|
+
isMuted: boolean;
|
|
512
|
+
volume: number;
|
|
513
|
+
showControls: boolean;
|
|
514
|
+
isAudio: boolean;
|
|
515
|
+
togglePlay: () => void;
|
|
516
|
+
toggleMute: () => void;
|
|
517
|
+
handleVolumeChange: (val: number) => void;
|
|
518
|
+
seekTo: (time: number) => void;
|
|
519
|
+
formatTime: (time: number) => string;
|
|
520
|
+
autoPlay: () => void;
|
|
521
|
+
updateProgress: () => void;
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* 窗口拖拽功能管理
|
|
526
|
+
*/
|
|
527
|
+
declare function useWindowDrag(): {
|
|
528
|
+
position: {
|
|
529
|
+
x: number;
|
|
530
|
+
y: number;
|
|
531
|
+
};
|
|
532
|
+
isDragging: boolean;
|
|
533
|
+
startDrag: (e: React.MouseEvent) => void;
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
type ResizeDirection = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw';
|
|
537
|
+
/**
|
|
538
|
+
* 窗口调整大小功能管理
|
|
539
|
+
*/
|
|
540
|
+
declare function useWindowResize(initialWidth: number, initialHeight: number, minWidth: number, minHeight: number, maxWidth: number, maxHeight: number): {
|
|
541
|
+
width: number;
|
|
542
|
+
height: number;
|
|
543
|
+
isResizing: boolean;
|
|
544
|
+
startResize: (e: React.MouseEvent, direction: ResizeDirection, currentWidth: number, currentHeight: number) => void;
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
declare global {
|
|
548
|
+
interface Window {
|
|
549
|
+
fileExplorerAPI?: {
|
|
550
|
+
getApplicationIcon?: (appPath: string) => Promise<string | null>;
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* 应用程序图标管理 hook
|
|
556
|
+
*/
|
|
557
|
+
declare function useApplicationIcon(items: FileItem[]): {
|
|
558
|
+
getAppIconUrl: (item: FileItem) => string | undefined;
|
|
559
|
+
loadApplicationIcon: (item: FileItem) => Promise<void>;
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
export { Breadcrumb, type BreadcrumbItem, CompressDialog, type CompressFormat, type CompressLevel, type CompressOptions, type CompressProgress, type CompressResult, ContextMenu, type ContextMenuItem, type ExtractOptions, type FileExplorerAdapter, FileGrid, FileIcon, FileInfoDialog, type FileInfoDialogProps, type FileItem, FileList, FileListView, type FileListViewHandle, FileSidebar, FileType, type MediaMetadata, type MediaTranscodeProgress, type OperationResult, ProgressDialog, type ProgressInfo, type ProgressStatus, type SidebarItem, type SortConfig, SortIndicator, StatusBar, Toolbar, type TranscodeInfo, type TranscodeMethod, type TranscodeStatus, type ViewMode, type WatchEvent, type WatchEventType, Window, useApplicationIcon, useDragAndDrop, useMediaPlayer, useSelection, useWindowDrag, useWindowResize };
|