Flask-Files/app/static/js/quick-upload.js
2025-03-23 03:29:05 +01:00

183 lines
No EOL
6.2 KiB
JavaScript

/**
* Quick upload functionality for instant file uploads
*/
document.addEventListener('DOMContentLoaded', function () {
// Elements
const globalDropzone = document.getElementById('global-dropzone');
const uploadToast = document.getElementById('upload-toast');
const uploadProgressBar = document.getElementById('upload-toast-progress-bar');
const uploadPercentage = document.getElementById('upload-toast-percentage');
const uploadFileName = document.getElementById('upload-toast-file');
const uploadToastClose = document.getElementById('upload-toast-close');
// Get current folder ID from URL or data attribute
function getCurrentFolderId() {
// Check if we're on a folder page
const urlParams = new URLSearchParams(window.location.search);
const folderIdFromUrl = urlParams.get('folder_id');
// Check for a data attribute on the page
const folderElement = document.querySelector('[data-current-folder-id]');
const folderIdFromData = folderElement ? folderElement.dataset.currentFolderId : null;
return folderIdFromUrl || folderIdFromData || null;
}
// Show global dropzone when files are dragged over the window
window.addEventListener('dragover', function (e) {
e.preventDefault();
e.stopPropagation();
// Only show dropzone if user is on dashboard or files page
const onRelevantPage = window.location.pathname.includes('/dashboard') ||
window.location.pathname.includes('/files');
if (onRelevantPage) {
globalDropzone.classList.add('active');
}
});
// Hide dropzone when dragging leaves window
window.addEventListener('dragleave', function (e) {
e.preventDefault();
e.stopPropagation();
// Only hide if leaving the window (not entering child elements)
if (e.clientX <= 0 || e.clientY <= 0 ||
e.clientX >= window.innerWidth || e.clientY >= window.innerHeight) {
globalDropzone.classList.remove('active');
}
});
// Handle drop event for quick upload
window.addEventListener('drop', function (e) {
e.preventDefault();
e.stopPropagation();
// Hide the dropzone
globalDropzone.classList.remove('active');
// Make sure files were dropped
if (!e.dataTransfer.files || e.dataTransfer.files.length === 0) {
return;
}
// Show upload progress toast
uploadToast.classList.add('active');
// Get the current folder ID (null for root)
const currentFolderId = getCurrentFolderId();
// Upload the files
uploadFiles(e.dataTransfer.files, currentFolderId);
});
// Close upload toast
if (uploadToastClose) {
uploadToastClose.addEventListener('click', function () {
uploadToast.classList.remove('active');
});
}
// Quick upload function
function uploadFiles(files, folderId) {
// Create FormData object
const formData = new FormData();
// Add folder ID if provided
if (folderId) {
formData.append('parent_folder_id', folderId);
}
// Add all files
for (let i = 0; i < files.length; i++) {
formData.append('files[]', files[i]);
}
// Create XHR request
const xhr = new XMLHttpRequest();
// Update progress
xhr.upload.addEventListener('progress', function (e) {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
uploadProgressBar.style.width = percent + '%';
uploadPercentage.textContent = percent + '%';
if (files.length === 1) {
uploadFileName.textContent = files[0].name;
} else {
uploadFileName.textContent = `Uploading ${files.length} files...`;
}
}
});
// Handle completion
xhr.addEventListener('load', function () {
if (xhr.status >= 200 && xhr.status < 300) {
// Success - upload complete
uploadProgressBar.style.width = '100%';
uploadPercentage.textContent = '100%';
uploadFileName.textContent = 'Upload Complete!';
// Show success alert
if (typeof showAlert === 'function') {
showAlert('Files uploaded successfully!', 'success');
}
// Reload page after brief delay to show new files
setTimeout(function () {
window.location.reload();
}, 1000);
} else {
// Error
let errorMessage = 'Upload failed';
try {
const response = JSON.parse(xhr.responseText);
if (response.error) {
errorMessage = response.error;
}
} catch (e) {
// Ignore parsing error
}
uploadFileName.textContent = errorMessage;
if (typeof showAlert === 'function') {
showAlert(errorMessage, 'error');
}
}
// Hide toast after delay
setTimeout(function () {
uploadToast.classList.remove('active');
// Reset progress
setTimeout(function () {
uploadProgressBar.style.width = '0%';
uploadPercentage.textContent = '0%';
uploadFileName.textContent = 'Processing...';
}, 300);
}, 3000);
});
// Handle errors
xhr.addEventListener('error', function () {
uploadFileName.textContent = 'Network error occurred';
if (typeof showAlert === 'function') {
showAlert('Network error occurred', 'error');
}
// Hide toast after delay
setTimeout(function () {
uploadToast.classList.remove('active');
}, 3000);
});
// Set up and send the request
xhr.open('POST', '/files/upload_xhr', true);
xhr.send(formData);
}
});