upload: basic folder upload support
This commit is contained in:
+68
-27
@@ -35,8 +35,9 @@ templ Upload(expirations []Expiry, uploadedLink string) {
|
||||
</div>
|
||||
<script>
|
||||
let drop_zone = document.getElementById("drop_zone");
|
||||
let desc = document.getElementById("desc");
|
||||
let fileInput = document.getElementById("files");
|
||||
let desc = document.getElementById("desc");
|
||||
let fileInput = document.getElementById("files");
|
||||
|
||||
function updateDescription(len) {
|
||||
desc.innerText = `${len} File`
|
||||
if (len > 1) {
|
||||
@@ -44,33 +45,73 @@ templ Upload(expirations []Expiry, uploadedLink string) {
|
||||
}
|
||||
desc.innerText += " Attached"
|
||||
}
|
||||
fileInput.addEventListener("change", () => {
|
||||
updateDescription(fileInput.files.length)
|
||||
});
|
||||
drop_zone.addEventListener("click", function (ev) {
|
||||
fileInput.click();
|
||||
})
|
||||
drop_zone.addEventListener("drop", function (ev) {
|
||||
ev.preventDefault();
|
||||
drop_zone.classList.remove('dragover');
|
||||
const dt = ev.dataTransfer;
|
||||
if (!dt) return
|
||||
|
||||
const files = Array.from(dt.files); // iterable
|
||||
fileInput.addEventListener("change", () => {
|
||||
updateDescription(fileInput.files.length);
|
||||
});
|
||||
|
||||
const newDT = new DataTransfer();
|
||||
files.forEach(f => newDT.items.add(f));
|
||||
fileInput.files = newDT.files;
|
||||
updateDescription(fileInput.files.length)
|
||||
});
|
||||
drop_zone.addEventListener("dragover", function (e) {
|
||||
drop_zone.classList.add('dragover');
|
||||
e.preventDefault();
|
||||
});
|
||||
drop_zone.addEventListener("dragleave", function (e) {
|
||||
drop_zone.classList.remove('dragover');
|
||||
e.preventDefault();
|
||||
});
|
||||
drop_zone.addEventListener("click", () => fileInput.click());
|
||||
|
||||
drop_zone.addEventListener("dragover", (e) => {
|
||||
e.preventDefault();
|
||||
drop_zone.classList.add('dragover');
|
||||
});
|
||||
|
||||
drop_zone.addEventListener("dragleave", (e) => {
|
||||
e.preventDefault();
|
||||
drop_zone.classList.remove('dragover');
|
||||
});
|
||||
|
||||
drop_zone.addEventListener("drop", async (ev) => {
|
||||
ev.preventDefault();
|
||||
drop_zone.classList.remove('dragover');
|
||||
|
||||
const items = ev.dataTransfer?.items;
|
||||
if (!items) return;
|
||||
|
||||
const collected = [];
|
||||
|
||||
const readEntries = (reader) => new Promise((resolve, reject) => reader.readEntries(resolve, reject));
|
||||
const getFile = (entry) => new Promise((resolve, reject) => entry.file(resolve, reject));
|
||||
|
||||
async function traverse(entry, path = "") {
|
||||
if (entry.isFile) {
|
||||
const file = await getFile(entry);
|
||||
Object.defineProperty(file, "webkitRelativePath", {
|
||||
value: path + file.name,
|
||||
configurable: true });
|
||||
collected.push(file);
|
||||
} else if (entry.isDirectory) {
|
||||
const reader = entry.createReader();
|
||||
const prefix = path + entry.name + "/";
|
||||
let entries;
|
||||
do {
|
||||
entries = await readEntries(reader);
|
||||
for (const child of entries) {
|
||||
await traverse(child, prefix);
|
||||
}
|
||||
} while (entries.length > 0);
|
||||
}
|
||||
}
|
||||
|
||||
const tasks = [];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const entry = items[i].webkitGetAsEntry();
|
||||
if (entry) {
|
||||
tasks.push(traverse(entry));
|
||||
} else {
|
||||
const file = items[i].getAsFile();
|
||||
if (file) collected.push(file);
|
||||
}
|
||||
}
|
||||
await Promise.all(tasks);
|
||||
|
||||
const dt = new DataTransfer();
|
||||
collected.forEach(f => dt.items.add(f));
|
||||
fileInput.files = dt.files;
|
||||
|
||||
updateDescription(fileInput.files.length);
|
||||
});
|
||||
</script>
|
||||
<style>.dragover {border-color: #00C950;}</style>
|
||||
<div class="flex flex-col gap-3 w-full">
|
||||
|
||||
Reference in New Issue
Block a user