Merge pull request #426 from christianlouis/copilot/support-directory-upload
feat(upload): directory drag-and-drop, adaptive 429 throttling, full Gotenberg file type support
This commit is contained in:
@@ -3,6 +3,12 @@
|
||||
|
||||
{% block head_extra %}
|
||||
<script src="/static/js/common.js"></script>
|
||||
<script>
|
||||
window.uploadConfig = {
|
||||
concurrency: {{ upload_concurrency }},
|
||||
queueDelayMs: {{ upload_queue_delay_ms }}
|
||||
};
|
||||
</script>
|
||||
<script src="/static/js/upload.js"></script>
|
||||
<style>
|
||||
/* Drop overlay styles - covers entire page for drag-and-drop anywhere */
|
||||
@@ -342,8 +348,8 @@
|
||||
<div id="dropOverlay" class="drop-overlay">
|
||||
<div class="drop-message">
|
||||
<i class="fas fa-cloud-upload-alt"></i>
|
||||
<p>Drop files anywhere to upload</p>
|
||||
<div class="drop-hint">Supports PDF, Office docs, images, and more</div>
|
||||
<p>Drop files or folders anywhere to upload</p>
|
||||
<div class="drop-hint">Supports PDF, Office docs, images, HTML, Markdown, and more – folders are processed recursively</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -902,18 +908,19 @@
|
||||
e.dataTransfer.dropEffect = 'copy';
|
||||
});
|
||||
|
||||
window.addEventListener('drop', (e) => {
|
||||
window.addEventListener('drop', async (e) => {
|
||||
e.preventDefault();
|
||||
dragCounter = 0;
|
||||
dropOverlay.classList.remove('active');
|
||||
|
||||
if (e.dataTransfer.files.length > 0) {
|
||||
const files = await getFilesFromDataTransfer(e.dataTransfer);
|
||||
if (files.length > 0) {
|
||||
// Show upload modal
|
||||
uploadModal.classList.add('active');
|
||||
uploadProgressContainer.innerHTML = '';
|
||||
|
||||
// Process the dropped files
|
||||
processFiles(e.dataTransfer.files, uploadProgressContainer, uploadStatusMessage);
|
||||
// Process the dropped files (queue-based, with adaptive throttling)
|
||||
processFiles(files, uploadProgressContainer, uploadStatusMessage);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -12,12 +12,11 @@
|
||||
<div
|
||||
id="dropZone"
|
||||
class="border-4 border-dashed border-gray-300 rounded-lg p-6 sm:p-8 bg-white text-center w-full"
|
||||
ondrop="handleDrop(event)"
|
||||
ondragover="handleDragOver(event)"
|
||||
ondragleave="handleDragLeave(event)"
|
||||
>
|
||||
<p class="text-gray-500 mb-4 hidden sm:block">
|
||||
Drag & drop files here, or click to select files.
|
||||
Drag & drop files or folders here, or click to select files.
|
||||
</p>
|
||||
<p class="text-gray-500 mb-4 sm:hidden">
|
||||
Tap to select files or use the camera button below.
|
||||
@@ -42,7 +41,7 @@
|
||||
</button>
|
||||
<div class="text-sm text-gray-500 mt-2">
|
||||
<p>Allowed types: PDF, Office documents (Word, Excel, PowerPoint, etc.), Images</p>
|
||||
<p>Maximum size: 500MB per file</p>
|
||||
<p>Maximum size: 500MB per file • Directories are uploaded recursively</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -122,6 +121,13 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
// Expose server-side upload throttling configuration to upload.js
|
||||
window.uploadConfig = {
|
||||
concurrency: {{ upload_concurrency }},
|
||||
queueDelayMs: {{ upload_queue_delay_ms }}
|
||||
};
|
||||
</script>
|
||||
<script src="/static/js/upload.js"></script>
|
||||
<script>
|
||||
// Drag-and-drop / file input logic
|
||||
@@ -143,10 +149,12 @@
|
||||
dropZone.classList.remove("bg-gray-100");
|
||||
}
|
||||
|
||||
function handleDrop(e) {
|
||||
dropZone.addEventListener("drop", async (e) => {
|
||||
e.preventDefault();
|
||||
dropZone.classList.remove("bg-gray-100");
|
||||
if (e.dataTransfer.files.length) {
|
||||
|
||||
const files = await getFilesFromDataTransfer(e.dataTransfer);
|
||||
if (files.length) {
|
||||
// Clear previous upload progress
|
||||
uploadProgress.innerHTML = "";
|
||||
|
||||
@@ -155,10 +163,10 @@
|
||||
progressContainer.className = "space-y-2";
|
||||
uploadProgress.appendChild(progressContainer);
|
||||
|
||||
// Use the shared processFiles function
|
||||
processFiles(e.dataTransfer.files, progressContainer, statusMessage);
|
||||
// Use the shared processFiles function (queue-based)
|
||||
processFiles(files, progressContainer, statusMessage);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function handleFileSelect(e) {
|
||||
if (e.target.files.length) {
|
||||
@@ -171,7 +179,7 @@
|
||||
uploadProgress.appendChild(progressContainer);
|
||||
|
||||
// Use the shared processFiles function
|
||||
processFiles(e.target.files, progressContainer, statusMessage);
|
||||
processFiles(Array.from(e.target.files), progressContainer, statusMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user