// domUtils.js // Basic DOM Helpers export function toggleVisibility(elementId, shouldShow) { const element = document.getElementById(elementId); if (element) { element.style.display = shouldShow ? "block" : "none"; } else { console.error(`Element with id "${elementId}" not found.`); } } export function escapeHTML(str) { return String(str) .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } export function toggleAllCheckboxes(masterCheckbox) { const checkboxes = document.querySelectorAll(".file-checkbox"); checkboxes.forEach(chk => { chk.checked = masterCheckbox.checked; }); updateFileActionButtons(); // update buttons based on current selection } export function updateFileActionButtons() { const fileCheckboxes = document.querySelectorAll("#fileList .file-checkbox"); const selectedCheckboxes = document.querySelectorAll("#fileList .file-checkbox:checked"); const copyBtn = document.getElementById("copySelectedBtn"); const moveBtn = document.getElementById("moveSelectedBtn"); const deleteBtn = document.getElementById("deleteSelectedBtn"); const zipBtn = document.getElementById("downloadZipBtn"); const extractZipBtn = document.getElementById("extractZipBtn"); if (fileCheckboxes.length === 0) { if (copyBtn) copyBtn.style.display = "none"; if (moveBtn) moveBtn.style.display = "none"; if (deleteBtn) deleteBtn.style.display = "none"; if (zipBtn) zipBtn.style.display = "none"; if (extractZipBtn) extractZipBtn.style.display = "none"; } else { if (copyBtn) copyBtn.style.display = "inline-block"; if (moveBtn) moveBtn.style.display = "inline-block"; if (deleteBtn) deleteBtn.style.display = "inline-block"; if (zipBtn) zipBtn.style.display = "inline-block"; if (extractZipBtn) extractZipBtn.style.display = "inline-block"; const anySelected = selectedCheckboxes.length > 0; if (copyBtn) copyBtn.disabled = !anySelected; if (moveBtn) moveBtn.disabled = !anySelected; if (deleteBtn) deleteBtn.disabled = !anySelected; if (zipBtn) zipBtn.disabled = !anySelected; if (extractZipBtn) { // Enable only if at least one selected file ends with .zip (case-insensitive). const anyZipSelected = Array.from(selectedCheckboxes).some(chk => chk.value.toLowerCase().endsWith(".zip") ); extractZipBtn.disabled = !anyZipSelected; } } } export function showToast(message, duration = 3000) { const toast = document.getElementById("customToast"); if (!toast) { console.error("Toast element not found"); return; } toast.textContent = message; toast.style.display = "block"; // Force reflow for transition effect. void toast.offsetWidth; toast.classList.add("show"); setTimeout(() => { toast.classList.remove("show"); setTimeout(() => { toast.style.display = "none"; }, 500); }, duration); } // --- DOM Building Functions for File Table --- export function buildSearchAndPaginationControls({ currentPage, totalPages, searchTerm }) { const safeSearchTerm = escapeHTML(searchTerm); return `
search
Page ${currentPage} of ${totalPages || 1}
`; } export function buildFileTableHeader(sortOrder) { return ` `; } export function buildFileTableRow(file, folderPath) { const safeFileName = escapeHTML(file.name); const safeModified = escapeHTML(file.modified); const safeUploaded = escapeHTML(file.uploaded); const safeSize = escapeHTML(file.size); const safeUploader = escapeHTML(file.uploader || "Unknown"); let previewButton = ""; if (/\.(jpg|jpeg|png|gif|bmp|webp|svg|ico|tif|tiff|eps|heic|pdf|mp4|webm|mov|mp3|wav|m4a|ogg|flac|aac|wma|opus)$/i.test(file.name)) { let previewIcon = ""; if (/\.(jpg|jpeg|png|gif|bmp|webp|svg|ico|tif|tiff|eps|heic)$/i.test(file.name)) { previewIcon = `image`; } else if (/\.(mp4|webm|mov)$/i.test(file.name)) { previewIcon = `videocam`; } else if (/\.pdf$/i.test(file.name)) { previewIcon = `picture_as_pdf`; } else if (/\.(mp3|wav|m4a|ogg|flac|aac|wma|opus)$/i.test(file.name)) { previewIcon = `audiotrack`; } previewButton = ``; } return ` `; } export function buildBottomControls(itemsPerPageSetting) { return `
items per page
`; } // --- Global Helper Functions --- export function debounce(func, wait) { let timeout; return function (...args) { clearTimeout(timeout); timeout = setTimeout(() => func.apply(this, args), wait); }; } export function updateRowHighlight(checkbox) { const row = checkbox.closest('tr'); if (!row) return; if (checkbox.checked) { row.classList.add('row-selected'); } else { row.classList.remove('row-selected'); } } export function toggleRowSelection(event, fileName) { const targetTag = event.target.tagName.toLowerCase(); if (targetTag === 'a' || targetTag === 'button' || targetTag === 'input') { return; } const row = event.currentTarget; const checkbox = row.querySelector('.file-checkbox'); if (!checkbox) return; checkbox.checked = !checkbox.checked; updateRowHighlight(checkbox); updateFileActionButtons(); } export function attachEnterKeyListener(modalId, buttonId) { const modal = document.getElementById(modalId); if (modal) { // Make the modal focusable modal.setAttribute("tabindex", "-1"); modal.focus(); modal.addEventListener("keydown", function(e) { if (e.key === "Enter") { e.preventDefault(); const btn = document.getElementById(buttonId); if (btn) { btn.click(); } } }); } } export function showCustomConfirmModal(message) { return new Promise((resolve) => { const modal = document.getElementById("customConfirmModal"); const messageElem = document.getElementById("confirmMessage"); const yesBtn = document.getElementById("confirmYesBtn"); const noBtn = document.getElementById("confirmNoBtn"); messageElem.textContent = message; modal.style.display = "block"; // Cleanup function to hide the modal and remove event listeners. function cleanup() { modal.style.display = "none"; yesBtn.removeEventListener("click", onYes); noBtn.removeEventListener("click", onNo); } function onYes() { cleanup(); resolve(true); } function onNo() { cleanup(); resolve(false); } yesBtn.addEventListener("click", onYes); noBtn.addEventListener("click", onNo); }); }
File Name ${sortOrder.column === "name" ? (sortOrder.ascending ? "▲" : "▼") : ""} Date Modified ${sortOrder.column === "modified" ? (sortOrder.ascending ? "▲" : "▼") : ""} Upload Date ${sortOrder.column === "uploaded" ? (sortOrder.ascending ? "▲" : "▼") : ""} File Size ${sortOrder.column === "size" ? (sortOrder.ascending ? "▲" : "▼") : ""} Uploader ${sortOrder.column === "uploader" ? (sortOrder.ascending ? "▲" : "▼") : ""} Actions
${safeFileName} ${safeModified} ${safeUploaded} ${safeSize} ${safeUploader}
file_download ${file.editable ? ` ` : ""} ${previewButton}