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