feat: upload - deel 02
This commit is contained in:
@@ -57,6 +57,12 @@ let imageViewerState = {
|
||||
path: null,
|
||||
resizeHandler: null,
|
||||
};
|
||||
let uploadState = {
|
||||
active: false,
|
||||
targetPath: "",
|
||||
files: [],
|
||||
index: 0,
|
||||
};
|
||||
let settingsState = {
|
||||
activeTab: "general",
|
||||
logsLoaded: false,
|
||||
@@ -302,6 +308,17 @@ function infoElements() {
|
||||
};
|
||||
}
|
||||
|
||||
function uploadElements() {
|
||||
return {
|
||||
button: document.getElementById("upload-btn"),
|
||||
input: document.getElementById("upload-input"),
|
||||
progress: document.getElementById("upload-progress"),
|
||||
target: document.getElementById("upload-target"),
|
||||
currentFile: document.getElementById("upload-current-file"),
|
||||
count: document.getElementById("upload-count"),
|
||||
};
|
||||
}
|
||||
|
||||
async function apiRequest(method, url, body) {
|
||||
const options = { method, headers: {} };
|
||||
if (body !== undefined) {
|
||||
@@ -317,6 +334,23 @@ async function apiRequest(method, url, body) {
|
||||
return data;
|
||||
}
|
||||
|
||||
async function uploadFileRequest(targetPath, file) {
|
||||
const formData = new FormData();
|
||||
formData.append("target_path", targetPath);
|
||||
formData.append("file", file, file.name);
|
||||
|
||||
const response = await fetch("/api/files/upload", {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
});
|
||||
const data = await response.json().catch(() => ({}));
|
||||
if (!response.ok) {
|
||||
const error = data.error || {};
|
||||
throw new Error(error.message || `HTTP ${response.status}`);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
async function refreshTasksSnapshot() {
|
||||
try {
|
||||
const data = await apiRequest("GET", "/api/tasks");
|
||||
@@ -333,6 +367,76 @@ function createButton(text, onClick) {
|
||||
return button;
|
||||
}
|
||||
|
||||
function setUploadProgressVisible(visible) {
|
||||
uploadElements().progress.classList.toggle("hidden", !visible);
|
||||
}
|
||||
|
||||
function resetUploadProgress() {
|
||||
const elements = uploadElements();
|
||||
uploadState.active = false;
|
||||
uploadState.targetPath = "";
|
||||
uploadState.files = [];
|
||||
uploadState.index = 0;
|
||||
elements.button.disabled = false;
|
||||
elements.target.textContent = "";
|
||||
elements.currentFile.textContent = "";
|
||||
elements.count.textContent = "";
|
||||
setUploadProgressVisible(false);
|
||||
}
|
||||
|
||||
function updateUploadProgress() {
|
||||
const elements = uploadElements();
|
||||
const total = uploadState.files.length;
|
||||
const currentFile = uploadState.files[uploadState.index] || null;
|
||||
elements.target.textContent = `Upload to: ${uploadState.targetPath}`;
|
||||
elements.currentFile.textContent = currentFile
|
||||
? `Uploading ${total} file${total === 1 ? "" : "s"} - Current file: ${currentFile.name}`
|
||||
: `Uploading ${total} file${total === 1 ? "" : "s"}`;
|
||||
elements.count.textContent = total > 0 ? `${Math.min(uploadState.index + 1, total)}/${total} files` : "";
|
||||
elements.button.disabled = uploadState.active;
|
||||
setUploadProgressVisible(uploadState.active);
|
||||
}
|
||||
|
||||
function openUploadPicker() {
|
||||
if (uploadState.active) {
|
||||
return;
|
||||
}
|
||||
uploadState.targetPath = activePaneState().currentPath;
|
||||
const elements = uploadElements();
|
||||
elements.input.value = "";
|
||||
elements.input.click();
|
||||
}
|
||||
|
||||
async function handleUploadSelection(event) {
|
||||
const files = Array.from(event.target.files || []);
|
||||
event.target.value = "";
|
||||
if (files.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const targetPath = uploadState.targetPath || activePaneState().currentPath;
|
||||
uploadState.active = true;
|
||||
uploadState.targetPath = targetPath;
|
||||
uploadState.files = files;
|
||||
uploadState.index = 0;
|
||||
setError("actions-error", "");
|
||||
updateUploadProgress();
|
||||
|
||||
try {
|
||||
for (let index = 0; index < files.length; index += 1) {
|
||||
uploadState.index = index;
|
||||
updateUploadProgress();
|
||||
await uploadFileRequest(targetPath, files[index]);
|
||||
}
|
||||
await loadBrowsePane(state.activePane);
|
||||
setStatus(`Upload: ${files.length} file${files.length === 1 ? "" : "s"} uploaded`);
|
||||
} catch (err) {
|
||||
setActionError("Upload", err);
|
||||
} finally {
|
||||
resetUploadProgress();
|
||||
}
|
||||
}
|
||||
|
||||
function setActivePane(pane) {
|
||||
state.activePane = pane;
|
||||
document.getElementById("left-pane").classList.toggle("active-pane", pane === "left");
|
||||
@@ -2723,6 +2827,7 @@ function setupEvents() {
|
||||
setupPaneEvents("right");
|
||||
document.addEventListener("keydown", handleKeyboardShortcuts);
|
||||
document.getElementById("theme-toggle").onclick = toggleTheme;
|
||||
document.getElementById("upload-btn").onclick = openUploadPicker;
|
||||
document.getElementById("settings-btn").onclick = () => openSettings("general");
|
||||
document.getElementById("view-btn").onclick = openViewer;
|
||||
document.getElementById("edit-btn").onclick = openEditor;
|
||||
@@ -2731,6 +2836,7 @@ function setupEvents() {
|
||||
document.getElementById("copy-btn").onclick = startCopySelected;
|
||||
document.getElementById("move-btn").onclick = openF6Flow;
|
||||
document.getElementById("mkdir-btn").onclick = createFolderForActivePane;
|
||||
uploadElements().input.onchange = handleUploadSelection;
|
||||
|
||||
const rename = renameElements();
|
||||
rename.closeButton.onclick = closeRenamePopup;
|
||||
|
||||
Reference in New Issue
Block a user