diff options
author | Marvin Borner | 2019-04-07 17:17:17 +0200 |
---|---|---|
committer | Marvin Borner | 2019-04-07 17:17:17 +0200 |
commit | 5ec7ec5c50eeb3e2c281c0edfee6c74d7d512500 (patch) | |
tree | 071270805b5b2169d4aa26462647f9a5737b231e | |
parent | 4e2024432ee680f98d91d07b050ac60151ebec4c (diff) |
Added drag and drop file upload
-rw-r--r-- | src/main/kotlin/App.kt | 22 | ||||
-rw-r--r-- | src/main/resources/css/files.css | 6 | ||||
-rw-r--r-- | src/main/resources/css/layout.css | 4 | ||||
-rw-r--r-- | src/main/resources/js/files.js | 31 | ||||
-rw-r--r-- | src/main/resources/views/files.rocker.html | 19 | ||||
-rw-r--r-- | src/main/resources/views/upload.rocker.html | 4 |
6 files changed, 69 insertions, 17 deletions
diff --git a/src/main/kotlin/App.kt b/src/main/kotlin/App.kt index d79e25e..f69a960 100644 --- a/src/main/kotlin/App.kt +++ b/src/main/kotlin/App.kt @@ -49,7 +49,7 @@ fun main() { * Receives and saves multipart media data * TODO: Fix possible security issue with "../" */ - post("/upload", { ctx -> upload(ctx) }, roles(Roles.ADMIN)) + post("/upload/*", { ctx -> upload(ctx) }, roles(Roles.ADMIN)) } } @@ -66,18 +66,23 @@ fun setupRoles(handler: Handler, ctx: Context, permittedRoles: Set<Role>) { } /** - * Crawls the requested directory and returns filenames in array + * Crawls the requested file and either renders the directory view or the file view */ fun crawlFiles(ctx: Context) { - val files = ArrayList<String>() try { if (File("$fileHome/${ctx.splats()[0]}").isDirectory) { + val files = ArrayList<String>() Files.list(Paths.get("$fileHome/${ctx.splats()[0]}/")).forEach { val fileName = it.toString() .drop(fileHome.length + (if (ctx.splats()[0].isNotEmpty()) ctx.splats()[0].length + 2 else 1)) val filePath = "$fileHome${it.toString().drop(fileHome.length)}" files.add(if (File(filePath).isDirectory) "$fileName/" else fileName) - ctx.render("files.rocker.html", model("files", files)) + ctx.render( + "files.rocker.html", model( + "files", files, + "path", ctx.splats()[0] + ) + ) } } else ctx.render( @@ -99,12 +104,9 @@ fun crawlFiles(ctx: Context) { * Saves multipart media data into requested directory */ fun upload(ctx: Context) { - ctx.uploadedFiles("files").forEach { (contentType, content, name, extension) -> - if (ctx.queryParam("dir") !== null) { - FileUtil.streamToFile(content, "files/${ctx.queryParam("dir")}/$name") - ctx.redirect("/views/upload.rocker.html") - } else - throw BadRequestResponse("Error: Please enter a filename.") + ctx.uploadedFiles("file").forEach { (contentType, content, name, extension) -> + FileUtil.streamToFile(content, "$fileHome/${ctx.splats()[0]}/$name") + ctx.redirect("/upload") } } diff --git a/src/main/resources/css/files.css b/src/main/resources/css/files.css index 0f55ca6..798e3ec 100644 --- a/src/main/resources/css/files.css +++ b/src/main/resources/css/files.css @@ -3,3 +3,9 @@ a.filename { text-decoration: none; margin-bottom: 5px;; } + +.drop { + padding: 8px; + min-height: calc(100vh - 16px); + z-index: -1; +} diff --git a/src/main/resources/css/layout.css b/src/main/resources/css/layout.css index 4a1e1f0..c11ee79 100644 --- a/src/main/resources/css/layout.css +++ b/src/main/resources/css/layout.css @@ -1,3 +1,7 @@ html, body { font-family: Arial, Helvetica, sans-serif; + padding: 0; + margin: 0; + min-width: 100%; + min-height: 100%; } diff --git a/src/main/resources/js/files.js b/src/main/resources/js/files.js new file mode 100644 index 0000000..24140b0 --- /dev/null +++ b/src/main/resources/js/files.js @@ -0,0 +1,31 @@ +const drop = document.getElementById("drop"); + +drop.addEventListener('dragover', e => { + e.stopPropagation(); + e.preventDefault(); + e.dataTransfer.dropEffect = 'copy'; + drop.style.background = "rgba(12,99,250,0.3)"; +}); + +drop.addEventListener('dragleave', e => + drop.style.background = "white" +); + +drop.addEventListener('drop', e => { + // TODO: Fix directory uploading + e.stopPropagation(); + e.preventDefault(); + drop.style.background = "white"; + const files = e.dataTransfer.files; + + for (let i = 0; i < files.length; i++) { + let request = new XMLHttpRequest(); + let formData = new FormData(); + + drop.insertAdjacentHTML('beforeend', `<a class="filename" href="${files[i].name}">${files[i].name}</a><br><hr>`); + + formData.append("file", files[i]); + request.open("POST", "/upload/" + path); + request.send(formData); + } +}); diff --git a/src/main/resources/views/files.rocker.html b/src/main/resources/views/files.rocker.html index 7a2d432..1373eca 100644 --- a/src/main/resources/views/files.rocker.html +++ b/src/main/resources/views/files.rocker.html @@ -1,13 +1,22 @@ @import java.util.ArrayList -@args (ArrayList files) +@args (ArrayList files, String path) @css => { <link href="/css/files.css" rel="stylesheet"> } -@layout.template(files.size() + " Files", css, RockerContent.NONE) -> { -@for (String file : files) { -<a class="filename" href="@file">@file</a><br> -<hr> +@js => { +<script>const path = "@path";</script> +<script src="/js/files.js"></script> } + +@layout.template(files.size() + " Files", css, js) -> { +<div class="drop" id="drop"> + <a class="filename" href="../">../</a><br> + <hr> + @for (String file : files) { + <a class="filename" href="@file">@file</a><br> + <hr> + } +</div> } diff --git a/src/main/resources/views/upload.rocker.html b/src/main/resources/views/upload.rocker.html index b36abdc..ec5daa2 100644 --- a/src/main/resources/views/upload.rocker.html +++ b/src/main/resources/views/upload.rocker.html @@ -1,8 +1,8 @@ @args (String content) @layout.template("Upload", RockerContent.NONE, RockerContent.NONE) -> { -<form action="/api/upload?dir=test" enctype="multipart/form-data" method="post"> - <input multiple name="files" type="file"> +<form action="/upload/test" enctype="multipart/form-data" method="post"> + <input multiple name="file" type="file"> <button>Submit</button> </form> } |