From d3532a24ee1d77769d7635d0f21af8bf709464c6 Mon Sep 17 00:00:00 2001
From: thorved <54140516+thorved@users.noreply.github.com>
Date: Sat, 4 Oct 2025 15:03:51 +0530
Subject: [PATCH 1/3] Feature request: Add delete confirmation dialog to file
manager
- Added confirmation dialog before deleting files/folders
- Users must confirm deletion with a warning message
- Works for both Delete key and right-click delete
- Shows different messages for single file, folder, or multiple items
- Includes permanent deletion warning
- Follows existing design patterns using confirmWithToast
---
src/locales/en/translation.json | 4 +
.../Desktop/Apps/File Manager/FileManager.tsx | 121 +++++++++++-------
2 files changed, 80 insertions(+), 45 deletions(-)
diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json
index 0e6d735e..842f24fe 100644
--- a/src/locales/en/translation.json
+++ b/src/locales/en/translation.json
@@ -844,8 +844,12 @@
"selectServerToEdit": "Select a server from the sidebar to start editing files",
"fileOperations": "File Operations",
"confirmDeleteMessage": "Are you sure you want to delete {{name}}?",
+ "confirmDeleteSingleItem": "Are you sure you want to permanently delete \"{{name}}\"?",
+ "confirmDeleteMultipleItems": "Are you sure you want to permanently delete {{count}} items?",
+ "confirmDeleteFolder": "Are you sure you want to permanently delete the folder \"{{name}}\" and all its contents?",
"deleteDirectoryWarning": "This will delete the folder and all its contents.",
"actionCannotBeUndone": "This action cannot be undone.",
+ "permanentDeleteWarning": "This action cannot be undone. The item(s) will be permanently deleted from the server.",
"recent": "Recent",
"pinned": "Pinned",
"folderShortcuts": "Folder Shortcuts",
diff --git a/src/ui/Desktop/Apps/File Manager/FileManager.tsx b/src/ui/Desktop/Apps/File Manager/FileManager.tsx
index 0f05c589..b00efe06 100644
--- a/src/ui/Desktop/Apps/File Manager/FileManager.tsx
+++ b/src/ui/Desktop/Apps/File Manager/FileManager.tsx
@@ -9,6 +9,7 @@ import { FileWindow } from "./components/FileWindow";
import { DiffWindow } from "./components/DiffWindow";
import { useDragToDesktop } from "../../../hooks/useDragToDesktop";
import { useDragToSystemDesktop } from "../../../hooks/useDragToSystemDesktop";
+import { useConfirmation } from "@/hooks/use-confirmation.ts";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { toast } from "sonner";
@@ -82,6 +83,7 @@ function formatFileSize(bytes?: number): string {
function FileManagerContent({ initialHost, onClose }: FileManagerProps) {
const { openWindow } = useWindowManager();
const { t } = useTranslation();
+ const { confirmWithToast } = useConfirmation();
const [currentHost, setCurrentHost] = useState(
initialHost || null,
@@ -587,54 +589,83 @@ function FileManagerContent({ initialHost, onClose }: FileManagerProps) {
async function handleDeleteFiles(files: FileItem[]) {
if (!sshSessionId || files.length === 0) return;
- try {
- await ensureSSHConnection();
-
- for (const file of files) {
- await deleteSSHItem(
- sshSessionId,
- file.path,
- file.type === "directory",
- currentHost?.id,
- currentHost?.userId?.toString(),
- );
- }
-
- const deletedFiles = files.map((file) => ({
- path: file.path,
- name: file.name,
- }));
-
- const undoAction: UndoAction = {
- type: "delete",
- description: t("fileManager.deletedItems", { count: files.length }),
- data: {
- operation: "cut",
- deletedFiles,
- targetDirectory: currentPath,
- },
- timestamp: Date.now(),
- };
- setUndoHistory((prev) => [...prev.slice(-9), undoAction]);
-
- toast.success(
- t("fileManager.itemsDeletedSuccessfully", { count: files.length }),
- );
- handleRefreshDirectory();
- clearSelection();
- } catch (error: any) {
- if (
- error.message?.includes("connection") ||
- error.message?.includes("established")
- ) {
- toast.error(
- `SSH connection failed. Please check your connection to ${currentHost?.name} (${currentHost?.ip}:${currentHost?.port})`,
- );
+ // Determine the confirmation message based on file count and type
+ let confirmMessage: string;
+ if (files.length === 1) {
+ const file = files[0];
+ if (file.type === "directory") {
+ confirmMessage = t("fileManager.confirmDeleteFolder", {
+ name: file.name,
+ });
} else {
- toast.error(t("fileManager.failedToDeleteItems"));
+ confirmMessage = t("fileManager.confirmDeleteSingleItem", {
+ name: file.name,
+ });
}
- console.error("Delete failed:", error);
+ } else {
+ confirmMessage = t("fileManager.confirmDeleteMultipleItems", {
+ count: files.length,
+ });
}
+
+ // Add permanent deletion warning
+ const fullMessage = `${confirmMessage}\n\n${t("fileManager.permanentDeleteWarning")}`;
+
+ // Show confirmation dialog
+ confirmWithToast(
+ fullMessage,
+ async () => {
+ try {
+ await ensureSSHConnection();
+
+ for (const file of files) {
+ await deleteSSHItem(
+ sshSessionId,
+ file.path,
+ file.type === "directory",
+ currentHost?.id,
+ currentHost?.userId?.toString(),
+ );
+ }
+
+ const deletedFiles = files.map((file) => ({
+ path: file.path,
+ name: file.name,
+ }));
+
+ const undoAction: UndoAction = {
+ type: "delete",
+ description: t("fileManager.deletedItems", { count: files.length }),
+ data: {
+ operation: "cut",
+ deletedFiles,
+ targetDirectory: currentPath,
+ },
+ timestamp: Date.now(),
+ };
+ setUndoHistory((prev) => [...prev.slice(-9), undoAction]);
+
+ toast.success(
+ t("fileManager.itemsDeletedSuccessfully", { count: files.length }),
+ );
+ handleRefreshDirectory();
+ clearSelection();
+ } catch (error: any) {
+ if (
+ error.message?.includes("connection") ||
+ error.message?.includes("established")
+ ) {
+ toast.error(
+ `SSH connection failed. Please check your connection to ${currentHost?.name} (${currentHost?.ip}:${currentHost?.port})`,
+ );
+ } else {
+ toast.error(t("fileManager.failedToDeleteItems"));
+ }
+ console.error("Delete failed:", error);
+ }
+ },
+ "destructive",
+ );
}
function handleCreateNewFolder() {
--
2.49.1
From 05c019dfc26c0070eb37921aa03962857ef82157 Mon Sep 17 00:00:00 2001
From: thorved <54140516+thorved@users.noreply.github.com>
Date: Sat, 4 Oct 2025 15:29:04 +0530
Subject: [PATCH 2/3] Adds confirmation for deletion of items including folders
Updates the file deletion confirmation logic to distinguish between
deleting multiple items with or without folders. Introduces a new
translation string for a clearer user prompt when folders and their
contents are included in the deletion.
Improves clarity and reduces user error when performing bulk deletions.
---
src/locales/en/translation.json | 1 +
src/ui/Desktop/Apps/File Manager/FileManager.tsx | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json
index 842f24fe..d3aff79d 100644
--- a/src/locales/en/translation.json
+++ b/src/locales/en/translation.json
@@ -846,6 +846,7 @@
"confirmDeleteMessage": "Are you sure you want to delete {{name}}?",
"confirmDeleteSingleItem": "Are you sure you want to permanently delete \"{{name}}\"?",
"confirmDeleteMultipleItems": "Are you sure you want to permanently delete {{count}} items?",
+ "confirmDeleteMultipleItemsWithFolders": "Are you sure you want to permanently delete {{count}} items? This includes folders and their contents.",
"confirmDeleteFolder": "Are you sure you want to permanently delete the folder \"{{name}}\" and all its contents?",
"deleteDirectoryWarning": "This will delete the folder and all its contents.",
"actionCannotBeUndone": "This action cannot be undone.",
diff --git a/src/ui/Desktop/Apps/File Manager/FileManager.tsx b/src/ui/Desktop/Apps/File Manager/FileManager.tsx
index b00efe06..73ac9bc6 100644
--- a/src/ui/Desktop/Apps/File Manager/FileManager.tsx
+++ b/src/ui/Desktop/Apps/File Manager/FileManager.tsx
@@ -603,7 +603,12 @@ function FileManagerContent({ initialHost, onClose }: FileManagerProps) {
});
}
} else {
- confirmMessage = t("fileManager.confirmDeleteMultipleItems", {
+ const hasDirectory = files.some((file) => file.type === "directory");
+ const translationKey = hasDirectory
+ ? "fileManager.confirmDeleteMultipleItemsWithFolders"
+ : "fileManager.confirmDeleteMultipleItems";
+
+ confirmMessage = t(translationKey, {
count: files.length,
});
}
--
2.49.1
From f5df2b240b4e0c00f6d5de86979e0ab82da20919 Mon Sep 17 00:00:00 2001
From: thorved <54140516+thorved@users.noreply.github.com>
Date: Sat, 4 Oct 2025 16:14:29 +0530
Subject: [PATCH 3/3] feat: Add Chinese translations for delete confirmation
messages
---
src/locales/zh/translation.json | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/locales/zh/translation.json b/src/locales/zh/translation.json
index 62069e11..0cd92395 100644
--- a/src/locales/zh/translation.json
+++ b/src/locales/zh/translation.json
@@ -852,8 +852,13 @@
"selectServerToEdit": "从侧边栏选择服务器以开始编辑文件",
"fileOperations": "文件操作",
"confirmDeleteMessage": "确定要删除 {{name}} 吗?",
+ "confirmDeleteSingleItem": "确定要永久删除 \"{{name}}\" 吗?",
+ "confirmDeleteMultipleItems": "确定要永久删除 {{count}} 个项目吗?",
+ "confirmDeleteMultipleItemsWithFolders": "确定要永久删除 {{count}} 个项目吗?这包括文件夹及其内容。",
+ "confirmDeleteFolder": "确定要永久删除文件夹 \"{{name}}\" 及其所有内容吗?",
"deleteDirectoryWarning": "这将删除文件夹及其所有内容。",
"actionCannotBeUndone": "此操作无法撤销。",
+ "permanentDeleteWarning": "此操作无法撤销。项目将从服务器永久删除。",
"dragSystemFilesToUpload": "拖拽系统文件到此处上传",
"dragFilesToWindowToDownload": "拖拽文件到窗口外下载",
"openTerminalHere": "在此处打开终端",
--
2.49.1