From 19af9219134c6a065308710c8d03cc71475ce29c Mon Sep 17 00:00:00 2001 From: William Harrell Date: Sun, 13 Nov 2022 22:06:24 -0500 Subject: [PATCH] added file uploads to frontend --- client/src/components/files.vue | 103 ++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 11 deletions(-) diff --git a/client/src/components/files.vue b/client/src/components/files.vue index 320df30..bfae9cf 100644 --- a/client/src/components/files.vue +++ b/client/src/components/files.vue @@ -15,8 +15,8 @@
-

Downloads

-
+

Downloads

+

{{ download.name }}

{{ Math.min(100, Math.round(download.progress / download.size * 100))}}%

@@ -25,10 +25,22 @@
+

Uploads

+
+
+

{{ upload.name }}

+

{{ Math.min(100, Math.round(upload.progress / upload.size * 100))}}%

+ +
+ +
-
+
-

Drag files here to upload

+

Click or drag files here to upload

@@ -116,6 +128,9 @@ margin: 10px 10px 10px 10px; background-color: rgba($color: #fff, $alpha: 0.05); border-radius: 5px; + max-height: 50vh; + overflow-y: scroll; + overflow-x: hidden; } .transfers > p { @@ -145,6 +160,14 @@ border-radius: 5px; } + .upload-area:hover { + cursor: pointer; + } + + .upload-area-drag, .upload-area:hover { + background-color: rgba($color: #fff, $alpha: 0.10); + } + .upload-area > i { font-size: 4em; margin: 10px 10px 10px 10px; @@ -163,7 +186,7 @@ import Markdown from './markdown' import Content from './context.vue' -import { FileTransfer } from '~/neko/types' + import { FileTransfer } from '~/neko/types' @Component({ name: 'neko-files', @@ -174,6 +197,8 @@ import { FileTransfer } from '~/neko/types' }) export default class extends Vue { + public uploadAreaDrag: boolean = false; + get cwd() { return this.$accessor.files.cwd } @@ -208,8 +233,8 @@ import { FileTransfer } from '~/neko/types' id: Math.round(Math.random() * 10000), name: item.name, direction: 'download', - // this is just an estimation, but for large files the content length - // is not sent (chunked transfer) + // this may be smaller than the actual transfer amount, but for large files the + // content length is not sent (chunked transfer) size: item.size, progress: 0, status: 'pending', @@ -228,6 +253,8 @@ import { FileTransfer } from '~/neko/types' } if (transfer.progress === transfer.size) { transfer.status = 'completed' + } else if (transfer.status !== 'inprogress') { + transfer.status = 'inprogress' } } }).then((res) => { @@ -245,6 +272,64 @@ import { FileTransfer } from '~/neko/types' this.$accessor.files.addTransfer(transfer) } + upload(dt: DataTransfer) { + this.uploadAreaDrag = false + + for (const file of dt.files) { + const formdata = new FormData() + formdata.append("files", file, file.name) + + const url = `/file?pwd=${this.$accessor.password}` + let transfer: FileTransfer = { + id: Math.round(Math.random() * 10000), + name: file.name, + direction: 'upload', + size: file.size, + progress: 0, + status: 'pending', + axios: null, + abortController: null + } + transfer.abortController = new AbortController() + this.$http.post(url, formdata, { + onUploadProgress: (x: any) => { + transfer.progress = x.loaded + + if (transfer.size !== x.total) { + transfer.size = x.total + } + if (transfer.progress === transfer.size) { + transfer.status = 'completed' + } else if (transfer.status !== 'inprogress') { + transfer.status = 'inprogress' + } + } + }).catch((err) => { + this.$log.error(err) + }) + this.$accessor.files.addTransfer(transfer) + } + } + + openFileBrowser() { + const input = document.createElement('input') + input.type = 'file' + input.setAttribute('multiple', 'true') + input.click() + + input.onchange = (e) => { + if (e === null) { + return + } + const dt = new DataTransfer() + const target = e.target as any + for (const f of target.files) { + dt.items.add(f) + } + this.upload(dt) + } + } + removeTransfer(transfer: FileTransfer) { if (transfer.status !== 'completed') { transfer.abortController?.abort() @@ -296,10 +381,6 @@ import { FileTransfer } from '~/neko/types' return `${(size / 1000 ** 4).toFixed(3)} tb` } - onFileDrop(e: any) { - console.log('file dropped', e) - console.log(e.dataTransfer.files) - } }