375 lines
No EOL
14 KiB
JavaScript
375 lines
No EOL
14 KiB
JavaScript
/**
|
|
* File browser functionality
|
|
*/
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
// View toggle functionality
|
|
const filesContainer = document.getElementById('files-container');
|
|
const gridViewBtn = document.getElementById('grid-view-btn');
|
|
const listViewBtn = document.getElementById('list-view-btn');
|
|
|
|
if (filesContainer && gridViewBtn && listViewBtn) {
|
|
// Set initial view based on saved preference
|
|
const savedView = localStorage.getItem('view_preference') || 'grid';
|
|
filesContainer.className = `files-container ${savedView}-view`;
|
|
|
|
// Highlight the correct button
|
|
if (savedView === 'grid') {
|
|
gridViewBtn.classList.add('active');
|
|
listViewBtn.classList.remove('active');
|
|
} else {
|
|
listViewBtn.classList.add('active');
|
|
gridViewBtn.classList.remove('active');
|
|
}
|
|
|
|
// Add event listeners
|
|
gridViewBtn.addEventListener('click', function () {
|
|
filesContainer.className = 'files-container grid-view';
|
|
gridViewBtn.classList.add('active');
|
|
listViewBtn.classList.remove('active');
|
|
|
|
// Save preference
|
|
localStorage.setItem('view_preference', 'grid');
|
|
});
|
|
|
|
listViewBtn.addEventListener('click', function () {
|
|
filesContainer.className = 'files-container list-view';
|
|
listViewBtn.classList.add('active');
|
|
gridViewBtn.classList.remove('active');
|
|
|
|
// Save preference
|
|
localStorage.setItem('view_preference', 'list');
|
|
});
|
|
}
|
|
|
|
// Variables for tracking selected items
|
|
let selectedItemId = null;
|
|
let selectedItemType = null;
|
|
|
|
// Setup context menu functionality
|
|
function setupContextMenu() {
|
|
// Context menu already implemented via context-menu.js
|
|
// We'll just need to ensure our item actions are properly set
|
|
|
|
// Add item click handler to set selected item
|
|
document.querySelectorAll('.file-item, .folder-item').forEach(item => {
|
|
item.addEventListener('click', function (e) {
|
|
// If clicking on an action button, don't select the item
|
|
if (e.target.closest('.item-actions') || e.target.closest('a')) {
|
|
return;
|
|
}
|
|
|
|
// Set selected item
|
|
selectedItemId = this.dataset.id;
|
|
selectedItemType = this.classList.contains('folder-item') ? 'folder' : 'file';
|
|
|
|
// Highlight selected item
|
|
document.querySelectorAll('.file-item, .folder-item').forEach(i => {
|
|
i.classList.remove('selected');
|
|
});
|
|
this.classList.add('selected');
|
|
});
|
|
|
|
// Right-click to open context menu
|
|
item.addEventListener('contextmenu', function (e) {
|
|
// Set selected item
|
|
selectedItemId = this.dataset.id;
|
|
selectedItemType = this.classList.contains('folder-item') ? 'folder' : 'file';
|
|
|
|
// Highlight selected item
|
|
document.querySelectorAll('.file-item, .folder-item').forEach(i => {
|
|
i.classList.remove('selected');
|
|
});
|
|
this.classList.add('selected');
|
|
});
|
|
});
|
|
}
|
|
|
|
// Handle folder creation
|
|
const newFolderForm = document.getElementById('new-folder-form');
|
|
if (newFolderForm) {
|
|
newFolderForm.addEventListener('submit', function (e) {
|
|
e.preventDefault();
|
|
|
|
const folderName = document.getElementById('folder-name').value;
|
|
const parentId = document.querySelector('input[name="parent_id"]').value;
|
|
|
|
// Create FormData
|
|
const formData = new FormData();
|
|
formData.append('name', folderName);
|
|
if (parentId) formData.append('parent_id', parentId);
|
|
|
|
// Send request
|
|
fetch('/files/create_folder', {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Close modal
|
|
closeModal('new-folder-modal');
|
|
|
|
// Show success message
|
|
showAlert('Folder created successfully', 'success');
|
|
|
|
// Reload page to show new folder
|
|
setTimeout(() => window.location.reload(), 500);
|
|
} else {
|
|
showAlert(data.error || 'Error creating folder', 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
showAlert('Error creating folder: ' + error, 'error');
|
|
});
|
|
});
|
|
}
|
|
|
|
// Handle rename
|
|
const renameForm = document.getElementById('rename-form');
|
|
if (renameForm) {
|
|
renameForm.addEventListener('submit', function (e) {
|
|
e.preventDefault();
|
|
|
|
const newName = document.getElementById('new-name').value;
|
|
|
|
if (!selectedItemId) {
|
|
showAlert('No item selected', 'error');
|
|
return;
|
|
}
|
|
|
|
fetch('/files/rename', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: JSON.stringify({
|
|
item_id: selectedItemId,
|
|
new_name: newName
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Close modal
|
|
closeModal('rename-modal');
|
|
|
|
// Show success message
|
|
showAlert('Item renamed successfully', 'success');
|
|
|
|
// Update item name in the UI or reload
|
|
setTimeout(() => window.location.reload(), 500);
|
|
} else {
|
|
showAlert(data.error || 'Failed to rename item', 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
showAlert('Error: ' + error, 'error');
|
|
});
|
|
});
|
|
}
|
|
|
|
// Handle delete confirmation
|
|
const confirmDeleteBtn = document.getElementById('confirm-delete-btn');
|
|
if (confirmDeleteBtn) {
|
|
confirmDeleteBtn.addEventListener('click', function () {
|
|
if (!selectedItemId) {
|
|
showAlert('No item selected', 'error');
|
|
closeModal('delete-modal');
|
|
return;
|
|
}
|
|
|
|
fetch(`/files/delete/${selectedItemId}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Close modal
|
|
closeModal('delete-modal');
|
|
|
|
// Show success message
|
|
showAlert(data.message || 'Item deleted successfully', 'success');
|
|
|
|
// Remove the item from the UI or reload
|
|
setTimeout(() => window.location.reload(), 500);
|
|
} else {
|
|
showAlert(data.error || 'Failed to delete item', 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
showAlert('Error: ' + error, 'error');
|
|
});
|
|
});
|
|
}
|
|
|
|
// Initialize
|
|
setupContextMenu();
|
|
|
|
// Buttons to open modals
|
|
const deleteBtn = document.getElementById('delete-btn');
|
|
if (deleteBtn) {
|
|
deleteBtn.addEventListener('click', function () {
|
|
if (!selectedItemId) {
|
|
showAlert('Please select an item first', 'warning');
|
|
return;
|
|
}
|
|
openModal('delete-modal');
|
|
});
|
|
}
|
|
|
|
const renameBtn = document.getElementById('rename-btn');
|
|
if (renameBtn) {
|
|
renameBtn.addEventListener('click', function () {
|
|
if (!selectedItemId) {
|
|
showAlert('Please select an item first', 'warning');
|
|
return;
|
|
}
|
|
|
|
// Get current name
|
|
const selectedItem = document.querySelector(`.file-item[data-id="${selectedItemId}"], .folder-item[data-id="${selectedItemId}"]`);
|
|
const currentName = selectedItem ? selectedItem.querySelector('.item-name').textContent.trim() : '';
|
|
|
|
// Set current name in the input
|
|
document.getElementById('new-name').value = currentName;
|
|
|
|
openModal('rename-modal');
|
|
document.getElementById('new-name').focus();
|
|
});
|
|
}
|
|
|
|
// Delete functionality
|
|
const deleteModal = document.getElementById('delete-modal');
|
|
const deleteForm = document.getElementById('delete-form');
|
|
const deleteItemIdInput = document.getElementById('delete-item-id');
|
|
|
|
if (deleteModal && deleteForm) {
|
|
// Update the form action when the modal is shown
|
|
document.querySelectorAll('.action-btn.delete').forEach(btn => {
|
|
btn.addEventListener('click', function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
const itemElement = this.closest('.folder-item, .file-item');
|
|
const itemId = itemElement.dataset.id;
|
|
|
|
// Set the item ID in the form
|
|
deleteItemIdInput.value = itemId;
|
|
|
|
// Update the form action URL
|
|
const formAction = deleteForm.action;
|
|
deleteForm.action = formAction.replace('placeholder', itemId);
|
|
|
|
// Show the modal
|
|
deleteModal.classList.add('active');
|
|
});
|
|
});
|
|
|
|
// Close modal when cancel is clicked
|
|
deleteModal.querySelector('.modal-cancel').addEventListener('click', function () {
|
|
deleteModal.classList.remove('active');
|
|
});
|
|
|
|
// Close modal when X is clicked
|
|
deleteModal.querySelector('.modal-close').addEventListener('click', function () {
|
|
deleteModal.classList.remove('active');
|
|
});
|
|
}
|
|
});
|
|
|
|
// Browser-specific functionality
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
// Initialize folder browser view
|
|
initializeFolderBrowser();
|
|
});
|
|
|
|
function initializeFolderBrowser() {
|
|
// Handle item selection
|
|
const items = document.querySelectorAll('.folder-item, .file-item');
|
|
items.forEach(item => {
|
|
item.addEventListener('click', function (e) {
|
|
// Only select if not clicking on an action button
|
|
if (!e.target.closest('.file-actions')) {
|
|
// Remove selection from all items
|
|
items.forEach(i => i.classList.remove('selected'));
|
|
|
|
// Select this item
|
|
this.classList.add('selected');
|
|
}
|
|
});
|
|
});
|
|
|
|
// Handle folder creation form submission
|
|
const newFolderForm = document.getElementById('new-folder-form');
|
|
if (newFolderForm) {
|
|
newFolderForm.addEventListener('submit', function (e) {
|
|
// Form will be submitted normally, we just close the modal
|
|
const modal = document.getElementById('new-folder-modal');
|
|
if (modal) {
|
|
modal.classList.remove('active');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Handle file/folder actions from context menu
|
|
document.querySelectorAll('.context-menu-item').forEach(item => {
|
|
item.addEventListener('click', function () {
|
|
const action = this.getAttribute('data-action');
|
|
const menu = this.closest('.context-menu');
|
|
const itemId = menu.getAttribute('data-item-id');
|
|
const itemType = menu.getAttribute('data-item-type');
|
|
|
|
// Handle different actions
|
|
switch (action) {
|
|
case 'open':
|
|
if (itemType === 'folder') {
|
|
window.location.href = `/files/browser/${itemId}`;
|
|
}
|
|
break;
|
|
case 'download':
|
|
if (itemType === 'file') {
|
|
window.location.href = `/files/download/${itemId}`;
|
|
}
|
|
break;
|
|
case 'share':
|
|
// TODO: Implement share functionality
|
|
alert('Share functionality coming soon');
|
|
break;
|
|
case 'rename':
|
|
// TODO: Implement rename functionality
|
|
alert('Rename functionality coming soon');
|
|
break;
|
|
case 'delete':
|
|
if (confirm(`Are you sure you want to delete this ${itemType}?`)) {
|
|
// Send delete request to server
|
|
fetch(`/files/delete/${itemType}/${itemId}`, {
|
|
method: 'POST',
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Remove item from DOM
|
|
document.querySelector(`[data-id="${itemId}"]`).remove();
|
|
} else {
|
|
alert(`Failed to delete ${itemType}: ${data.error}`);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert(`An error occurred while deleting the ${itemType}`);
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Hide menu after action
|
|
menu.style.display = 'none';
|
|
});
|
|
});
|
|
}
|