feat: download - fase 01
This commit is contained in:
@@ -328,6 +328,7 @@ function contextMenuElements() {
|
||||
target: document.getElementById("context-menu-target"),
|
||||
openButton: document.getElementById("context-menu-open-btn"),
|
||||
editButton: document.getElementById("context-menu-edit-btn"),
|
||||
downloadButton: document.getElementById("context-menu-download-btn"),
|
||||
renameButton: document.getElementById("context-menu-rename-btn"),
|
||||
copyButton: document.getElementById("context-menu-copy-btn"),
|
||||
moveButton: document.getElementById("context-menu-move-btn"),
|
||||
@@ -383,12 +384,15 @@ function openContextMenu(pane, entry, event) {
|
||||
const isMulti = items.length > 1;
|
||||
const openableSingle = items.length === 1 && isOpenableSelection(items[0]);
|
||||
const editableSingle = items.length === 1 && isEditableSelection(items[0]);
|
||||
const downloadableSingle = items.length === 1 && items[0].kind === "file";
|
||||
elements.scope.textContent = isMulti ? "Multi-selection" : "Single item";
|
||||
elements.target.textContent = isMulti ? `${items.length} selected items` : entry.name;
|
||||
elements.openButton.classList.toggle("hidden", isMulti);
|
||||
elements.openButton.disabled = !openableSingle;
|
||||
elements.editButton.classList.toggle("hidden", isMulti || items.length !== 1 || items[0].kind !== "file");
|
||||
elements.editButton.disabled = !editableSingle;
|
||||
elements.downloadButton.classList.toggle("hidden", !downloadableSingle);
|
||||
elements.downloadButton.disabled = !downloadableSingle;
|
||||
elements.renameButton.classList.toggle("hidden", isMulti);
|
||||
elements.copyButton.classList.remove("hidden");
|
||||
elements.copyButton.disabled = items.length === 0;
|
||||
@@ -490,6 +494,40 @@ function startContextMenuEdit() {
|
||||
openEditor();
|
||||
}
|
||||
|
||||
async function startDownloadSelected() {
|
||||
const selectedItems = activePaneState().selectedItems;
|
||||
if (selectedItems.length !== 1 || selectedItems[0].kind !== "file") {
|
||||
return;
|
||||
}
|
||||
const selected = selectedItems[0];
|
||||
try {
|
||||
const blob = await downloadFileRequest(selected.path);
|
||||
const url = URL.createObjectURL(blob);
|
||||
const anchor = document.createElement("a");
|
||||
anchor.href = url;
|
||||
anchor.download = selected.name;
|
||||
document.body.append(anchor);
|
||||
anchor.click();
|
||||
anchor.remove();
|
||||
URL.revokeObjectURL(url);
|
||||
setStatus(`Download started: ${selected.name}`);
|
||||
} catch (err) {
|
||||
setActionError("Download", err);
|
||||
}
|
||||
}
|
||||
|
||||
function startContextMenuDownload() {
|
||||
if (contextMenuElements().downloadButton?.disabled) {
|
||||
return;
|
||||
}
|
||||
if (!applyContextMenuSelection()) {
|
||||
closeContextMenu();
|
||||
return;
|
||||
}
|
||||
closeContextMenu();
|
||||
startDownloadSelected();
|
||||
}
|
||||
|
||||
function startContextMenuProperties() {
|
||||
if (contextMenuElements().propertiesButton?.disabled) {
|
||||
return;
|
||||
@@ -744,6 +782,15 @@ function createApiError(response, data) {
|
||||
return err;
|
||||
}
|
||||
|
||||
async function downloadFileRequest(path) {
|
||||
const response = await fetch(`/api/files/download?${new URLSearchParams({ path }).toString()}`);
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => ({}));
|
||||
throw createApiError(response, data);
|
||||
}
|
||||
return response.blob();
|
||||
}
|
||||
|
||||
async function uploadFileRequest(targetPath, file, overwrite = false) {
|
||||
const formData = new FormData();
|
||||
formData.append("target_path", targetPath);
|
||||
@@ -3836,6 +3883,9 @@ function setupEvents() {
|
||||
if (contextMenu.editButton) {
|
||||
contextMenu.editButton.onclick = startContextMenuEdit;
|
||||
}
|
||||
if (contextMenu.downloadButton) {
|
||||
contextMenu.downloadButton.onclick = startContextMenuDownload;
|
||||
}
|
||||
if (contextMenu.copyButton) {
|
||||
contextMenu.copyButton.onclick = startContextMenuCopy;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user