diff --git a/src/assets/svgs/bxs--file-export.svg b/src/assets/svgs/bxs--file-export.svg
new file mode 100644
index 0000000..72a4578
--- /dev/null
+++ b/src/assets/svgs/bxs--file-export.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/filehandle/components/FileContent.tsx b/src/filehandle/components/FileContent.tsx
index 8f991f2..18ced19 100644
--- a/src/filehandle/components/FileContent.tsx
+++ b/src/filehandle/components/FileContent.tsx
@@ -13,7 +13,7 @@ import AddFileModal from './AddFileModal';
import { FileSystemContext } from './FilePanel';
import styles from './styles/FileContent.module.less';
import type { FileInfo } from '../utils/fileManager';
-import { FileType } from '../utils/fileManager';
+import { exportDirectory, exportFile, FileType } from '../utils/fileManager';
import { fileOperationWarning } from '../utils/operationWarning';
function MountWebdavModal(props: { open: boolean; close(): void }) {
@@ -270,6 +270,22 @@ const FileContent: React.FC = (props) => {
});
};
+ const handleExportFile = async () => {
+ const curr = selection[0];
+
+ if (!curr) return void 0;
+
+ try {
+ await (curr.handle.kind === 'directory'
+ ? exportDirectory(curr.handle)
+ : exportFile(curr.handle));
+
+ success(`已为你导出文件 ${curr.name}。`);
+ } catch (err) {
+ error((err as Error).message);
+ }
+ };
+
const handleOk = async (name: string, type: FileType) => {
try {
await create(name, type);
@@ -334,6 +350,14 @@ const FileContent: React.FC = (props) => {
icon: ,
onClick: importDirectory
},
+ {
+ name: '导出文件',
+ icon: ,
+ style: {
+ display: selection.length ? void 0 : 'none'
+ },
+ onClick: handleExportFile
+ },
{
name: '删除',
icon: ,
diff --git a/src/filehandle/utils/fileManager.ts b/src/filehandle/utils/fileManager.ts
index 15bedbf..a472071 100644
--- a/src/filehandle/utils/fileManager.ts
+++ b/src/filehandle/utils/fileManager.ts
@@ -69,8 +69,6 @@ export async function getHandleType(handle: DH | FH) {
}
export async function importFile(directory: DH, options?: FilePickerOptions) {
- if (!window.showOpenFilePicker) return false;
-
const files = await window.showOpenFilePicker(options);
await Promise.all(
@@ -81,8 +79,6 @@ export async function importFile(directory: DH, options?: FilePickerOptions) {
}
export async function importDirectory(directory: DH, options?: DirectoryPickerOptions) {
- if (!window.showDirectoryPicker) return false;
-
const folder = await window.showDirectoryPicker(options);
await move(folder, await createDirectory(directory, folder.name));
@@ -90,6 +86,25 @@ export async function importDirectory(directory: DH, options?: DirectoryPickerOp
return true;
}
+export async function exportFile(file: FH) {
+ const handle = await window.showSaveFilePicker({
+ suggestedName: file.name,
+ types: [{ description: 'export file', accept: {} }]
+ });
+
+ await writeFile(handle, await file.getFile());
+
+ return true;
+}
+
+export async function exportDirectory(directory: DH) {
+ const handle = await window.showDirectoryPicker({ mode: 'readwrite' });
+
+ await moveDirectoryWithSelf(directory, handle);
+
+ return true;
+}
+
export async function writeFile(file: FH, data: FileDataType) {
const writable = await file.createWritable();
await writable.write(data);
@@ -123,15 +138,24 @@ export async function moveFile(origin: DH, target: DH, name: string, copy = true
return handle;
}
+export async function moveDirectoryWithSelf(origin: DH, target: DH) {
+ const _target = await target.getDirectoryHandle(origin.name, { create: true });
+
+ await move(origin, _target);
+
+ return true;
+}
+
export async function moveDirectory(origin: DH, target: DH, name: string, copy = true) {
const _origin = await origin.getDirectoryHandle(name);
const _target = await createDirectory(target, name);
- for await (const [key, handle] of _origin.entries()) {
+ const entries = _origin.entries();
+ for await (const [key, handle] of entries) {
if ((await getHandleType(handle)) === FileType.FILE) {
- return await moveFile(_origin, _target, key, copy);
+ await moveFile(_origin, _target, key, copy);
} else {
- return await moveDirectory(_origin, _target, key);
+ await moveDirectory(_origin, _target, key);
}
}
diff --git a/types/filesystem.d.ts b/types/filesystem.d.ts
index 987c520..8f8f0b2 100644
--- a/types/filesystem.d.ts
+++ b/types/filesystem.d.ts
@@ -99,7 +99,7 @@ declare interface SaveFilePickerOptions {
}
declare interface Window {
- showDirectoryPicker: (options?: DirectoryPickerOptions) => Promise;
+ showDirectoryPicker(options?: DirectoryPickerOptions): Promise;
showOpenFilePicker(options?: FilePickerOptions): Promise;
showSaveFilePicker(options?: SaveFilePickerOptions): Promise;
}