Files
Termix/src/ui/Desktop/Apps/File Manager/hooks/useFileSelection.ts
ZacharyZcR 49e7159939 Implement modern file manager with drag-and-drop interface
Major UI/UX improvements to replace clunky sidebar with modern grid layout:

- Add FileManagerModern component with grid-based file browser
- Implement drag-and-drop file upload with validation and progress
- Add comprehensive context menu with file operations (copy/cut/paste/delete)
- Create intelligent file selection system with multi-select support
- Add modern toolbar with search, view switching, and file operations
- Integrate seamless view switching between classic and modern interfaces
- Support keyboard shortcuts and accessibility features
- Add complete i18n support for all new interface elements

Technical components:
- FileManagerGrid: Grid layout with breadcrumb navigation
- FileManagerContextMenu: Right-click context menu system
- useFileSelection: Hook for managing file selection state
- useDragAndDrop: Hook for handling drag-and-drop operations
- View switching logic integrated into main FileManager component

The modern interface is now the default while maintaining backward compatibility.
Users can switch between modern and classic views seamlessly.
2025-09-16 15:36:39 +08:00

82 lines
2.1 KiB
TypeScript

import { useState, useCallback } from 'react';
interface FileItem {
name: string;
type: "file" | "directory" | "link";
path: string;
size?: number;
modified?: string;
permissions?: string;
owner?: string;
group?: string;
}
export function useFileSelection() {
const [selectedFiles, setSelectedFiles] = useState<FileItem[]>([]);
const selectFile = useCallback((file: FileItem, multiSelect = false) => {
if (multiSelect) {
setSelectedFiles(prev => {
const isSelected = prev.some(f => f.path === file.path);
if (isSelected) {
return prev.filter(f => f.path !== file.path);
} else {
return [...prev, file];
}
});
} else {
setSelectedFiles([file]);
}
}, []);
const selectRange = useCallback((files: FileItem[], startFile: FileItem, endFile: FileItem) => {
const startIndex = files.findIndex(f => f.path === startFile.path);
const endIndex = files.findIndex(f => f.path === endFile.path);
if (startIndex !== -1 && endIndex !== -1) {
const start = Math.min(startIndex, endIndex);
const end = Math.max(startIndex, endIndex);
const rangeFiles = files.slice(start, end + 1);
setSelectedFiles(rangeFiles);
}
}, []);
const selectAll = useCallback((files: FileItem[]) => {
setSelectedFiles([...files]);
}, []);
const clearSelection = useCallback(() => {
setSelectedFiles([]);
}, []);
const toggleSelection = useCallback((file: FileItem) => {
setSelectedFiles(prev => {
const isSelected = prev.some(f => f.path === file.path);
if (isSelected) {
return prev.filter(f => f.path !== file.path);
} else {
return [...prev, file];
}
});
}, []);
const isSelected = useCallback((file: FileItem) => {
return selectedFiles.some(f => f.path === file.path);
}, [selectedFiles]);
const getSelectedCount = useCallback(() => {
return selectedFiles.length;
}, [selectedFiles]);
return {
selectedFiles,
selectFile,
selectRange,
selectAll,
clearSelection,
toggleSelection,
isSelected,
getSelectedCount,
setSelectedFiles
};
}