feat: file viewer added
This commit is contained in:
@@ -58,6 +58,18 @@ function showActionSummary(action, successes, failures, firstError) {
|
||||
setStatus(base);
|
||||
}
|
||||
|
||||
function viewerElements() {
|
||||
return {
|
||||
overlay: document.getElementById("viewer-modal"),
|
||||
title: document.getElementById("viewer-title"),
|
||||
fileName: document.getElementById("viewer-file-name"),
|
||||
filePath: document.getElementById("viewer-file-path"),
|
||||
error: document.getElementById("viewer-error"),
|
||||
content: document.getElementById("viewer-content"),
|
||||
closeButton: document.getElementById("viewer-close-btn"),
|
||||
};
|
||||
}
|
||||
|
||||
async function apiRequest(method, url, body) {
|
||||
const options = { method, headers: {} };
|
||||
if (body !== undefined) {
|
||||
@@ -145,6 +157,7 @@ function updateActionButtons() {
|
||||
const hasSelection = count > 0;
|
||||
const exactlyOne = count === 1;
|
||||
const allFiles = hasSelection && selectedItems.every((item) => item.kind === "file");
|
||||
document.getElementById("view-btn").disabled = !exactlyOne || !allFiles;
|
||||
document.getElementById("rename-btn").disabled = !exactlyOne;
|
||||
document.getElementById("delete-btn").disabled = !hasSelection;
|
||||
document.getElementById("copy-btn").disabled = !allFiles;
|
||||
@@ -633,6 +646,10 @@ function isWildcardPopupOpen() {
|
||||
return !wildcardPopupElements().overlay.classList.contains("hidden");
|
||||
}
|
||||
|
||||
function isViewerOpen() {
|
||||
return !viewerElements().overlay.classList.contains("hidden");
|
||||
}
|
||||
|
||||
function escapeRegExp(text) {
|
||||
return text.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
|
||||
}
|
||||
@@ -715,6 +732,40 @@ function openWildcardPopup(mode) {
|
||||
elements.input.focus();
|
||||
}
|
||||
|
||||
function closeViewer() {
|
||||
const viewer = viewerElements();
|
||||
viewer.overlay.classList.add("hidden");
|
||||
viewer.error.textContent = "";
|
||||
viewer.content.textContent = "";
|
||||
}
|
||||
|
||||
async function openViewer() {
|
||||
const selectedItems = activePaneState().selectedItems;
|
||||
if (selectedItems.length !== 1 || selectedItems[0].kind !== "file") {
|
||||
return;
|
||||
}
|
||||
const selected = selectedItems[0];
|
||||
const viewer = viewerElements();
|
||||
viewer.overlay.classList.remove("hidden");
|
||||
viewer.title.textContent = "View";
|
||||
viewer.fileName.textContent = selected.name;
|
||||
viewer.filePath.textContent = selected.path;
|
||||
viewer.error.textContent = "";
|
||||
viewer.content.textContent = "Loading...";
|
||||
try {
|
||||
const data = await apiRequest("GET", `/api/files/view?${new URLSearchParams({ path: selected.path }).toString()}`);
|
||||
viewer.fileName.textContent = data.name;
|
||||
viewer.filePath.textContent = data.path;
|
||||
viewer.content.textContent = data.content;
|
||||
if (data.truncated) {
|
||||
viewer.error.textContent = "Preview truncated for safety";
|
||||
}
|
||||
} catch (err) {
|
||||
viewer.content.textContent = "";
|
||||
viewer.error.textContent = err.message;
|
||||
}
|
||||
}
|
||||
|
||||
function moveCurrentRow(delta) {
|
||||
const pane = state.activePane;
|
||||
const model = paneState(pane);
|
||||
@@ -770,6 +821,13 @@ function clearSelectionForActivePane() {
|
||||
}
|
||||
|
||||
function handleKeyboardShortcuts(event) {
|
||||
if (isViewerOpen()) {
|
||||
if (event.key === "Escape") {
|
||||
event.preventDefault();
|
||||
closeViewer();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (isWildcardPopupOpen()) {
|
||||
return;
|
||||
}
|
||||
@@ -851,6 +909,7 @@ function setupEvents() {
|
||||
setupPaneEvents("left");
|
||||
setupPaneEvents("right");
|
||||
document.addEventListener("keydown", handleKeyboardShortcuts);
|
||||
document.getElementById("view-btn").onclick = openViewer;
|
||||
document.getElementById("rename-btn").onclick = renameSelected;
|
||||
document.getElementById("delete-btn").onclick = deleteSelected;
|
||||
document.getElementById("copy-btn").onclick = startCopySelected;
|
||||
@@ -876,6 +935,14 @@ function setupEvents() {
|
||||
closeWildcardPopup();
|
||||
}
|
||||
};
|
||||
|
||||
const viewer = viewerElements();
|
||||
viewer.closeButton.onclick = closeViewer;
|
||||
viewer.overlay.onclick = (event) => {
|
||||
if (event.target === viewer.overlay) {
|
||||
closeViewer();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function init() {
|
||||
|
||||
Reference in New Issue
Block a user