From e8bd7c1eb7fc944a2aaad72ee45d4977eb311f04 Mon Sep 17 00:00:00 2001 From: Franklin Waller Date: Mon, 4 Nov 2019 14:27:31 +0100 Subject: [PATCH] feat(explorer): Add support for uploading files --- src/js/apps/Explorer/Explorer.scss | 2 ++ src/js/apps/Explorer/Explorer.tsx | 6 ++-- .../apps/Explorer/components/File/File.scss | 1 + .../Explorer/components/Folder/Folder.scss | 1 + .../molecules/Dropzone/Dropzone.tsx | 33 +++++++++++++++++++ src/js/components/molecules/Dropzone/index.ts | 1 + src/js/services/FileReaderService.ts | 25 ++++++++++++++ 7 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 src/js/components/molecules/Dropzone/Dropzone.tsx create mode 100644 src/js/components/molecules/Dropzone/index.ts create mode 100644 src/js/services/FileReaderService.ts diff --git a/src/js/apps/Explorer/Explorer.scss b/src/js/apps/Explorer/Explorer.scss index 87fc904..6edd6da 100644 --- a/src/js/apps/Explorer/Explorer.scss +++ b/src/js/apps/Explorer/Explorer.scss @@ -2,6 +2,8 @@ display: flex; // justify-content: space-evenly; flex-flow: wrap; + height: 100%; + outline: none; } .toolbarButton { diff --git a/src/js/apps/Explorer/Explorer.tsx b/src/js/apps/Explorer/Explorer.tsx index 9dedd8a..392484c 100644 --- a/src/js/apps/Explorer/Explorer.tsx +++ b/src/js/apps/Explorer/Explorer.tsx @@ -16,7 +16,7 @@ import WasmFs from "@wasmer/wasmfs"; import Folder from './components/Folder'; import File from './components/File'; import Dirent from 'memfs/lib/Dirent'; -import { useDropzone } from 'react-dropzone' +import Dropzone from '../../components/molecules/Dropzone'; const styles = require('./Explorer.scss'); export default function Explorer() { @@ -93,7 +93,7 @@ export default function Explorer() { }> -
+ {files.map((file) => { if (file.isDirectory()) { return @@ -101,7 +101,7 @@ export default function Explorer() { return } })} -
+ ); diff --git a/src/js/apps/Explorer/components/File/File.scss b/src/js/apps/Explorer/components/File/File.scss index 7fa15c3..cffa562 100644 --- a/src/js/apps/Explorer/components/File/File.scss +++ b/src/js/apps/Explorer/components/File/File.scss @@ -3,6 +3,7 @@ flex-direction: column; align-items: center; width: 25%; + height: 200px; } .iconWrapper { diff --git a/src/js/apps/Explorer/components/Folder/Folder.scss b/src/js/apps/Explorer/components/Folder/Folder.scss index 8a46886..8561dd8 100644 --- a/src/js/apps/Explorer/components/Folder/Folder.scss +++ b/src/js/apps/Explorer/components/Folder/Folder.scss @@ -3,6 +3,7 @@ flex-direction: column; align-items: center; width: 25%; + height: 200px; } .icon { diff --git a/src/js/components/molecules/Dropzone/Dropzone.tsx b/src/js/components/molecules/Dropzone/Dropzone.tsx new file mode 100644 index 0000000..39ad38c --- /dev/null +++ b/src/js/components/molecules/Dropzone/Dropzone.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; +import { useDropzone } from 'react-dropzone'; +import WasmFs from "@wasmer/wasmfs"; +import InstanceBag from '../../../InstanceBag'; +import { readFileAsArrayBuffer } from '../../../services/FileReaderService'; + +interface Props { + className?: string; + currentPath: string; + children: React.ReactNode; +} + +export default function Dropzone(props: Props) { + const onDrop = React.useCallback(async (acceptedFiles: File[]) => { + const wasmFs = InstanceBag.get('fs'); + const promises = acceptedFiles.map(file => readFileAsArrayBuffer(file)); + const processedFiles = await Promise.all(promises); + + processedFiles.forEach((file) => { + const path = `${props.currentPath}/${file.name}`; + wasmFs.fs.writeFileSync(path, new Uint8Array(file.bin)); + }); + }, [props.currentPath]); + + const { getInputProps, getRootProps, isDragActive } = useDropzone({ onDrop, noClick: true }); + + return ( +
+ + {props.children} +
+ ); +} diff --git a/src/js/components/molecules/Dropzone/index.ts b/src/js/components/molecules/Dropzone/index.ts new file mode 100644 index 0000000..fe6aee3 --- /dev/null +++ b/src/js/components/molecules/Dropzone/index.ts @@ -0,0 +1 @@ +export { default } from './Dropzone'; diff --git a/src/js/services/FileReaderService.ts b/src/js/services/FileReaderService.ts new file mode 100644 index 0000000..e4ff5d6 --- /dev/null +++ b/src/js/services/FileReaderService.ts @@ -0,0 +1,25 @@ +interface ProcessedFile { + name: string; + size: number; + bin: ArrayBuffer; +} + +export function readFileAsArrayBuffer(file: File): Promise { + return new Promise((resolve, reject) => { + const fileReader = new FileReader(); + + fileReader.onerror = (error) => { + reject(error); + } + + fileReader.onload = () => { + resolve({ + name: file.name, + size: file.size, + bin: fileReader.result, + }); + } + + fileReader.readAsArrayBuffer(file); + }); +}