History

fix(web): scope root reveal selection sync

t3-code[bot] committed 3 months ago

Commit f05a6671 parent a6cd7081 file · +27 −12Browse files

Unified · Split

apps/web/src/components/files/FileBrowserPanel.tsx+27−12
@@ -144,15 +144,27 @@ export default function FileBrowserPanel({ · 143 unmodified lines
144 const treeSelectionPathRef = useRef<string | null>(null);144 const treeSelectionPathRef = useRef<string | null>(null);
145 const handledRevealRef = useRef<{ path: string; revealId: number } | null>(null);145 const handledRevealRef = useRef<{ path: string; revealId: number } | null>(null);
146 const handledBreadcrumbRevealRef = useRef<{ path: string; revealId: number } | null>(null);146 const handledBreadcrumbRevealRef = useRef<{ path: string; revealId: number } | null>(null);
147 const suppressSelectedPathScrollRef = useRef(breadcrumbRevealPath === "");147 const suppressedSelectedPathRef = useRef<{ path: string; revealId: number } | null>(null);
148 if (148 const capturedRootRevealIdRef = useRef<number | null>(null);
149 breadcrumbRevealPath === "" &&149
150 selectedPath &&150 useEffect(() => {
151 (handledRevealRef.current?.path !== selectedPath ||151 if (breadcrumbRevealPath !== "") {
152 handledRevealRef.current.revealId !== selectedPathRevealId)152 if (breadcrumbRevealPath !== null) suppressedSelectedPathRef.current = null;
153 ) {153 return;
154 suppressSelectedPathScrollRef.current = true;154 }
155 }155 if (capturedRootRevealIdRef.current === breadcrumbRevealId) return;
156 capturedRootRevealIdRef.current = breadcrumbRevealId;
157 const handledReveal = handledRevealRef.current;
158 if (
159 selectedPath &&
160 (handledReveal?.path !== selectedPath || handledReveal.revealId !== selectedPathRevealId)
161 ) {
162 suppressedSelectedPathRef.current = {
163 path: selectedPath,
164 revealId: breadcrumbRevealId,
165 };
166 }
167 }, [breadcrumbRevealId, breadcrumbRevealPath, selectedPath, selectedPathRevealId]);
156 168
157 // The tree renders rows in shadow DOM and its anchor rect is unreliable, so169 // The tree renders rows in shadow DOM and its anchor rect is unreliable, so
158 // capture the right-click position ourselves; contextmenu is a composed170 // capture the right-click position ourselves; contextmenu is a composed
@@ -298,7 +310,7 @@ export default function FileBrowserPanel({ · 139 unmodified lines
298 useEffect(() => {310 useEffect(() => {
299 if (!selectedPath) {311 if (!selectedPath) {
300 handledRevealRef.current = null;312 handledRevealRef.current = null;
301 suppressSelectedPathScrollRef.current = false;313 suppressedSelectedPathRef.current = null;
302 return;314 return;
303 }315 }
304 const revealRequest = { path: selectedPath, revealId: selectedPathRevealId };316 const revealRequest = { path: selectedPath, revealId: selectedPathRevealId };
@@ -328,10 +340,10 @@ export default function FileBrowserPanel({ · 23 unmodified lines
328 return;340 return;
329 }341 }
330 342
331 if (suppressSelectedPathScrollRef.current) {343 if (suppressedSelectedPathRef.current?.path === selectedPath) {
332 treeSelectionPathRef.current = null;344 treeSelectionPathRef.current = null;
333 handledRevealRef.current = revealRequest;345 handledRevealRef.current = revealRequest;
334 suppressSelectedPathScrollRef.current = false;346 suppressedSelectedPathRef.current = null;
335 syncingSelectionRef.current = true;347 syncingSelectionRef.current = true;
336 const segments = selectedPath.split("/");348 const segments = selectedPath.split("/");
337 let ancestorPath = "";349 let ancestorPath = "";
@@ -340,6 +352,9 @@ export default function FileBrowserPanel({ · 2 unmodified lines
340 const item = model.getItem(`${ancestorPath}/`) ?? model.getItem(ancestorPath);352 const item = model.getItem(`${ancestorPath}/`) ?? model.getItem(ancestorPath);
341 if (item && "expand" in item) item.expand();353 if (item && "expand" in item) item.expand();
342 }354 }
355 for (const path of model.getSelectedPaths()) {
356 model.getItem(path)?.deselect();
357 }
343 selectedItem.select();358 selectedItem.select();
344 queueMicrotask(() => {359 queueMicrotask(() => {
345 syncingSelectionRef.current = false;360 syncingSelectionRef.current = false;