re-reading a folder does not blank it
`loading` swaps the whole grid for a spinner. That is right when arriving somewhere new and wrong when re-reading a folder already on screen — and every refresh went through the same path: after a paste, after a delete, and now every time a window comes forward. On a folder of a hundred files that is a flash and a lost scroll position, to replace information that was already correct. The spinner is now for a folder that cannot yet be shown: nothing listed, or a different folder than the one listed. Re-reading the same folder leaves what is there until better information arrives, so the only visible change is whatever actually changed. `shownPath` is what separates the two cases. From inside `refresh` they are identical — it is called the same way by a navigation and by a refresh — and they need opposite treatment. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -247,6 +247,10 @@ export const useFileBrowserApp = (
|
||||
filesRef.current = files;
|
||||
const currentPathRef = useRef(currentPath);
|
||||
currentPathRef.current = currentPath;
|
||||
// Read inside `refresh`, which is not re-created per render and would otherwise close over a
|
||||
// stale list the first time it ran.
|
||||
const entriesRef = useRef(entries);
|
||||
entriesRef.current = entries;
|
||||
const visibleEntries = showHidden ? entries : entries.filter((e) => !e.name.startsWith('.'));
|
||||
|
||||
const entryPath = (name: string) => (currentPath === '/' ? `/${name}` : `${currentPath}/${name}`);
|
||||
@@ -254,8 +258,29 @@ export const useFileBrowserApp = (
|
||||
|
||||
const firstListing = useRef(true);
|
||||
|
||||
/**
|
||||
* The folder the entries currently on screen belong to.
|
||||
*
|
||||
* What separates "re-read this folder" from "go to a different one", which look identical from
|
||||
* inside `refresh` and need opposite treatment — see below.
|
||||
*/
|
||||
const shownPath = useRef<string | null>(null);
|
||||
|
||||
const refresh = async () => {
|
||||
setLoading(true);
|
||||
/*
|
||||
Blank the list only when there is nothing true to show.
|
||||
|
||||
`loading` swaps the whole grid for a spinner, which is right when arriving somewhere new and
|
||||
wrong when re-reading a folder already on screen: every refresh — after a paste, after a delete,
|
||||
and now every time the window comes forward — made the contents vanish and come back. On a
|
||||
folder of a hundred files that is a flash and a lost scroll position, for information that was
|
||||
already correct.
|
||||
|
||||
So the spinner is for a folder we cannot yet show: nothing listed, or a different folder than the
|
||||
one listed. Re-reading the same folder leaves what is there until better information arrives, and
|
||||
the only visible change is whatever actually changed.
|
||||
*/
|
||||
if (entriesRef.current.length === 0 || shownPath.current !== currentPathRef.current) setLoading(true);
|
||||
try {
|
||||
const data = await filesRef.current.listDir(currentPathRef.current);
|
||||
if (data.reset) {
|
||||
@@ -263,6 +288,7 @@ export const useFileBrowserApp = (
|
||||
return;
|
||||
}
|
||||
setEntries(data.entries);
|
||||
shownPath.current = currentPathRef.current;
|
||||
if (data.rootDir) setRootDir(data.rootDir);
|
||||
} catch (err: any) {
|
||||
console.error('[FileBrowser] refresh error:', err);
|
||||
|
||||
Reference in New Issue
Block a user