diff options
author | Marvin Borner | 2019-05-16 21:18:32 +0200 |
---|---|---|
committer | Marvin Borner | 2019-05-16 21:18:32 +0200 |
commit | b5af1a221ebbc8f713ba01b61f308262f95bbf97 (patch) | |
tree | e493871c7129d285be7d2a9de34df8ff3f7c646f | |
parent | 5cbb9d1ffe6ad4b7d89c0b189a7821d1005bbdda (diff) |
Added manual file upload support and fixed some bugs
Co-authored-by: LarsVomMars <lars@kroenner.eu>
-rw-r--r-- | src/main/resources/css/files.css | 30 | ||||
-rw-r--r-- | src/main/resources/js/files.js | 132 | ||||
-rw-r--r-- | src/main/resources/js/index.js | 14 | ||||
-rw-r--r-- | src/main/resources/views/files.rocker.html | 6 |
4 files changed, 135 insertions, 47 deletions
diff --git a/src/main/resources/css/files.css b/src/main/resources/css/files.css index 2b8e510..4131830 100644 --- a/src/main/resources/css/files.css +++ b/src/main/resources/css/files.css @@ -2,7 +2,34 @@ transition: all .2s linear; } +input[type="file"] { + display: none; +} + +.upload { + position: absolute; + margin: 20px; + right: 0; + top: 0; + padding: 8px; + border: 1px solid #ccc; + font-size: 1em; + width: 1em; + text-align: center; + line-height: 1em; + cursor: pointer; + border-radius: 100px; +} + +.upload[for="file"] { + right: 3em; +} + .navigation { + white-space: nowrap; + max-width: calc(100% - 6em); + overflow: hidden; + text-overflow: ellipsis; position: relative; padding: 0; } @@ -14,8 +41,9 @@ .progress { display: none; - color: green; float: right; + color: green; + margin-right: 6em; } table { diff --git a/src/main/resources/js/files.js b/src/main/resources/js/files.js index 9c8c135..d3ce6c4 100644 --- a/src/main/resources/js/files.js +++ b/src/main/resources/js/files.js @@ -2,18 +2,18 @@ * Drag and drop */ const drop = document.getElementById("drop"); -drop.addEventListener('dragover', e => { +drop.addEventListener("dragover", e => { e.stopPropagation(); e.preventDefault(); - e.dataTransfer.dropEffect = 'copy'; + e.dataTransfer.dropEffect = "copy"; drop.classList.add("hover"); }); -drop.addEventListener('dragleave', () => +drop.addEventListener("dragleave", () => drop.classList.remove("hover") ); -drop.addEventListener('drop', e => { +drop.addEventListener("drop", e => { e.stopPropagation(); e.preventDefault(); drop.classList.remove("hover"); @@ -42,45 +42,50 @@ drop.addEventListener('drop', e => { setListeners(); - iterateFiles(item, files => { - const progress = document.getElementById("progress"); - const request = new XMLHttpRequest(); - const formData = new FormData(); + iterateFiles(item, files => upload(files)) + } +}, false); - for (const file of files) - formData.append('file', file); +document.getElementById("directory").addEventListener("change", () => { + const files = document.getElementById("directory").files; + let dirName = ""; + + for (const file of files) dirName = file.webkitRelativePath.slice(0, file.webkitRelativePath.indexOf("/")) + "/"; + + const date = new Date(); + const row = document.getElementById("table").insertRow(-1); + row.setAttribute("data-href", dirName); + row.insertCell(0).innerHTML = "<td><i class='icon ion-md-folder'></i></td>"; + row.insertCell(1).innerHTML = dirName; + row.insertCell(2).innerHTML = "? B"; + row.insertCell(3).innerHTML = `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`; + row.insertCell(4).innerHTML = "<td><button class='share'><i class='icon ion-md-share'></i></button></td>"; + row.insertCell(5).innerHTML = "<button class='downloadButton'><a class='download' href='" + dirName + "' download='" + dirName + "'><i class='icon ion-md-download'></i></a></button>"; + row.insertCell(6).innerHTML = "<td><button class='delete'><i class='icon ion-md-trash'></i></button></td>"; + setListeners(); + + upload(files); +}); - request.upload.onprogress = e => { - if (e.lengthComputable) { - progress.style.display = "block"; - progress.innerText = `Uploading ${files.length} file(s): ${(e.loaded / e.total * 100).toFixed(2)}%`; - } - }; +document.getElementById("file").addEventListener("change", () => { + const files = document.getElementById("file").files; - request.onreadystatechange = () => { - if (request.readyState === 4) { - if (request.status === 200) { - progress.innerText = "Finished uploading!"; - setTimeout(() => progress.style.display = "none", 3000) - } else { - progress.style.color = "red"; - progress.innerText = "An error occurred :("; - } - } - }; - - request.open('POST', `/upload/${path}`.clean(), true); - request.send(formData); - }); + for (const file of files) { + const date = new Date(); + const row = document.getElementById("table").insertRow(-1); + row.setAttribute("data-href", file.name); + row.insertCell(0).innerHTML = "<td><i class='icon ion-md-folder'></i></td>"; + row.insertCell(1).innerHTML = file.name; + row.insertCell(2).innerHTML = bytesToSize(file.size); + row.insertCell(3).innerHTML = `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`; + row.insertCell(4).innerHTML = "<td><button class='share'><i class='icon ion-md-share'></i></button></td>"; + row.insertCell(5).innerHTML = "<button class='downloadButton'><a class='download' href='" + file.name + "' download='" + file.name + "'><i class='icon ion-md-download'></i></a></button>"; + row.insertCell(6).innerHTML = "<td><button class='delete'><i class='icon ion-md-trash'></i></button></td>"; } + setListeners(); - function bytesToSize(bytes) { - const sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB']; - if (bytes === 0) return '0 Byte'; - const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); - return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i]; - } -}, false); + upload(files); +}); /** * Set up listeners @@ -230,6 +235,53 @@ function setListeners() { setListeners(); /** + * Uploads an file array + * @param files + */ +function upload(files) { + const progress = document.getElementById("progress"); + const request = new XMLHttpRequest(); + const formData = new FormData(); + + for (const file of files) + formData.append('file', file); + + request.upload.onprogress = e => { + if (e.lengthComputable) { + progress.style.display = "block"; + progress.innerText = `Uploading ${files.length} file(s): ${(e.loaded / e.total * 100).toFixed(2)}%`; + } + }; + + request.onreadystatechange = () => { + if (request.readyState === 4) { + if (request.status === 200) { + progress.innerText = "Finished uploading!"; + setTimeout(() => progress.style.display = "none", 3000) + } else { + progress.style.color = "red"; + progress.innerText = "An error occurred :("; + } + } + }; + + request.open('POST', `/upload/${path}`.clean(), true); + request.send(formData); +} + +/** + * Returns bytes as human readable string + * @param bytes + * @returns {string} + */ +function bytesToSize(bytes) { + const sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB']; + if (bytes === 0) return '0 Byte'; + const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); + return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i]; +} + +/** * Iterates over files and directories * TODO: Add empty directory upload support * @param item @@ -237,7 +289,6 @@ setListeners(); */ function iterateFiles(item, callback) { const files = []; - console.log(item); (function iterate(subItem) { if (subItem.isDirectory) { const directoryReader = subItem.createReader(); @@ -249,7 +300,8 @@ function iterateFiles(item, callback) { }); } else subItem.file(file => { - const newName = subItem.fullPath.charAt(0) === '/' ? subItem.fullPath.substr(1) : subItem.fullPath; + const newName = location.pathname.split('/').slice(2).join('/') + + (subItem.fullPath.charAt(0) === '/' ? subItem.fullPath.substr(1) : subItem.fullPath); files.push(new File([file], newName, { lastModified: file.lastModified, lastModifiedDate: file.lastModifiedDate, diff --git a/src/main/resources/js/index.js b/src/main/resources/js/index.js index 4939622..6266978 100644 --- a/src/main/resources/js/index.js +++ b/src/main/resources/js/index.js @@ -1,6 +1,8 @@ -document.querySelector("#toggle").addEventListener("click", () => { - const request = new XMLHttpRequest(); - request.open("POST", "/user/theme"); - request.onload = () => location.reload(); - request.send(); -}); +if (document.querySelector("#toggle") !== null) { + document.querySelector("#toggle").addEventListener("click", () => { + const request = new XMLHttpRequest(); + request.open("POST", "/user/theme"); + request.onload = () => location.reload(); + request.send(); + }); +} diff --git a/src/main/resources/views/files.rocker.html b/src/main/resources/views/files.rocker.html index 1bdf858..7e074c4 100644 --- a/src/main/resources/views/files.rocker.html +++ b/src/main/resources/views/files.rocker.html @@ -41,6 +41,12 @@ <span class="progress" id="progress"></span> </h3> + <label class="upload" for="directory"><i class="icon ion-md-cloud-upload"></i></label> + <input directory id="directory" multiple type="file" webkitdirectory/> + + <label class="upload" for="file"><i class="icon ion-md-add"></i></label> + <input id="file" multiple type="file"/> + <table id="table"> <colgroup> <col/> |