Fix file manager navigation buttons - implement proper directory navigation
🧭 Navigation System Overhaul: - Replace broken browser history navigation with proper file system navigation - Implement intelligent directory history tracking with forward/backward support - Add smart button state management with auto-disable when not applicable 🔧 Button Fixes: - Back button (<): Now navigates to previously visited directories - Forward button (>): Restores navigation after going back - Up button (↑): Properly constructs parent directory paths - Refresh button: Fixed icon from Download to RefreshCw 🎯 Smart Button States: - Back/Forward buttons auto-disable when no history available - Up button disables at root directory (/) - Visual feedback with opacity changes for disabled states - Proper hover effects and accessibility 🧠 Navigation History Logic: - Automatic history tracking when directories change - History index management for proper back/forward behavior - Clean path construction with correct separator handling - Memory-efficient history management The file manager now provides desktop-class navigation experience matching modern file explorers like Windows Explorer or macOS Finder.
This commit is contained in:
@@ -13,7 +13,9 @@ import {
|
|||||||
Download,
|
Download,
|
||||||
ChevronLeft,
|
ChevronLeft,
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
MoreHorizontal
|
MoreHorizontal,
|
||||||
|
RefreshCw,
|
||||||
|
ArrowUp
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
@@ -134,6 +136,49 @@ export function FileManagerGrid({
|
|||||||
const [selectionStart, setSelectionStart] = useState<{ x: number; y: number } | null>(null);
|
const [selectionStart, setSelectionStart] = useState<{ x: number; y: number } | null>(null);
|
||||||
const [selectionRect, setSelectionRect] = useState<{ x: number; y: number; width: number; height: number } | null>(null);
|
const [selectionRect, setSelectionRect] = useState<{ x: number; y: number; width: number; height: number } | null>(null);
|
||||||
|
|
||||||
|
// 导航历史管理
|
||||||
|
const [navigationHistory, setNavigationHistory] = useState<string[]>([currentPath]);
|
||||||
|
const [historyIndex, setHistoryIndex] = useState(0);
|
||||||
|
|
||||||
|
// 更新导航历史
|
||||||
|
useEffect(() => {
|
||||||
|
const lastPath = navigationHistory[historyIndex];
|
||||||
|
if (currentPath !== lastPath) {
|
||||||
|
const newHistory = navigationHistory.slice(0, historyIndex + 1);
|
||||||
|
newHistory.push(currentPath);
|
||||||
|
setNavigationHistory(newHistory);
|
||||||
|
setHistoryIndex(newHistory.length - 1);
|
||||||
|
}
|
||||||
|
}, [currentPath]);
|
||||||
|
|
||||||
|
// 导航函数
|
||||||
|
const goBack = () => {
|
||||||
|
if (historyIndex > 0) {
|
||||||
|
const newIndex = historyIndex - 1;
|
||||||
|
setHistoryIndex(newIndex);
|
||||||
|
onPathChange(navigationHistory[newIndex]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const goForward = () => {
|
||||||
|
if (historyIndex < navigationHistory.length - 1) {
|
||||||
|
const newIndex = historyIndex + 1;
|
||||||
|
setHistoryIndex(newIndex);
|
||||||
|
onPathChange(navigationHistory[newIndex]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const goUp = () => {
|
||||||
|
const parts = currentPath.split('/').filter(Boolean);
|
||||||
|
if (parts.length > 0) {
|
||||||
|
parts.pop();
|
||||||
|
const parentPath = '/' + parts.join('/');
|
||||||
|
onPathChange(parentPath);
|
||||||
|
} else if (currentPath !== '/') {
|
||||||
|
onPathChange('/');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 路径导航
|
// 路径导航
|
||||||
const pathParts = currentPath.split('/').filter(Boolean);
|
const pathParts = currentPath.split('/').filter(Boolean);
|
||||||
const navigateToPath = (index: number) => {
|
const navigateToPath = (index: number) => {
|
||||||
@@ -296,32 +341,44 @@ export function FileManagerGrid({
|
|||||||
{/* 导航按钮 */}
|
{/* 导航按钮 */}
|
||||||
<div className="flex items-center gap-1 p-2 border-b border-dark-border">
|
<div className="flex items-center gap-1 p-2 border-b border-dark-border">
|
||||||
<button
|
<button
|
||||||
onClick={() => window.history.back()}
|
onClick={goBack}
|
||||||
className="p-1 rounded hover:bg-dark-hover"
|
disabled={historyIndex <= 0}
|
||||||
title="后退"
|
className={cn(
|
||||||
|
"p-1 rounded hover:bg-dark-hover",
|
||||||
|
historyIndex <= 0 && "opacity-50 cursor-not-allowed"
|
||||||
|
)}
|
||||||
|
title={t("common.back")}
|
||||||
>
|
>
|
||||||
<ChevronLeft className="w-4 h-4" />
|
<ChevronLeft className="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => window.history.forward()}
|
onClick={goForward}
|
||||||
className="p-1 rounded hover:bg-dark-hover"
|
disabled={historyIndex >= navigationHistory.length - 1}
|
||||||
title="前进"
|
className={cn(
|
||||||
|
"p-1 rounded hover:bg-dark-hover",
|
||||||
|
historyIndex >= navigationHistory.length - 1 && "opacity-50 cursor-not-allowed"
|
||||||
|
)}
|
||||||
|
title={t("common.forward")}
|
||||||
>
|
>
|
||||||
<ChevronRight className="w-4 h-4" />
|
<ChevronRight className="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => onPathChange(files.find(f => f.name === '..')?.path || '/')}
|
onClick={goUp}
|
||||||
className="p-1 rounded hover:bg-dark-hover"
|
disabled={currentPath === '/'}
|
||||||
title="上级目录"
|
className={cn(
|
||||||
|
"p-1 rounded hover:bg-dark-hover",
|
||||||
|
currentPath === '/' && "opacity-50 cursor-not-allowed"
|
||||||
|
)}
|
||||||
|
title={t("fileManager.parentDirectory")}
|
||||||
>
|
>
|
||||||
↑
|
<ArrowUp className="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={onRefresh}
|
onClick={onRefresh}
|
||||||
className="p-1 rounded hover:bg-dark-hover"
|
className="p-1 rounded hover:bg-dark-hover"
|
||||||
title="刷新"
|
title={t("common.refresh")}
|
||||||
>
|
>
|
||||||
<Download className="w-4 h-4" />
|
<RefreshCw className="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user