Fix appearance persistence and add drag over folder highlighting
All checks were successful
Automated Container Build / build-and-push (push) Successful in 32s

This commit is contained in:
Elijah 2026-05-22 18:07:20 -07:00
parent d532f8d064
commit 425598c278

View file

@ -89,9 +89,28 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
const [movingFiles, setMovingFiles] = useState<string[]>([]);
const [moveModalPath, setMoveModalPath] = useState('.');
const [moveFolders, setMoveFolders] = useState<FileItem[]>([]);
const [dragOverFolder, setDragOverFolder] = useState<string | null>(null);
const searchTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
const fileInputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
api.getSettings().then((data) => {
const theme = data?.settings?.theme || data?.theme;
if (theme) {
if (theme === 'light') {
document.documentElement.setAttribute('data-theme', 'light');
document.documentElement.classList.remove('dark');
document.documentElement.style.setProperty('color-scheme', 'light');
} else {
document.documentElement.setAttribute('data-theme', 'dark');
document.documentElement.classList.add('dark');
document.documentElement.style.setProperty('color-scheme', 'dark');
}
localStorage.setItem('theme', theme);
}
}).catch(console.error);
}, []);
// Load files on path change
const loadFiles = useCallback(async (path?: string) => {
const targetPath = path ?? currentPath;
@ -339,10 +358,20 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
if (!file.is_dir) return;
if (draggedFile === file.path) return;
e.preventDefault();
if (dragOverFolder !== file.path) {
setDragOverFolder(file.path);
}
}
function handleItemDragLeave(e: React.DragEvent, file: FileItem) {
if (dragOverFolder === file.path) {
setDragOverFolder(null);
}
}
async function handleItemDrop(e: React.DragEvent, file: FileItem) {
if (!file.is_dir) return;
setDragOverFolder(null);
const sourcePath = e.dataTransfer.getData('text/plain');
if (!sourcePath || sourcePath === file.path) return;
@ -829,6 +858,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
draggable
onDragStart={(e: any) => handleItemDragStart(e, file.path)}
onDragOver={(e: any) => handleItemDragOver(e, file)}
onDragLeave={(e: any) => handleItemDragLeave(e, file)}
onDrop={(e: any) => handleItemDrop(e, file)}
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
@ -837,8 +867,8 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
onContextMenu={(e) => handleContextMenu(e, file)}
className={`group relative p-4 rounded-xl cursor-pointer transition-all duration-150 border-2 ${draggedFile === file.path ? 'opacity-50' : ''}`}
style={{
backgroundColor: selectedFiles.has(file.path) ? 'var(--color-accent-subtle)' : 'var(--color-bg-elevated)',
border: `1px solid ${selectedFiles.has(file.path) ? 'var(--color-accent)' : 'var(--color-border-subtle)'}`,
backgroundColor: selectedFiles.has(file.path) || dragOverFolder === file.path ? 'var(--color-accent-subtle)' : 'var(--color-bg-elevated)',
border: `1px solid ${selectedFiles.has(file.path) || dragOverFolder === file.path ? 'var(--color-accent)' : 'var(--color-border-subtle)'}`,
}}
>
<div
@ -907,6 +937,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
draggable
onDragStart={(e: any) => handleItemDragStart(e, file.path)}
onDragOver={(e: any) => handleItemDragOver(e, file)}
onDragLeave={(e: any) => handleItemDragLeave(e, file)}
onDrop={(e: any) => handleItemDrop(e, file)}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
@ -915,8 +946,8 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
onContextMenu={(e) => handleContextMenu(e, file)}
className={`group relative p-4 rounded-xl cursor-pointer transition-all duration-150 ${draggedFile === file.path ? 'opacity-50' : ''}`}
style={{
backgroundColor: selectedFiles.has(file.path) ? 'var(--color-accent-subtle)' : 'var(--color-bg-elevated)',
border: `1px solid ${selectedFiles.has(file.path) ? 'var(--color-accent)' : 'var(--color-border-subtle)'}`,
backgroundColor: selectedFiles.has(file.path) || dragOverFolder === file.path ? 'var(--color-accent-subtle)' : 'var(--color-bg-elevated)',
border: `1px solid ${selectedFiles.has(file.path) || dragOverFolder === file.path ? 'var(--color-accent)' : 'var(--color-border-subtle)'}`,
}}
>
<div
@ -986,6 +1017,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
draggable
onDragStart={(e: any) => handleItemDragStart(e, file.path)}
onDragOver={(e: any) => handleItemDragOver(e, file)}
onDragLeave={(e: any) => handleItemDragLeave(e, file)}
onDrop={(e: any) => handleItemDrop(e, file)}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
@ -993,7 +1025,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
onClick={(e) => handleFileClick(file, e)}
onContextMenu={(e) => handleContextMenu(e, file)}
className={`grid grid-cols-[1fr_100px_140px_40px] gap-4 items-center px-4 py-2.5 rounded-lg cursor-pointer transition-all duration-100 group ${draggedFile === file.path ? 'opacity-50' : ''}`}
style={{ backgroundColor: selectedFiles.has(file.path) ? 'var(--color-accent-subtle)' : 'transparent' }}
style={{ backgroundColor: selectedFiles.has(file.path) || dragOverFolder === file.path ? 'var(--color-accent-subtle)' : 'transparent' }}
>
<div className="flex items-center gap-3 min-w-0">
<input
@ -1052,6 +1084,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
draggable
onDragStart={(e: any) => handleItemDragStart(e, file.path)}
onDragOver={(e: any) => handleItemDragOver(e, file)}
onDragLeave={(e: any) => handleItemDragLeave(e, file)}
onDrop={(e: any) => handleItemDrop(e, file)}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
@ -1059,7 +1092,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
onClick={(e) => handleFileClick(file, e)}
onContextMenu={(e) => handleContextMenu(e, file)}
className={`grid grid-cols-[1fr_100px_140px_40px] gap-4 items-center px-4 py-2.5 rounded-lg cursor-pointer transition-all duration-100 group ${draggedFile === file.path ? 'opacity-50' : ''}`}
style={{ backgroundColor: selectedFiles.has(file.path) ? 'var(--color-accent-subtle)' : 'transparent' }}
style={{ backgroundColor: selectedFiles.has(file.path) || dragOverFolder === file.path ? 'var(--color-accent-subtle)' : 'transparent' }}
>
<div className="flex items-center gap-3 min-w-0">
<input