Implement draggable file windows - Windows Explorer style
Added comprehensive draggable window system with the following features: 🪟 **DraggableWindow Component**: - Full drag and drop functionality with title bar dragging - Window resizing from all edges and corners - Maximize/minimize/close window controls - Double-click title bar to maximize/restore - Auto position adjustment to prevent off-screen windows - Windows-style blue gradient title bar 📁 **FileViewer Component**: - Multi-format file support (text, code, images, videos, audio) - Syntax highlighting distinction for code files - Editable text files with real-time content tracking - File metadata display (size, modified date, permissions) - Save and download functionality - Unsaved changes indicator 🎯 **WindowManager System**: - Multi-window support with proper z-index management - Window factory pattern for dynamic component creation - Focus management - clicking brings window to front - Smart window positioning with auto-offset - Memory leak prevention with proper cleanup 🔗 **FileWindow Integration**: - SSH file loading with error handling - Auto-detect editable file types - Real-time file saving to remote server - Download files as binary blobs - Loading states and progress feedback ✨ **User Experience**: - Double-click any file to open in draggable window - Multiple files can be open simultaneously - Windows behave like native Windows Explorer - Smooth animations and transitions - Responsive design that works on all screen sizes This transforms the file manager from a basic browser into a full desktop-class application with native OS window management behavior.
This commit is contained in:
@@ -3,6 +3,8 @@ import { FileManagerGrid } from "./FileManagerGrid";
|
||||
import { FileManagerContextMenu } from "./FileManagerContextMenu";
|
||||
import { useFileSelection } from "./hooks/useFileSelection";
|
||||
import { useDragAndDrop } from "./hooks/useDragAndDrop";
|
||||
import { WindowManager, useWindowManager } from "./components/WindowManager";
|
||||
import { FileWindow } from "./components/FileWindow";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { toast } from "sonner";
|
||||
@@ -47,7 +49,9 @@ interface FileManagerModernProps {
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
export function FileManagerModern({ initialHost, onClose }: FileManagerModernProps) {
|
||||
// 内部组件,使用窗口管理器
|
||||
function FileManagerContent({ initialHost, onClose }: FileManagerModernProps) {
|
||||
const { openWindow } = useWindowManager();
|
||||
const { t } = useTranslation();
|
||||
|
||||
// State
|
||||
@@ -329,8 +333,38 @@ export function FileManagerModern({ initialHost, onClose }: FileManagerModernPro
|
||||
if (file.type === 'directory') {
|
||||
setCurrentPath(file.path);
|
||||
} else {
|
||||
// 打开文件编辑器或预览
|
||||
console.log("Open file:", file);
|
||||
// 在新窗口中打开文件
|
||||
if (!sshSessionId) {
|
||||
toast.error(t("fileManager.noSSHConnection"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算窗口位置(稍微错开)
|
||||
const windowCount = Date.now() % 10; // 简单的偏移计算
|
||||
const offsetX = 120 + (windowCount * 30);
|
||||
const offsetY = 120 + (windowCount * 30);
|
||||
|
||||
// 创建窗口组件工厂函数
|
||||
const createWindowComponent = (windowId: string) => (
|
||||
<FileWindow
|
||||
windowId={windowId}
|
||||
file={file}
|
||||
sshSessionId={sshSessionId}
|
||||
initialX={offsetX}
|
||||
initialY={offsetY}
|
||||
/>
|
||||
);
|
||||
|
||||
openWindow({
|
||||
title: file.name,
|
||||
x: offsetX,
|
||||
y: offsetY,
|
||||
width: 800,
|
||||
height: 600,
|
||||
isMaximized: false,
|
||||
isMinimized: false,
|
||||
component: createWindowComponent
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -538,4 +572,13 @@ export function FileManagerModern({ initialHost, onClose }: FileManagerModernPro
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 主要的导出组件,包装了 WindowManager
|
||||
export function FileManagerModern({ initialHost, onClose }: FileManagerModernProps) {
|
||||
return (
|
||||
<WindowManager>
|
||||
<FileManagerContent initialHost={initialHost} onClose={onClose} />
|
||||
</WindowManager>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user