Flask-Files/app/static/js/drag-drop.js
2025-03-24 20:34:42 +01:00

136 lines
No EOL
4 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function () {
// Get elements
const filesContainer = document.getElementById('files-container');
const globalDropzone = document.getElementById('global-dropzone');
if (!filesContainer || !globalDropzone) return;
// Track if we're dragging items from within the app
let internalDrag = false;
// Handle drag start on files/folders
filesContainer.addEventListener('dragstart', function (e) {
const item = e.target.closest('.file-item, .folder-item');
if (item) {
// Set data for drag operation
e.dataTransfer.setData('text/plain', JSON.stringify({
id: item.dataset.id,
type: item.classList.contains('folder-item') ? 'folder' : 'file',
name: item.querySelector('.item-name').textContent
}));
// Mark as internal drag
internalDrag = true;
// Add dragging class for styling
item.classList.add('dragging');
}
});
// Handle drag end
filesContainer.addEventListener('dragend', function (e) {
const item = e.target.closest('.file-item, .folder-item');
if (item) {
item.classList.remove('dragging');
internalDrag = false;
}
});
// Handle drag enter on folders
filesContainer.addEventListener('dragenter', function (e) {
const folderItem = e.target.closest('.folder-item');
if (folderItem && internalDrag) {
folderItem.classList.add('drag-over');
}
});
// Handle drag leave on folders
filesContainer.addEventListener('dragleave', function (e) {
const folderItem = e.target.closest('.folder-item');
if (folderItem) {
folderItem.classList.remove('drag-over');
}
});
// Handle drag over (prevent default to allow drop)
filesContainer.addEventListener('dragover', function (e) {
e.preventDefault();
// If dragging from within app, don't show global dropzone
if (internalDrag) {
globalDropzone.classList.remove('active');
}
});
// Handle drop on folders
filesContainer.addEventListener('drop', function (e) {
e.preventDefault();
const folderItem = e.target.closest('.folder-item');
if (folderItem && internalDrag) {
folderItem.classList.remove('drag-over');
try {
const dragData = JSON.parse(e.dataTransfer.getData('text/plain'));
const sourceId = dragData.id;
const sourceType = dragData.type;
const targetId = folderItem.dataset.id;
// Make AJAX call to move item
moveItem(sourceId, sourceType, targetId);
} catch (err) {
console.error('Error processing drop:', err);
}
}
});
// Function to move item via AJAX
function moveItem(sourceId, sourceType, targetFolderId) {
fetch('/files/move', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
body: JSON.stringify({
item_id: sourceId,
item_type: sourceType,
target_folder_id: targetFolderId
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Refresh the page or update the UI
window.location.reload();
} else {
alert('Error: ' + data.error);
}
})
.catch(error => {
console.error('Error moving item:', error);
alert('Failed to move item. Please try again.');
});
}
// Global window drag events - only show dropzone for external files
window.addEventListener('dragover', function (e) {
e.preventDefault();
// Only show global dropzone if not dragging internally
if (!internalDrag) {
globalDropzone.classList.add('active');
}
});
window.addEventListener('dragleave', function (e) {
// Check if mouse left the window
if (e.clientX <= 0 || e.clientY <= 0 ||
e.clientX >= window.innerWidth || e.clientY >= window.innerHeight) {
globalDropzone.classList.remove('active');
}
});
window.addEventListener('drop', function (e) {
e.preventDefault();
globalDropzone.classList.remove('active');
});
});