144 lines
No EOL
4.4 KiB
JavaScript
144 lines
No EOL
4.4 KiB
JavaScript
/**
|
|
* Context Menu for Files/Folders
|
|
*/
|
|
|
|
class ContextMenu {
|
|
constructor() {
|
|
this.menu = null;
|
|
this.currentTarget = null;
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
// Create context menu element
|
|
this.menu = document.createElement('div');
|
|
this.menu.className = 'context-menu';
|
|
this.menu.style.display = 'none';
|
|
document.body.appendChild(this.menu);
|
|
|
|
// Close menu on click outside
|
|
document.addEventListener('click', (e) => {
|
|
if (this.menu.style.display === 'block') {
|
|
this.hideMenu();
|
|
}
|
|
});
|
|
|
|
// Prevent default context menu
|
|
document.addEventListener('contextmenu', (e) => {
|
|
if (e.target.closest('.file-item, .folder-item')) {
|
|
e.preventDefault();
|
|
this.showMenu(e);
|
|
}
|
|
});
|
|
|
|
// Close on escape key
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape' && this.menu.style.display === 'block') {
|
|
this.hideMenu();
|
|
}
|
|
});
|
|
}
|
|
|
|
showMenu(e) {
|
|
// Get target item
|
|
this.currentTarget = e.target.closest('.file-item, .folder-item');
|
|
const itemId = this.currentTarget.dataset.id;
|
|
const itemType = this.currentTarget.classList.contains('folder-item') ? 'folder' : 'file';
|
|
const itemName = this.currentTarget.querySelector('.item-name').textContent;
|
|
|
|
// Create menu items based on item type
|
|
this.menu.innerHTML = '';
|
|
|
|
if (itemType === 'folder') {
|
|
// Folder actions
|
|
this.addMenuItem('Open', 'fa-folder-open', () => {
|
|
window.location.href = `/files/browse/${itemId}`;
|
|
});
|
|
|
|
this.addMenuItem('Rename', 'fa-edit', () => {
|
|
openModal('rename-modal');
|
|
document.getElementById('new-name').value = itemName;
|
|
window.selectedItemId = itemId;
|
|
});
|
|
|
|
this.addMenuItem('Delete', 'fa-trash-alt', () => {
|
|
openModal('delete-modal');
|
|
window.selectedItemId = itemId;
|
|
});
|
|
} else {
|
|
// File actions
|
|
this.addMenuItem('Download', 'fa-download', () => {
|
|
window.location.href = `/files/download/${itemId}`;
|
|
});
|
|
|
|
this.addMenuItem('View', 'fa-eye', () => {
|
|
window.location.href = `/files/view/${itemId}`;
|
|
});
|
|
|
|
this.addMenuItem('Rename', 'fa-edit', () => {
|
|
openModal('rename-modal');
|
|
document.getElementById('new-name').value = itemName;
|
|
window.selectedItemId = itemId;
|
|
});
|
|
|
|
this.addMenuItem('Delete', 'fa-trash-alt', () => {
|
|
openModal('delete-modal');
|
|
window.selectedItemId = itemId;
|
|
});
|
|
}
|
|
|
|
// Position menu
|
|
const x = e.clientX;
|
|
const y = e.clientY;
|
|
|
|
// Set menu position
|
|
this.menu.style.left = `${x}px`;
|
|
this.menu.style.top = `${y}px`;
|
|
|
|
// Show menu with animation
|
|
this.menu.style.display = 'block';
|
|
|
|
// Adjust position if menu goes off screen
|
|
const menuRect = this.menu.getBoundingClientRect();
|
|
const windowWidth = window.innerWidth;
|
|
const windowHeight = window.innerHeight;
|
|
|
|
if (menuRect.right > windowWidth) {
|
|
this.menu.style.left = `${windowWidth - menuRect.width - 10}px`;
|
|
}
|
|
|
|
if (menuRect.bottom > windowHeight) {
|
|
this.menu.style.top = `${windowHeight - menuRect.height - 10}px`;
|
|
}
|
|
}
|
|
|
|
hideMenu() {
|
|
this.menu.style.display = 'none';
|
|
this.currentTarget = null;
|
|
}
|
|
|
|
addMenuItem(label, icon, action) {
|
|
const item = document.createElement('div');
|
|
item.className = 'context-menu-item';
|
|
item.innerHTML = `<i class="fas ${icon}"></i> ${label}`;
|
|
|
|
item.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
this.hideMenu();
|
|
action();
|
|
});
|
|
|
|
this.menu.appendChild(item);
|
|
}
|
|
|
|
addDivider() {
|
|
const divider = document.createElement('div');
|
|
divider.className = 'context-menu-divider';
|
|
this.menu.appendChild(divider);
|
|
}
|
|
}
|
|
|
|
// Initialize context menu
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
window.contextMenu = new ContextMenu();
|
|
});
|