feat(MediaManager): add breadcrumb scrolling functionality for improved navigation

This commit is contained in:
Jaime Idolpx 2026-06-12 20:57:28 -04:00
parent dfe87c05a1
commit 085df24ba7
2 changed files with 16 additions and 9 deletions

View File

@ -455,9 +455,10 @@ export default function MediaManager({ initialPath, rootPath, title, config, set
const [renameName, setRenameName] = useState(''); const [renameName, setRenameName] = useState('');
const [mountEntry, setMountEntry] = useState<EntryInfo | null>(null); const [mountEntry, setMountEntry] = useState<EntryInfo | null>(null);
const fileInputRef = useRef<HTMLInputElement>(null); const fileInputRef = useRef<HTMLInputElement>(null);
const renameInputRef = useRef<HTMLInputElement>(null); const renameInputRef = useRef<HTMLInputElement>(null);
const dragCounter = useRef(0); const breadcrumbRef = useRef<HTMLDivElement>(null);
const dragCounter = useRef(0);
const [confirm, setConfirm] = useState<ConfirmOptions | null>(null); const [confirm, setConfirm] = useState<ConfirmOptions | null>(null);
// ── Directory loading ──────────────────────────────────────────────────── // ── Directory loading ────────────────────────────────────────────────────
@ -477,6 +478,10 @@ export default function MediaManager({ initialPath, rootPath, title, config, set
}, []); }, []);
useEffect(() => { void load(path); }, [path, load]); useEffect(() => { void load(path); }, [path, load]);
useEffect(() => {
const el = breadcrumbRef.current;
if (el) el.scrollLeft = el.scrollWidth;
}, [path]);
useEffect(() => { localStorage.setItem('fileManager.filter', filter); }, [filter]); useEffect(() => { localStorage.setItem('fileManager.filter', filter); }, [filter]);
useEffect(() => { localStorage.setItem('fileManager.sortKey', sortKey); }, [sortKey]); useEffect(() => { localStorage.setItem('fileManager.sortKey', sortKey); }, [sortKey]);
useEffect(() => { localStorage.setItem('fileManager.sortAsc', String(sortAsc)); }, [sortAsc]); useEffect(() => { localStorage.setItem('fileManager.sortAsc', String(sortAsc)); }, [sortAsc]);
@ -1003,7 +1008,7 @@ export default function MediaManager({ initialPath, rootPath, title, config, set
{/* Breadcrumb */} {/* Breadcrumb */}
<div className="flex items-center gap-1 text-sm text-neutral-600"> <div className="flex items-center gap-1 text-sm text-neutral-600">
<div className="flex items-center gap-1 overflow-x-auto flex-1 min-w-0"> <div ref={breadcrumbRef} className="flex items-center gap-1 overflow-x-auto flex-1 min-w-0 [&::-webkit-scrollbar]:hidden" style={{ scrollbarWidth: 'none' }}>
<button onClick={() => navigateTo(rootPath ?? '/')} className="p-1 rounded hover:bg-neutral-100 flex-shrink-0" title="Root"> <button onClick={() => navigateTo(rootPath ?? '/')} className="p-1 rounded hover:bg-neutral-100 flex-shrink-0" title="Root">
<Home className="w-4 h-4" /> <Home className="w-4 h-4" />
</button> </button>

View File

@ -172,16 +172,18 @@ export default function StatusPage({ config, setConfig, onOpenFileManager }: Sta
<button <button
type="button" type="button"
onClick={() => setShowDeviceOverlay(true)} onClick={() => setShowDeviceOverlay(true)}
className="flex items-center gap-3 text-left rounded-lg p-1 -m-1 hover:bg-neutral-50 transition cursor-pointer" className="flex items-center gap-3 text-left rounded-lg p-1 -m-1 hover:bg-neutral-50 transition cursor-pointer min-w-0"
aria-label={`Open details for Device #${activeDevice.number}`} aria-label={`Open details for Device #${activeDevice.number}`}
> >
<div className="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center"> <div className="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center flex-shrink-0">
<HardDrive className="w-5 h-5 text-blue-600" /> <HardDrive className="w-5 h-5 text-blue-600" />
</div> </div>
<div> <div className="min-w-0">
<div className="font-medium">Device #{activeDevice.number}</div> <div className="font-medium">Device #{activeDevice.number}</div>
<div className="text-sm text-neutral-500"> <div className="text-sm text-neutral-500 overflow-hidden whitespace-nowrap" style={{ direction: 'rtl', textOverflow: 'ellipsis' }}>
{[activeDevice.base_url, activeDevice.url].filter(Boolean).join('') || '—'} <span style={{ direction: 'ltr', unicodeBidi: 'embed' }}>
{[activeDevice.base_url, activeDevice.url].filter(Boolean).join('') || '—'}
</span>
</div> </div>
</div> </div>
</button> </button>