diff --git a/src/web/binaryUpload.coffee b/src/web/binaryUpload.coffee index 81e5ecb..1788339 100644 --- a/src/web/binaryUpload.coffee +++ b/src/web/binaryUpload.coffee @@ -1,125 +1,87 @@ -import React from "react" -import Dropzone from "react-dropzone" +import React, { useState, useCallback } from "react" +import { useDropzone } from "react-dropzone" import HelpButton from "./helpButton" import LinkButton from "./util/linkButton" +import * as hooks from "./hooks" import * as crypto from "../crypto" import * as util from "../util" -class BinaryUpload extends React.Component - constructor: (props) -> - super props - @state = - file: null - uploading: false - progress: 0 - encrypt: false - encrypting: false +export default BinaryUpload = -> + [openDialog, renderDialog] = hooks.useDialog() + [encrypt, toggleEncrypt] = hooks.useToggle false + [encrypting, setEncrypting] = useState false + [file, setFile] = useState null - onDrop: (files) => - @setState - file: files[0] + # Paste hook and event + clearFile = (status) -> + setFile null if status == 200 + [doPaste, pasting, progress] = hooks.usePaste openDialog, + useCallback clearFile, [] - doUpload: => - key = null - iv = null - @setState - uploading: true - encrypting: @state.encrypt - progress: 0 - # Due to the lack of progress feature in current Fetch API - # We have to use XHR for now. Dang. - xhr = new XMLHttpRequest() - xhr.upload.addEventListener "progress", (e) => - if e.lengthComputable - @setState - progress: e.loaded / e.total - xhr.addEventListener "readystatechange", => - if xhr.readyState == XMLHttpRequest.DONE - @setState - uploading: false - encrypting: false - file: null - @props.openDialog do => - if xhr.status == 200 - url = if not @state.encrypt - xhr.responseText - else - xhr.responseText + "?crypt#" + key + "+" + iv - - https://{window.location.hostname}{url} - - else - xhr.responseText + # Dropzone hook and event + onDrop = (files) -> + setFile files[0] + {getRootProps, getInputProps, isDragActive} = useDropzone + onDrop: useCallback onDrop, [] - if not @state.encrypt - xhr.open 'PUT', '/paste/' + @state.file.name - xhr.send @state.file + # Upload handler, we basically extend the Paste hook with encryption + doUpload = -> + if not encrypt + doPaste file.name, file.type, file else - [key, iv, name, mime, encrypted] = await crypto.encryptFile @state.file - xhr.open 'PUT', '/paste/' + name - xhr.setRequestHeader 'content-type', mime - xhr.send encrypted - @setState - encrypting: false + # Handle encryption + setEncrypting true + [key, iv, name, mime, encrypted] = await crypto.encryptFile file + setEncrypting false + doPaste name, mime, encrypted, (url) -> + url + "?crypt#" + key + "+" + iv + doUpload = useCallback doUpload, [file, encrypt, doPaste] - progressText: -> - util.progressText @state.progress - - toggleEncrypt: => - @setState (state, props) -> - { encrypt: not state.encrypt } - - render: -> -
Drag 'n' drop a file here to upload, or click to select
-Drag 'n' drop a file here to upload, or click to select