From dfe837dfd0e070c27671b7dc191bf8b7e3299943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Sun, 30 Aug 2026 11:05:36 +0100 Subject: [PATCH] a window re-reads its folder when it comes forward MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cutting in one window and pasting in another moves the file on disk, and the window it left went on listing it until somebody pressed refresh. The clipboard was the obvious half of "these two windows disagree"; the listing is the half that matters more, because a file that is not there any more is a lie rather than a stale label. Same trigger as the clipboard, for the same reason: coming back to a window is exactly when its contents need to be true, and never while nobody is looking at it. `refresh` is held in a ref because it is rebuilt on every render — in the dependency array it would tear down and re-add both listeners several times a second. Co-Authored-By: Claude Opus 5 (1M context) --- .../FileBrowserApp/useFileBrowserApp.ts | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/useFileBrowserApp.ts b/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/useFileBrowserApp.ts index 71b5f192..2b0360ab 100644 --- a/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/useFileBrowserApp.ts +++ b/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/useFileBrowserApp.ts @@ -342,15 +342,31 @@ export const useFileBrowserApp = ( `visibilitychange` as well as `focus`, because a background tab brought forward by switching tabs fires only the second one in some browsers. */ + /* + ...and the FOLDER as well as the clipboard. + + Cutting in one window and pasting in another moves the file on disk, and the window it left went on + listing it until somebody pressed refresh. The clipboard was the obvious half of "these two windows + disagree"; the listing is the half that matters more, because a file that is not there any more is + a lie rather than a stale label. + + Held in a ref because `refreshRef.current` is rebuilt on every render — putting it in the + dependency array would tear down and re-add both listeners several times a second. + */ + const refreshRef = useRef(refresh); + refreshRef.current = refresh; + useEffect(() => { - const refresh = () => { - if (document.visibilityState === 'visible') void queryClient.invalidateQueries({ queryKey: ['USER_STATE'] }); + const onForeground = () => { + if (document.visibilityState !== 'visible') return; + void queryClient.invalidateQueries({ queryKey: ['USER_STATE'] }); + void refreshRef.current(); }; - window.addEventListener('focus', refresh); - document.addEventListener('visibilitychange', refresh); + window.addEventListener('focus', onForeground); + document.addEventListener('visibilitychange', onForeground); return () => { - window.removeEventListener('focus', refresh); - document.removeEventListener('visibilitychange', refresh); + window.removeEventListener('focus', onForeground); + document.removeEventListener('visibilitychange', onForeground); }; }, [queryClient]);