diff --git a/public/js/adminPanel.js b/public/js/adminPanel.js
index 399dc96..2368925 100644
--- a/public/js/adminPanel.js
+++ b/public/js/adminPanel.js
@@ -3,7 +3,7 @@ import { loadAdminConfigFunc } from './auth.js';
import { showToast, toggleVisibility, attachEnterKeyListener } from './domUtils.js';
import { sendRequest } from './networkUtils.js';
-const version = "v1.3.7";
+const version = "v1.3.8";
const adminTitle = `${t("admin_panel")}
${version}`;
// ————— Inject updated styles —————
diff --git a/public/js/domUtils.js b/public/js/domUtils.js
index 60bd10b..f4f9b9f 100644
--- a/public/js/domUtils.js
+++ b/public/js/domUtils.js
@@ -39,7 +39,7 @@ export function updateFileActionButtons() {
const moveBtn = document.getElementById("moveSelectedBtn");
const zipBtn = document.getElementById("downloadZipBtn");
const extractZipBtn = document.getElementById("extractZipBtn");
- const createBtn = document.getElementById("createFileBtn");
+ const createBtn = document.getElementById("createBtn");
const anyFiles = fileCheckboxes.length > 0;
const anySelected = selectedCheckboxes.length > 0;
diff --git a/public/js/fileActions.js b/public/js/fileActions.js
index 1e40113..9821fca 100644
--- a/public/js/fileActions.js
+++ b/public/js/fileActions.js
@@ -688,4 +688,35 @@ document.addEventListener("DOMContentLoaded", () => {
attachEnterKeyListener("downloadFileModal", "confirmSingleDownloadButton");
});
+document.addEventListener('DOMContentLoaded', () => {
+ const btn = document.getElementById('createBtn');
+ const menu = document.getElementById('createMenu');
+ const fileOpt = document.getElementById('createFileOption');
+ const folderOpt= document.getElementById('createFolderOption');
+
+ // Toggle dropdown on click
+ btn.addEventListener('click', (e) => {
+ e.stopPropagation();
+ menu.style.display = menu.style.display === 'block' ? 'none' : 'block';
+ });
+
+ // Create File
+ fileOpt.addEventListener('click', () => {
+ menu.style.display = 'none';
+ openCreateFileModal(); // your existing function
+ });
+
+ // Create Folder
+ folderOpt.addEventListener('click', () => {
+ menu.style.display = 'none';
+ document.getElementById('createFolderModal').style.display = 'block';
+ document.getElementById('newFolderName').focus();
+ });
+
+ // Close if you click anywhere else
+ document.addEventListener('click', () => {
+ menu.style.display = 'none';
+ });
+});
+
window.renameFile = renameFile;
\ No newline at end of file
diff --git a/public/js/fileListView.js b/public/js/fileListView.js
index f6e27cf..43e8136 100644
--- a/public/js/fileListView.js
+++ b/public/js/fileListView.js
@@ -16,7 +16,16 @@ import { t } from './i18n.js';
import { bindFileListContextMenu } from './fileMenu.js';
import { openDownloadModal } from './fileActions.js';
import { openTagModal, openMultiTagModal } from './fileTags.js';
-import { getParentFolder, updateBreadcrumbTitle, setupBreadcrumbDelegation } from './folderManager.js';
+import {
+ getParentFolder,
+ updateBreadcrumbTitle,
+ setupBreadcrumbDelegation,
+ showFolderManagerContextMenu,
+ hideFolderManagerContextMenu,
+ openRenameFolderModal,
+ openDeleteFolderModal
+} from './folderManager.js';
+import { openFolderShareModal } from './folderShareModal.js';
import {
folderDragOverHandler,
folderDragLeaveHandler,
@@ -240,17 +249,40 @@ export async function loadFileList(folderParam) {
if (!data.files || Object.keys(data.files).length === 0) {
fileListContainer.textContent = t("no_files_found");
- // hide summary
+ // hide summary + slider
const summaryElem = document.getElementById("fileSummary");
if (summaryElem) summaryElem.style.display = "none";
-
- // hide slider
const sliderContainer = document.getElementById("viewSliderContainer");
if (sliderContainer) sliderContainer.style.display = "none";
- // hide folder strip
- const strip = document.getElementById("folderStripContainer");
- if (strip) strip.style.display = "none";
+ // show/hide folder strip *even when there are no files*
+ let strip = document.getElementById("folderStripContainer");
+ if (!strip) {
+ strip = document.createElement("div");
+ strip.id = "folderStripContainer";
+ strip.className = "folder-strip-container";
+ actionsContainer.parentNode.insertBefore(strip, fileListContainer);
+ }
+ if (window.showFoldersInList && subfolders.length) {
+ strip.innerHTML = subfolders.map(sf => `
+
+
folder
+
${escapeHTML(sf.name)}
+
+ `).join("");
+ strip.style.display = "flex";
+ strip.querySelectorAll(".folder-item").forEach(el => {
+ el.addEventListener("click", () => {
+ const dest = el.dataset.folder;
+ window.currentFolder = dest;
+ localStorage.setItem("lastOpenedFolder", dest);
+ updateBreadcrumbTitle(dest);
+ loadFileList(dest);
+ });
+ });
+ } else {
+ strip.style.display = "none";
+ }
updateFileActionButtons();
return [];
@@ -360,34 +392,73 @@ export async function loadFileList(folderParam) {
strip.className = "folder-strip-container";
actionsContainer.parentNode.insertBefore(strip, actionsContainer);
}
+
if (window.showFoldersInList && subfolders.length) {
strip.innerHTML = subfolders.map(sf => `
-
-
folder
-
${escapeHTML(sf.name)}
-
- `).join("");
+
+
folder
+
${escapeHTML(sf.name)}
+
+ `).join("");
strip.style.display = "flex";
+ // wire up each folder‐tile
strip.querySelectorAll(".folder-item").forEach(el => {
- // click‐to‐navigate
+ // 1) click to navigate
el.addEventListener("click", () => {
const dest = el.dataset.folder;
window.currentFolder = dest;
localStorage.setItem("lastOpenedFolder", dest);
updateBreadcrumbTitle(dest);
- document.querySelectorAll(".folder-option.selected")
- .forEach(o => o.classList.remove("selected"));
- document.querySelector(`.folder-option[data-folder="${dest}"]`)
- ?.classList.add("selected");
+ document.querySelectorAll(".folder-option.selected").forEach(o => o.classList.remove("selected"));
+ document.querySelector(`.folder-option[data-folder="${dest}"]`)?.classList.add("selected");
loadFileList(dest);
});
- // drag & drop handlers
+ // 2) drag & drop
el.addEventListener("dragover", folderDragOverHandler);
el.addEventListener("dragleave", folderDragLeaveHandler);
el.addEventListener("drop", folderDropHandler);
+
+ // 3) right-click context menu
+ el.addEventListener("contextmenu", e => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ const dest = el.dataset.folder;
+ window.currentFolder = dest;
+ localStorage.setItem("lastOpenedFolder", dest);
+
+ // highlight the strip tile
+ strip.querySelectorAll(".folder-item.selected").forEach(i => i.classList.remove("selected"));
+ el.classList.add("selected");
+
+ // reuse folderManager menu
+ const menuItems = [
+ {
+ label: t("create_folder"),
+ action: () => document.getElementById("createFolderModal").style.display = "block"
+ },
+ {
+ label: t("rename_folder"),
+ action: () => openRenameFolderModal()
+ },
+ {
+ label: t("folder_share"),
+ action: () => openFolderShareModal(dest)
+ },
+ {
+ label: t("delete_folder"),
+ action: () => openDeleteFolderModal()
+ }
+ ];
+ showFolderManagerContextMenu(e.pageX, e.pageY, menuItems);
+ });
});
+
+ // one global click to hide any open context menu
+ document.addEventListener("click", hideFolderManagerContextMenu);
+
} else {
strip.style.display = "none";
}
diff --git a/public/js/folderManager.js b/public/js/folderManager.js
index 556a935..1a1da8d 100644
--- a/public/js/folderManager.js
+++ b/public/js/folderManager.js
@@ -551,7 +551,7 @@ export function loadFolderList(selectedFolder) {
document.getElementById("renameFolderBtn").addEventListener("click", openRenameFolderModal);
document.getElementById("deleteFolderBtn").addEventListener("click", openDeleteFolderModal);
-function openRenameFolderModal() {
+export function openRenameFolderModal() {
const selectedFolder = window.currentFolder || "root";
if (!selectedFolder || selectedFolder === "root") {
showToast("Please select a valid folder to rename.");
@@ -614,7 +614,7 @@ document.getElementById("submitRenameFolder").addEventListener("click", function
});
});
-function openDeleteFolderModal() {
+export function openDeleteFolderModal() {
const selectedFolder = window.currentFolder || "root";
if (!selectedFolder || selectedFolder === "root") {
showToast("Please select a valid folder to delete.");
@@ -718,7 +718,7 @@ document.getElementById("submitCreateFolder").addEventListener("click", async ()
});
// ---------- CONTEXT MENU SUPPORT FOR FOLDER MANAGER ----------
-function showFolderManagerContextMenu(x, y, menuItems) {
+export function showFolderManagerContextMenu(x, y, menuItems) {
let menu = document.getElementById("folderManagerContextMenu");
if (!menu) {
menu = document.createElement("div");
@@ -765,7 +765,7 @@ function showFolderManagerContextMenu(x, y, menuItems) {
menu.style.display = "block";
}
-function hideFolderManagerContextMenu() {
+export function hideFolderManagerContextMenu() {
const menu = document.getElementById("folderManagerContextMenu");
if (menu) {
menu.style.display = "none";
@@ -796,7 +796,7 @@ function folderManagerContextMenuHandler(e) {
},
{
label: t("folder_share"),
- action: () => { openFolderShareModal(); }
+ action: () => { openFolderShareModal(folder); }
},
{
label: t("delete_folder"),