form upload
This commit is contained in:
parent
c5c7c7f809
commit
f9d3d8b7f3
|
@ -1,10 +1,10 @@
|
|||
/** @jsx jsx */
|
||||
import * as R from "ramda"
|
||||
import { useCallback, useState } from "react"
|
||||
import { useCallback, useState, useRef } from "react"
|
||||
import { useDropzone } from "react-dropzone"
|
||||
import { Box, Flex, jsx } from "theme-ui"
|
||||
import { CircularProgress } from "@material-ui/core"
|
||||
|
||||
import { CircularProgress, Button } from "@material-ui/core"
|
||||
import { saveAs } from "file-saver"
|
||||
/**
|
||||
* nginx is setup to automatically handle and rewrite the url path.
|
||||
*/
|
||||
|
@ -18,83 +18,62 @@ const splitFilename = R.compose(R.head, R.split(".sia"))
|
|||
function MyDropzone() {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState(null)
|
||||
const formRef = useRef(null)
|
||||
const inputRef = useRef(null)
|
||||
|
||||
const onDrop = useCallback(
|
||||
acceptedFiles => {
|
||||
setLoading(true)
|
||||
const file = R.head(acceptedFiles)
|
||||
const fd = new FormData()
|
||||
const fd = new FormData(formRef.current)
|
||||
const fileName = R.compose(splitFilename, pName)(file)
|
||||
|
||||
fd.append("file", file)
|
||||
if (window) {
|
||||
const streamSaver = require("streamsaver")
|
||||
console.log("streamSaver", streamSaver)
|
||||
const url = API_ENDPOINT + "/siafile"
|
||||
fetch(url, {
|
||||
method: "POST",
|
||||
body: fd,
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*"
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
if (!res.ok) {
|
||||
setLoading(false)
|
||||
setError(res.status + " " + res.statusText)
|
||||
return
|
||||
}
|
||||
const readableStream = res.body
|
||||
const fileStream = streamSaver.createWriteStream(fileName)
|
||||
const url = API_ENDPOINT + "/siafile"
|
||||
|
||||
// more optimized
|
||||
if (window.WritableStream && readableStream.pipeTo) {
|
||||
return readableStream.pipeTo(fileStream).then(() => {
|
||||
setLoading(false)
|
||||
console.log("done writing")
|
||||
})
|
||||
}
|
||||
;(window as any).writer = fileStream.getWriter()
|
||||
const reader = res.body.getReader()
|
||||
const pump = () =>
|
||||
reader
|
||||
.read()
|
||||
.then(res =>
|
||||
res.done
|
||||
? (window as any).writer.close()
|
||||
: (window as any).writer.write(res.value).then(pump)
|
||||
)
|
||||
.catch(e => {
|
||||
setLoading(false)
|
||||
})
|
||||
pump()
|
||||
})
|
||||
.catch(e => {
|
||||
// setError(e)
|
||||
console.log("error is", e)
|
||||
setLoading(false)
|
||||
})
|
||||
}
|
||||
// formRef.current.submit()
|
||||
|
||||
// fetch(url, {
|
||||
// method: "POST",
|
||||
// body: fd,
|
||||
// credentials: "include"
|
||||
// })
|
||||
// .then(res => {
|
||||
// return res.headers
|
||||
// })
|
||||
// .then(headers => {
|
||||
// console.log("WE OUT HERE BOYS", document.cookie)
|
||||
// fetch(API_ENDPOINT + "/siafile/download", {
|
||||
// credentials: "include"
|
||||
// })
|
||||
// .then(res => res.blob())
|
||||
// .then(blob => saveAs(blob, fileName))
|
||||
// // saveAs(API_ENDPOINT + "/siafile/download", fileName)
|
||||
// })
|
||||
// .catch(e => {
|
||||
// console.log("error is", e)
|
||||
// setLoading(false)
|
||||
// })
|
||||
},
|
||||
[loading, setLoading, error, setError]
|
||||
[loading, setLoading, error, setError, formRef]
|
||||
)
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop })
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Flex
|
||||
{...getRootProps()}
|
||||
sx={{ height: 400, justifyContent: "center", alignItems: "center" }}
|
||||
>
|
||||
<input {...getInputProps()} />
|
||||
{error && error}
|
||||
{!error &&
|
||||
(loading ? (
|
||||
<CircularProgress color="secondary" />
|
||||
) : isDragActive ? (
|
||||
<p>Drop to 🚀 ...</p>
|
||||
) : (
|
||||
<p>Drag 'n' drop a Sia file here, or click to select a Sia file.</p>
|
||||
))}
|
||||
<form
|
||||
id="hidden-form"
|
||||
action={`${API_ENDPOINT}/siafile`}
|
||||
method="POST"
|
||||
encType="multipart/form-data"
|
||||
ref={formRef}
|
||||
>
|
||||
<input type="file" name="file" ref={inputRef} />
|
||||
<Button type="submit"> Download</Button>
|
||||
</form>
|
||||
</Flex>
|
||||
</Box>
|
||||
)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"cors": "2.8.5",
|
||||
"express": "^4.14.0",
|
||||
"express-fileupload": "1.1.6",
|
||||
"express-session": "1.17.0",
|
||||
"ramda": "0.26.1",
|
||||
"typescript": "^3.5.2"
|
||||
},
|
||||
|
|
|
@ -52,16 +52,24 @@ export class Server {
|
|||
private getPort = (): number => parseInt(process.env.PORT, 10) || 3000
|
||||
|
||||
private setRoutes = (): void => {
|
||||
this.app.use(cors())
|
||||
this.app.use(
|
||||
cors({
|
||||
origin: "http://localhost:*",
|
||||
credentials: true
|
||||
})
|
||||
)
|
||||
this.app.use(
|
||||
fileUpload({
|
||||
limits: { fileSize: 10 * 1024 * 1024 }
|
||||
})
|
||||
)
|
||||
this.app.post("/siafile", this.getSiaFile)
|
||||
this.app.post("/siafile", this.postSiaFile)
|
||||
this.app.get("/siafile/download", this.downloadSiaFile)
|
||||
}
|
||||
|
||||
private async getSiaFile(
|
||||
private async downloadSiaFile(req, res) {}
|
||||
|
||||
private async postSiaFile(
|
||||
req: express.Request & any,
|
||||
res: express.Response
|
||||
): Promise<express.Response> {
|
||||
|
@ -69,19 +77,33 @@ export class Server {
|
|||
try {
|
||||
const file: any = selectFile(req)
|
||||
|
||||
const { data: stream } = await siad.post("/renter/stream", file.data, {
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
},
|
||||
responseType: "stream"
|
||||
})
|
||||
const selectContentLength = R.path(["headers", "Content-Length"])
|
||||
const cl = selectContentLength(req)
|
||||
console.log("cl is", cl)
|
||||
|
||||
res.attachment(file.name)
|
||||
res.set("Content-Type", "application/octet-stream")
|
||||
console.log("file is", file)
|
||||
|
||||
const { data: stream, headers } = await siad.post(
|
||||
"/renter/stream",
|
||||
file.data,
|
||||
{
|
||||
responseType: "stream"
|
||||
}
|
||||
)
|
||||
const contentLength = headers["Content-Length"]
|
||||
|
||||
const pName = R.prop("name")
|
||||
const splitFilename = R.compose(R.head, R.split(".sia"))
|
||||
const fileName = R.compose(splitFilename, pName)(file)
|
||||
|
||||
res.set(
|
||||
"Content-Disposition",
|
||||
`attachment; filename="${fileName}"; filename*="${fileName}"`
|
||||
)
|
||||
res.set("Content-Length", contentLength)
|
||||
stream.pipe(res)
|
||||
} catch (e) {
|
||||
console.log("e is", e)
|
||||
console.log("postSiaFile err:", e)
|
||||
return res.json({ error: e.message })
|
||||
}
|
||||
}
|
||||
|
|
33
yarn.lock
33
yarn.lock
|
@ -3880,6 +3880,11 @@ depd@~1.1.2:
|
|||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
||||
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
|
||||
|
||||
depd@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
|
||||
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
|
||||
|
||||
deprecation@^2.0.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
|
||||
|
@ -4270,6 +4275,20 @@ express-fileupload@1.1.6:
|
|||
dependencies:
|
||||
busboy "^0.3.1"
|
||||
|
||||
express-session@1.17.0:
|
||||
version "1.17.0"
|
||||
resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.0.tgz#9b50dbb5e8a03c3537368138f072736150b7f9b3"
|
||||
integrity sha512-t4oX2z7uoSqATbMfsxWMbNjAL0T5zpvcJCk3Z9wnPPN7ibddhnmDZXHfEcoBMG2ojKXZoCyPMc5FbtK+G7SoDg==
|
||||
dependencies:
|
||||
cookie "0.4.0"
|
||||
cookie-signature "1.0.6"
|
||||
debug "2.6.9"
|
||||
depd "~2.0.0"
|
||||
on-headers "~1.0.2"
|
||||
parseurl "~1.3.3"
|
||||
safe-buffer "5.2.0"
|
||||
uid-safe "~2.1.5"
|
||||
|
||||
express@^4.14.0:
|
||||
version "4.17.1"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
|
||||
|
@ -7897,6 +7916,11 @@ ramda@0.26.1, ramda@^0.26.1:
|
|||
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06"
|
||||
integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==
|
||||
|
||||
random-bytes@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b"
|
||||
integrity sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=
|
||||
|
||||
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
|
@ -8366,7 +8390,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
|||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
|
||||
safe-buffer@5.2.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
|
||||
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
|
||||
|
@ -9295,6 +9319,13 @@ uid-number@0.0.6:
|
|||
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
|
||||
integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=
|
||||
|
||||
uid-safe@~2.1.5:
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a"
|
||||
integrity sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==
|
||||
dependencies:
|
||||
random-bytes "~1.0.0"
|
||||
|
||||
umask@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d"
|
||||
|
|
Reference in New Issue