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;
|
filesRef.current = files;
|
||||||
const currentPathRef = useRef(currentPath);
|
const currentPathRef = useRef(currentPath);
|
||||||
currentPathRef.current = 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 visibleEntries = showHidden ? entries : entries.filter((e) => !e.name.startsWith('.'));
|
||||||
|
|
||||||
const entryPath = (name: string) => (currentPath === '/' ? `/${name}` : `${currentPath}/${name}`);
|
const entryPath = (name: string) => (currentPath === '/' ? `/${name}` : `${currentPath}/${name}`);
|
||||||
@@ -254,8 +258,29 @@ export const useFileBrowserApp = (
|
|||||||
|
|
||||||
const firstListing = useRef(true);
|
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 () => {
|
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 {
|
try {
|
||||||
const data = await filesRef.current.listDir(currentPathRef.current);
|
const data = await filesRef.current.listDir(currentPathRef.current);
|
||||||
if (data.reset) {
|
if (data.reset) {
|
||||||
@@ -263,6 +288,7 @@ export const useFileBrowserApp = (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setEntries(data.entries);
|
setEntries(data.entries);
|
||||||
|
shownPath.current = currentPathRef.current;
|
||||||
if (data.rootDir) setRootDir(data.rootDir);
|
if (data.rootDir) setRootDir(data.rootDir);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.error('[FileBrowser] refresh error:', err);
|
console.error('[FileBrowser] refresh error:', err);
|
||||||
|
|||||||
Reference in New Issue
Block a user