/** * 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_mode') || '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'); localStorage.setItem('view_mode', 'grid'); }); listViewBtn.addEventListener('click', function () { filesContainer.className = 'files-container list-view'; listViewBtn.classList.add('active'); gridViewBtn.classList.remove('active'); localStorage.setItem('view_mode', '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'); }); } // File/folder action buttons const setupItemActions = () => { // Edit/rename buttons document.querySelectorAll('.action-btn.edit').forEach(btn => { btn.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation(); const itemElement = this.closest('.folder-item, .file-item'); const itemId = itemElement.dataset.id; const itemName = itemElement.querySelector('.item-name').textContent; const isFolder = itemElement.classList.contains('folder-item'); // Set values in rename modal const renameModal = document.getElementById('rename-modal'); const newNameInput = document.getElementById('new-name'); const itemIdInput = document.getElementById('item-id'); const itemTypeInput = document.getElementById('item-type'); if (renameModal && newNameInput && itemIdInput && itemTypeInput) { newNameInput.value = itemName; itemIdInput.value = itemId; itemTypeInput.value = isFolder ? 'folder' : 'file'; // Show modal renameModal.classList.add('active'); } }); }); // Delete buttons 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; const isFolder = itemElement.classList.contains('folder-item'); // Set values in delete modal const deleteModal = document.getElementById('delete-modal'); const deleteItemIdInput = document.getElementById('delete-item-id'); const deleteItemTypeInput = document.getElementById('delete-item-type'); if (deleteModal && deleteItemIdInput && deleteItemTypeInput) { deleteItemIdInput.value = itemId; deleteItemTypeInput.value = isFolder ? 'folder' : 'file'; // Update form action const deleteForm = document.getElementById('delete-form'); if (deleteForm) { deleteForm.action = `/files/delete/${itemId}`; } // Show modal deleteModal.classList.add('active'); } }); }); }; // Initialize item actions setupItemActions(); }); // 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'; }); }); }