478 lines
16 KiB
JavaScript
478 lines
16 KiB
JavaScript
// fileActions.js
|
|
import { showToast, attachEnterKeyListener } from './domUtils.js';
|
|
import { loadFileList } from './fileListView.js';
|
|
import { formatFolderName } from './fileListView.js';
|
|
import { t } from './i18n.js';
|
|
|
|
export function handleDeleteSelected(e) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
const checkboxes = document.querySelectorAll(".file-checkbox:checked");
|
|
if (checkboxes.length === 0) {
|
|
showToast("no_files_selected");
|
|
return;
|
|
}
|
|
|
|
window.filesToDelete = Array.from(checkboxes).map(chk => chk.value);
|
|
const count = window.filesToDelete.length;
|
|
document.getElementById("deleteFilesMessage").textContent = t("confirm_delete_files", { count: count });
|
|
document.getElementById("deleteFilesModal").style.display = "block";
|
|
attachEnterKeyListener("deleteFilesModal", "confirmDeleteFiles");
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
const cancelDelete = document.getElementById("cancelDeleteFiles");
|
|
if (cancelDelete) {
|
|
cancelDelete.addEventListener("click", function () {
|
|
document.getElementById("deleteFilesModal").style.display = "none";
|
|
window.filesToDelete = [];
|
|
});
|
|
}
|
|
|
|
const confirmDelete = document.getElementById("confirmDeleteFiles");
|
|
if (confirmDelete) {
|
|
confirmDelete.addEventListener("click", function () {
|
|
fetch("deleteFiles.php", {
|
|
method: "POST",
|
|
credentials: "include",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"X-CSRF-Token": window.csrfToken
|
|
},
|
|
body: JSON.stringify({ folder: window.currentFolder, files: window.filesToDelete })
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showToast("Selected files deleted successfully!");
|
|
loadFileList(window.currentFolder);
|
|
} else {
|
|
showToast("Error: " + (data.error || "Could not delete files"));
|
|
}
|
|
})
|
|
.catch(error => console.error("Error deleting files:", error))
|
|
.finally(() => {
|
|
document.getElementById("deleteFilesModal").style.display = "none";
|
|
window.filesToDelete = [];
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
attachEnterKeyListener("downloadZipModal", "confirmDownloadZip");
|
|
export function handleDownloadZipSelected(e) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
const checkboxes = document.querySelectorAll(".file-checkbox:checked");
|
|
if (checkboxes.length === 0) {
|
|
showToast("No files selected for download.");
|
|
return;
|
|
}
|
|
window.filesToDownload = Array.from(checkboxes).map(chk => chk.value);
|
|
document.getElementById("downloadZipModal").style.display = "block";
|
|
setTimeout(() => {
|
|
const input = document.getElementById("zipFileNameInput");
|
|
input.focus();
|
|
}, 100);
|
|
};
|
|
|
|
export function handleExtractZipSelected(e) {
|
|
if (e) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
}
|
|
const checkboxes = document.querySelectorAll(".file-checkbox:checked");
|
|
if (!checkboxes.length) {
|
|
showToast("No files selected.");
|
|
return;
|
|
}
|
|
const zipFiles = Array.from(checkboxes)
|
|
.map(chk => chk.value)
|
|
.filter(name => name.toLowerCase().endsWith(".zip"));
|
|
if (!zipFiles.length) {
|
|
showToast("No zip files selected.");
|
|
return;
|
|
}
|
|
fetch("extractZip.php", {
|
|
method: "POST",
|
|
credentials: "include",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"X-CSRF-Token": window.csrfToken
|
|
},
|
|
body: JSON.stringify({
|
|
folder: window.currentFolder || "root",
|
|
files: zipFiles
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
let toastMessage = "Zip file(s) extracted successfully!";
|
|
if (data.extractedFiles && Array.isArray(data.extractedFiles) && data.extractedFiles.length) {
|
|
toastMessage = "Extracted: " + data.extractedFiles.join(", ");
|
|
}
|
|
showToast(toastMessage);
|
|
loadFileList(window.currentFolder);
|
|
} else {
|
|
showToast("Error extracting zip: " + (data.error || "Unknown error"));
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error("Error extracting zip files:", error);
|
|
showToast("Error extracting zip files.");
|
|
});
|
|
}
|
|
|
|
const extractZipBtn = document.getElementById("extractZipBtn");
|
|
if (extractZipBtn) {
|
|
extractZipBtn.replaceWith(extractZipBtn.cloneNode(true));
|
|
document.getElementById("extractZipBtn").addEventListener("click", handleExtractZipSelected);
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
const cancelDownloadZip = document.getElementById("cancelDownloadZip");
|
|
if (cancelDownloadZip) {
|
|
cancelDownloadZip.addEventListener("click", function () {
|
|
document.getElementById("downloadZipModal").style.display = "none";
|
|
});
|
|
}
|
|
|
|
const confirmDownloadZip = document.getElementById("confirmDownloadZip");
|
|
if (confirmDownloadZip) {
|
|
confirmDownloadZip.addEventListener("click", function () {
|
|
let zipName = document.getElementById("zipFileNameInput").value.trim();
|
|
if (!zipName) {
|
|
showToast("Please enter a name for the zip file.");
|
|
return;
|
|
}
|
|
if (!zipName.toLowerCase().endsWith(".zip")) {
|
|
zipName += ".zip";
|
|
}
|
|
document.getElementById("downloadZipModal").style.display = "none";
|
|
const folder = window.currentFolder || "root";
|
|
fetch("downloadZip.php", {
|
|
method: "POST",
|
|
credentials: "include",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"X-CSRF-Token": window.csrfToken
|
|
},
|
|
body: JSON.stringify({ folder: folder, files: window.filesToDownload })
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
return response.text().then(text => {
|
|
throw new Error("Failed to create zip file: " + text);
|
|
});
|
|
}
|
|
return response.blob();
|
|
})
|
|
.then(blob => {
|
|
if (!blob || blob.size === 0) {
|
|
throw new Error("Received empty zip file.");
|
|
}
|
|
const url = window.URL.createObjectURL(blob);
|
|
const a = document.createElement("a");
|
|
a.style.display = "none";
|
|
a.href = url;
|
|
a.download = zipName;
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
window.URL.revokeObjectURL(url);
|
|
a.remove();
|
|
showToast("Download started.");
|
|
})
|
|
.catch(error => {
|
|
console.error("Error downloading zip:", error);
|
|
showToast("Error downloading selected files as zip: " + error.message);
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
export function handleCopySelected(e) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
const checkboxes = document.querySelectorAll(".file-checkbox:checked");
|
|
if (checkboxes.length === 0) {
|
|
showToast("No files selected for copying.", 5000);
|
|
return;
|
|
}
|
|
window.filesToCopy = Array.from(checkboxes).map(chk => chk.value);
|
|
document.getElementById("copyFilesModal").style.display = "block";
|
|
loadCopyMoveFolderListForModal("copyTargetFolder");
|
|
}
|
|
|
|
export async function loadCopyMoveFolderListForModal(dropdownId) {
|
|
const folderSelect = document.getElementById(dropdownId);
|
|
folderSelect.innerHTML = "";
|
|
|
|
if (window.userFolderOnly) {
|
|
const username = localStorage.getItem("username") || "root";
|
|
try {
|
|
const response = await fetch("getFolderList.php?restricted=1");
|
|
let folders = await response.json();
|
|
if (Array.isArray(folders) && folders.length && typeof folders[0] === "object" && folders[0].folder) {
|
|
folders = folders.map(item => item.folder);
|
|
}
|
|
folders = folders.filter(folder =>
|
|
folder.toLowerCase() !== "trash" &&
|
|
(folder === username || folder.indexOf(username + "/") === 0)
|
|
);
|
|
|
|
const rootOption = document.createElement("option");
|
|
rootOption.value = username;
|
|
rootOption.textContent = formatFolderName(username);
|
|
folderSelect.appendChild(rootOption);
|
|
|
|
folders.forEach(folder => {
|
|
if (folder !== username) {
|
|
const option = document.createElement("option");
|
|
option.value = folder;
|
|
option.textContent = formatFolderName(folder);
|
|
folderSelect.appendChild(option);
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error("Error loading folder list for modal:", error);
|
|
}
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch("getFolderList.php");
|
|
let folders = await response.json();
|
|
if (Array.isArray(folders) && folders.length && typeof folders[0] === "object" && folders[0].folder) {
|
|
folders = folders.map(item => item.folder);
|
|
}
|
|
folders = folders.filter(folder => folder !== "root" && folder.toLowerCase() !== "trash");
|
|
|
|
const rootOption = document.createElement("option");
|
|
rootOption.value = "root";
|
|
rootOption.textContent = "(Root)";
|
|
folderSelect.appendChild(rootOption);
|
|
|
|
if (Array.isArray(folders) && folders.length > 0) {
|
|
folders.forEach(folder => {
|
|
const option = document.createElement("option");
|
|
option.value = folder;
|
|
option.textContent = folder;
|
|
folderSelect.appendChild(option);
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error("Error loading folder list for modal:", error);
|
|
}
|
|
}
|
|
|
|
export function handleMoveSelected(e) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
const checkboxes = document.querySelectorAll(".file-checkbox:checked");
|
|
if (checkboxes.length === 0) {
|
|
showToast("No files selected for moving.");
|
|
return;
|
|
}
|
|
window.filesToMove = Array.from(checkboxes).map(chk => chk.value);
|
|
document.getElementById("moveFilesModal").style.display = "block";
|
|
loadCopyMoveFolderListForModal("moveTargetFolder");
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
const cancelCopy = document.getElementById("cancelCopyFiles");
|
|
if (cancelCopy) {
|
|
cancelCopy.addEventListener("click", function () {
|
|
document.getElementById("copyFilesModal").style.display = "none";
|
|
window.filesToCopy = [];
|
|
});
|
|
}
|
|
const confirmCopy = document.getElementById("confirmCopyFiles");
|
|
if (confirmCopy) {
|
|
confirmCopy.addEventListener("click", function () {
|
|
const targetFolder = document.getElementById("copyTargetFolder").value;
|
|
if (!targetFolder) {
|
|
showToast("Please select a target folder for copying.", 5000);
|
|
return;
|
|
}
|
|
if (targetFolder === window.currentFolder) {
|
|
showToast("Error: Cannot copy files to the same folder.");
|
|
return;
|
|
}
|
|
fetch("copyFiles.php", {
|
|
method: "POST",
|
|
credentials: "include",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"X-CSRF-Token": window.csrfToken
|
|
},
|
|
body: JSON.stringify({
|
|
source: window.currentFolder,
|
|
files: window.filesToCopy,
|
|
destination: targetFolder
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showToast("Selected files copied successfully!", 5000);
|
|
loadFileList(window.currentFolder);
|
|
} else {
|
|
showToast("Error: " + (data.error || "Could not copy files"), 5000);
|
|
}
|
|
})
|
|
.catch(error => console.error("Error copying files:", error))
|
|
.finally(() => {
|
|
document.getElementById("copyFilesModal").style.display = "none";
|
|
window.filesToCopy = [];
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
const cancelMove = document.getElementById("cancelMoveFiles");
|
|
if (cancelMove) {
|
|
cancelMove.addEventListener("click", function () {
|
|
document.getElementById("moveFilesModal").style.display = "none";
|
|
window.filesToMove = [];
|
|
});
|
|
}
|
|
const confirmMove = document.getElementById("confirmMoveFiles");
|
|
if (confirmMove) {
|
|
confirmMove.addEventListener("click", function () {
|
|
const targetFolder = document.getElementById("moveTargetFolder").value;
|
|
if (!targetFolder) {
|
|
showToast("Please select a target folder for moving.");
|
|
return;
|
|
}
|
|
if (targetFolder === window.currentFolder) {
|
|
showToast("Error: Cannot move files to the same folder.");
|
|
return;
|
|
}
|
|
fetch("moveFiles.php", {
|
|
method: "POST",
|
|
credentials: "include",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"X-CSRF-Token": window.csrfToken
|
|
},
|
|
body: JSON.stringify({
|
|
source: window.currentFolder,
|
|
files: window.filesToMove,
|
|
destination: targetFolder
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showToast("Selected files moved successfully!");
|
|
loadFileList(window.currentFolder);
|
|
} else {
|
|
showToast("Error: " + (data.error || "Could not move files"));
|
|
}
|
|
})
|
|
.catch(error => console.error("Error moving files:", error))
|
|
.finally(() => {
|
|
document.getElementById("moveFilesModal").style.display = "none";
|
|
window.filesToMove = [];
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
export function renameFile(oldName, folder) {
|
|
window.fileToRename = oldName;
|
|
window.fileFolder = folder || window.currentFolder || "root";
|
|
document.getElementById("newFileName").value = oldName;
|
|
document.getElementById("renameFileModal").style.display = "block";
|
|
setTimeout(() => {
|
|
const input = document.getElementById("newFileName");
|
|
input.focus();
|
|
const lastDot = oldName.lastIndexOf('.');
|
|
if (lastDot > 0) {
|
|
input.setSelectionRange(0, lastDot);
|
|
} else {
|
|
input.select();
|
|
}
|
|
}, 100);
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
const cancelBtn = document.getElementById("cancelRenameFile");
|
|
if (cancelBtn) {
|
|
cancelBtn.addEventListener("click", function () {
|
|
document.getElementById("renameFileModal").style.display = "none";
|
|
document.getElementById("newFileName").value = "";
|
|
});
|
|
}
|
|
|
|
const submitBtn = document.getElementById("submitRenameFile");
|
|
if (submitBtn) {
|
|
submitBtn.addEventListener("click", function () {
|
|
const newName = document.getElementById("newFileName").value.trim();
|
|
if (!newName || newName === window.fileToRename) {
|
|
document.getElementById("renameFileModal").style.display = "none";
|
|
return;
|
|
}
|
|
const folderUsed = window.fileFolder;
|
|
fetch("renameFile.php", {
|
|
method: "POST",
|
|
credentials: "include",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"X-CSRF-Token": window.csrfToken
|
|
},
|
|
body: JSON.stringify({ folder: folderUsed, oldName: window.fileToRename, newName: newName })
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showToast("File renamed successfully!");
|
|
loadFileList(folderUsed);
|
|
} else {
|
|
showToast("Error renaming file: " + (data.error || "Unknown error"));
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error("Error renaming file:", error);
|
|
showToast("Error renaming file");
|
|
})
|
|
.finally(() => {
|
|
document.getElementById("renameFileModal").style.display = "none";
|
|
document.getElementById("newFileName").value = "";
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
// Expose initFileActions so it can be called from fileManager.js
|
|
export function initFileActions() {
|
|
const deleteSelectedBtn = document.getElementById("deleteSelectedBtn");
|
|
if (deleteSelectedBtn) {
|
|
deleteSelectedBtn.replaceWith(deleteSelectedBtn.cloneNode(true));
|
|
document.getElementById("deleteSelectedBtn").addEventListener("click", handleDeleteSelected);
|
|
}
|
|
const copySelectedBtn = document.getElementById("copySelectedBtn");
|
|
if (copySelectedBtn) {
|
|
copySelectedBtn.replaceWith(copySelectedBtn.cloneNode(true));
|
|
document.getElementById("copySelectedBtn").addEventListener("click", handleCopySelected);
|
|
}
|
|
const moveSelectedBtn = document.getElementById("moveSelectedBtn");
|
|
if (moveSelectedBtn) {
|
|
moveSelectedBtn.replaceWith(moveSelectedBtn.cloneNode(true));
|
|
document.getElementById("moveSelectedBtn").addEventListener("click", handleMoveSelected);
|
|
}
|
|
const downloadZipBtn = document.getElementById("downloadZipBtn");
|
|
if (downloadZipBtn) {
|
|
downloadZipBtn.replaceWith(downloadZipBtn.cloneNode(true));
|
|
document.getElementById("downloadZipBtn").addEventListener("click", handleDownloadZipSelected);
|
|
}
|
|
const extractZipBtn = document.getElementById("extractZipBtn");
|
|
if (extractZipBtn) {
|
|
extractZipBtn.replaceWith(extractZipBtn.cloneNode(true));
|
|
document.getElementById("extractZipBtn").addEventListener("click", handleExtractZipSelected);
|
|
}
|
|
}
|
|
|
|
window.renameFile = renameFile; |