From 997e825a8576c35582149a265e0d9d19fd22ea1e Mon Sep 17 00:00:00 2001 From: Ryan Date: Sun, 16 Mar 2025 11:57:00 -0400 Subject: [PATCH] persistent folder state --- fileManager.js | 21 +++++++++++++-------- folderManager.js | 22 ++++++++++++++++++---- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/fileManager.js b/fileManager.js index d9ed7f0..958922e 100644 --- a/fileManager.js +++ b/fileManager.js @@ -93,33 +93,38 @@ window.updateRowHighlight = function (checkbox) { export function loadFileList(folderParam) { const folder = folderParam || "root"; - // Request a recursive listing from the server. + const fileListContainer = document.getElementById("fileList"); + + // Hide the container while loading + fileListContainer.style.visibility = "hidden"; + fileListContainer.innerHTML = "
Loading files...
"; + return fetch("getFileList.php?folder=" + encodeURIComponent(folder) + "&recursive=1&t=" + new Date().getTime()) .then(response => response.json()) .then(data => { - const fileListContainer = document.getElementById("fileList"); + // Clear the container once data is loaded fileListContainer.innerHTML = ""; if (data.files && data.files.length > 0) { - // Map each file so that we have a full name that includes subfolder information. - // We assume that getFileList.php returns a property 'path' that contains the full relative path (e.g. "subfolder/filename.txt") data.files = data.files.map(file => { - // If file.path exists, use that; otherwise fallback to file.name. file.fullName = (file.path || file.name).trim().toLowerCase(); return file; }); - // Save fileData and render file table using your full list. fileData = data.files; renderFileTable(folder); } else { fileListContainer.textContent = "No files found."; updateFileActionButtons(); } - // Return the full file objects. return data.files || []; }) .catch(error => { console.error("Error loading file list:", error); + fileListContainer.textContent = "Error loading files."; return []; + }) + .finally(() => { + // Make the container visible after processing + fileListContainer.style.visibility = "visible"; }); } @@ -217,7 +222,7 @@ export function renderFileTable(folder) { 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|ogg)$/i.test(file.name)) { + } else if (/\.(mp4|webm|ogg)$/i.test(file.name)) { previewIcon = `videocam`; } else if (/\.pdf$/i.test(file.name)) { previewIcon = `picture_as_pdf`; diff --git a/folderManager.js b/folderManager.js index a5caa44..696eff5 100644 --- a/folderManager.js +++ b/folderManager.js @@ -75,7 +75,6 @@ function renderFolderTree(tree, parentPath = "", defaultDisplay = "block") { const hasChildren = Object.keys(tree[folder]).length > 0; // Use saved state if exists; otherwise use the defaultDisplay. const displayState = state[fullPath] !== undefined ? state[fullPath] : defaultDisplay; - const ulClass = displayState === "none" ? "collapsed" : "expanded"; html += `
  • `; if (hasChildren) { const toggleSymbol = (displayState === "none") ? "[+]" : "[-]"; @@ -169,20 +168,31 @@ export async function loadFolderTree(selectedFolder) { container.innerHTML = html; console.log("Rendered folder tree HTML:", container.innerHTML); + // Use the provided selectedFolder if available, + // otherwise check localStorage for the last opened folder. if (selectedFolder) { window.currentFolder = selectedFolder; - } else if (!window.currentFolder) { - window.currentFolder = "root"; + } else { + window.currentFolder = localStorage.getItem("lastOpenedFolder") || "root"; } + localStorage.setItem("lastOpenedFolder", window.currentFolder); document.getElementById("fileListTitle").textContent = window.currentFolder === "root" ? "Files in (Root)" : "Files in (" + window.currentFolder + ")"; loadFileList(window.currentFolder); - if (window.currentFolder !== "root") { + const folderState = loadFolderTreeState(); + if (window.currentFolder !== "root" && folderState[window.currentFolder] !== "none") { expandTreePath(window.currentFolder); } + // --- NEW SNIPPET: Highlight the current folder --- + const selectedEl = container.querySelector(`.folder-option[data-folder="${window.currentFolder}"]`); + if (selectedEl) { + selectedEl.classList.add("selected"); + } + // ---------------------------------------------------- + // Attach events to folder options. container.querySelectorAll(".folder-option").forEach(el => { el.addEventListener("click", function (e) { @@ -191,6 +201,7 @@ export async function loadFolderTree(selectedFolder) { this.classList.add("selected"); const selected = this.getAttribute("data-folder"); window.currentFolder = selected; + localStorage.setItem("lastOpenedFolder", selected); document.getElementById("fileListTitle").textContent = selected === "root" ? "Files in (Root)" : "Files in (" + selected + ")"; loadFileList(selected); @@ -303,6 +314,7 @@ document.getElementById("submitRenameFolder").addEventListener("click", function if (data.success) { showToast("Folder renamed successfully!"); window.currentFolder = newFolderFull; + localStorage.setItem("lastOpenedFolder", newFolderFull); loadFolderList(newFolderFull); } else { showToast("Error: " + (data.error || "Could not rename folder")); @@ -343,6 +355,7 @@ document.getElementById("confirmDeleteFolder").addEventListener("click", functio showToast("Folder deleted successfully!"); // Set current folder to the parent folder, not root window.currentFolder = getParentFolder(selectedFolder); + localStorage.setItem("lastOpenedFolder", window.currentFolder); loadFolderList(window.currentFolder); } else { showToast("Error: " + (data.error || "Could not delete folder")); @@ -386,6 +399,7 @@ document.getElementById("submitCreateFolder").addEventListener("click", function if (data.success) { showToast("Folder created successfully!"); window.currentFolder = fullFolderName; + localStorage.setItem("lastOpenedFolder", fullFolderName); loadFolderList(fullFolderName); } else { showToast("Error: " + (data.error || "Could not create folder"));