feat(FileBrowser): refactor entry icon rendering for better clarity and organization
feat(FileManager): persist filter, sort key, and sort order in local storage
This commit is contained in:
parent
0b547bf02b
commit
768c4c2336
|
|
@ -2,6 +2,9 @@ import { useEffect, useRef, useState } from 'react';
|
|||
import {
|
||||
Folder,
|
||||
File,
|
||||
FileText,
|
||||
HardDrive,
|
||||
Image as ImageIcon,
|
||||
ChevronRight,
|
||||
Home,
|
||||
RefreshCw,
|
||||
|
|
@ -34,6 +37,19 @@ import {
|
|||
DialogDescription,
|
||||
} from './ui/dialog';
|
||||
|
||||
const TEXT_EXTS = new Set(['txt','cfg','ini','bas','asm','seq','rel','prg','log','csv','s','lst','md','markdown','json','xml','svg','html','htm']);
|
||||
const IMAGE_EXTS = new Set(['png','jpg','jpeg','gif','bmp','webp']);
|
||||
const DISK_EXTS = new Set(['d64','d71','d81','d82','g64','g71','t64','tap','crt','nib']);
|
||||
|
||||
function EntryIcon({ entry }: { entry: EntryInfo }) {
|
||||
if (entry.type === 'folder') return <Folder className="w-5 h-5 text-blue-500 flex-shrink-0" />;
|
||||
const ext = entry.name.split('.').pop()?.toLowerCase() ?? '';
|
||||
if (IMAGE_EXTS.has(ext)) return <ImageIcon className="w-5 h-5 text-purple-500 flex-shrink-0" />;
|
||||
if (DISK_EXTS.has(ext)) return <HardDrive className="w-5 h-5 text-amber-500 flex-shrink-0" />;
|
||||
if (TEXT_EXTS.has(ext)) return <FileText className="w-5 h-5 text-green-600 flex-shrink-0" />;
|
||||
return <File className="w-5 h-5 text-neutral-400 flex-shrink-0" />;
|
||||
}
|
||||
|
||||
interface FileBrowserProps {
|
||||
currentPath: string;
|
||||
onSelect: (path: string) => void;
|
||||
|
|
@ -335,13 +351,7 @@ export default function FileBrowser({ currentPath, onSelect, onClose }: FileBrow
|
|||
}}
|
||||
className="flex-1 flex items-center gap-3 text-left min-w-0"
|
||||
>
|
||||
<div className={entry.type === 'folder' ? 'text-blue-600' : 'text-neutral-400'}>
|
||||
{entry.type === 'folder' ? (
|
||||
<Folder className="w-5 h-5" />
|
||||
) : (
|
||||
<File className="w-5 h-5" />
|
||||
)}
|
||||
</div>
|
||||
<EntryIcon entry={entry} />
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="text-neutral-900 truncate">{entry.name}</div>
|
||||
{entry.type === 'file' && (
|
||||
|
|
|
|||
|
|
@ -309,9 +309,9 @@ export default function FileManager({ initialPath = '/', config, setConfig, onBa
|
|||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [selected, setSelected] = useState<Set<string>>(new Set());
|
||||
const [filter, setFilter] = useState('');
|
||||
const [sortKey, setSortKey] = useState<SortKey>('name');
|
||||
const [sortAsc, setSortAsc] = useState(true);
|
||||
const [filter, setFilter] = useState(() => localStorage.getItem('fileManager.filter') ?? '');
|
||||
const [sortKey, setSortKey] = useState<SortKey>(() => (localStorage.getItem('fileManager.sortKey') as SortKey) ?? 'name');
|
||||
const [sortAsc, setSortAsc] = useState(() => localStorage.getItem('fileManager.sortAsc') !== 'false');
|
||||
const [clipboard, setClipboard] = useState<Clipboard | null>(null);
|
||||
const [actionEntry, setActionEntry] = useState<EntryInfo | null>(null);
|
||||
const [dragOver, setDragOver] = useState(false);
|
||||
|
|
@ -352,6 +352,9 @@ export default function FileManager({ initialPath = '/', config, setConfig, onBa
|
|||
}, []);
|
||||
|
||||
useEffect(() => { void load(path); }, [path, load]);
|
||||
useEffect(() => { localStorage.setItem('fileManager.filter', filter); }, [filter]);
|
||||
useEffect(() => { localStorage.setItem('fileManager.sortKey', sortKey); }, [sortKey]);
|
||||
useEffect(() => { localStorage.setItem('fileManager.sortAsc', String(sortAsc)); }, [sortAsc]);
|
||||
|
||||
const navigateTo = (p: string) => {
|
||||
const norm = normalizePath(p);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user