diff --git a/components/system/Files/FileManager.tsx b/components/system/Files/FileManager.tsx
index 479d6f1c..3303626e 100644
--- a/components/system/Files/FileManager.tsx
+++ b/components/system/Files/FileManager.tsx
@@ -1,4 +1,5 @@
import FileEntry from 'components/system/Files/FileEntry';
+import useFileDrop from 'hooks/useFileDrop';
import useFiles from 'hooks/useFiles';
import { basename, extname, resolve } from 'path';
import StyledFileManager from 'styles/components/system/Files/StyledFileManager';
@@ -7,16 +8,20 @@ type FileManagerProps = {
directory: string;
};
-const FileManager = ({ directory }: FileManagerProps): JSX.Element => (
-
- {useFiles(directory, (file) => (
-
- ))}
-
-);
+const FileManager = ({ directory }: FileManagerProps): JSX.Element => {
+ const { files, getFiles } = useFiles(directory);
+
+ return (
+
+ {files.map((file) => (
+
+ ))}
+
+ );
+};
export default FileManager;
diff --git a/hooks/useFileDrop.ts b/hooks/useFileDrop.ts
new file mode 100644
index 00000000..95a7770c
--- /dev/null
+++ b/hooks/useFileDrop.ts
@@ -0,0 +1,42 @@
+import { useFileSystem } from 'contexts/fileSystem';
+import { useCallback } from 'react';
+
+const haltDragEvent = (event: React.DragEvent): void => {
+ event.preventDefault();
+ event.stopPropagation();
+};
+
+type FileDrop = {
+ onDragOver: (event: React.DragEvent) => void;
+ onDrop: (event: React.DragEvent) => void;
+};
+
+const useFileDrop = (directory: string, getFiles: () => void): FileDrop => {
+ const { fs } = useFileSystem();
+ const onDrop = useCallback(
+ (event: React.DragEvent) => {
+ haltDragEvent(event);
+
+ const { files: [file] = [] } = event.dataTransfer || {};
+ const reader = new FileReader();
+
+ reader.onload = ({ target }) => {
+ fs?.writeFile(
+ `${directory}/${file.name}`,
+ Buffer.from(new Uint8Array(target?.result as ArrayBuffer)),
+ getFiles
+ );
+ };
+
+ reader.readAsArrayBuffer(file);
+ },
+ [directory, fs, getFiles]
+ );
+
+ return {
+ onDragOver: haltDragEvent,
+ onDrop
+ };
+};
+
+export default useFileDrop;
diff --git a/hooks/useFiles.ts b/hooks/useFiles.ts
index 16a167f7..4ba9ba03 100644
--- a/hooks/useFiles.ts
+++ b/hooks/useFiles.ts
@@ -1,20 +1,25 @@
import { useFileSystem } from 'contexts/fileSystem';
-import { useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
-const useFiles = (
- directory: string,
- callback: (file: string) => JSX.Element
-): JSX.Element[] => {
+type Files = {
+ files: string[];
+ getFiles: () => void;
+};
+
+const useFiles = (directory: string): Files => {
const [files, setFiles] = useState([]);
const { fs } = useFileSystem();
+ const getFiles = useCallback(
+ () => fs?.readdir(directory, (_error, contents = []) => setFiles(contents)),
+ [directory, fs]
+ );
- useEffect(() => {
- if (fs) {
- fs.readdir(directory, (_error, contents = []) => setFiles(contents));
- }
- }, [directory, fs]);
+ useEffect(getFiles, [getFiles]);
- return files.map(callback);
+ return {
+ files,
+ getFiles
+ };
};
export default useFiles;
diff --git a/tsconfig.json b/tsconfig.json
index cf575c7e..a8aceb89 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,6 +1,7 @@
{
"compilerOptions": {
"baseUrl": ".",
+ "downlevelIteration": true,
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,