Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions web/src/components/WorkspaceBrowser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,14 @@ export function WorkspaceBrowser(props: {
void loadDirectory(selectedRoot)
}, [machineId, selectedRoot, currentPath, loadDirectory])

// If switching machines, reset view
// 切换机器时重置浏览状态,并立即对齐到新机器的第一个 workspace root。
// 否则 selectedRoot 可能被清空后跳过自动加载,页面会停在空态。
useEffect(() => {
setSelectedRoot(null)
setSelectedRoot(workspaceRoots[0] ?? null)
setCurrentPath(null)
setEntries([])
setError(null)
}, [machineId])
}, [machineId, workspaceRoots])
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] workspaceRoots 在没有 roots 时来自 selectedMachine?.metadata?.workspaceRoots ?? [],每次 render 都会得到新的空数组引用。这个 effect 现在依赖它,并且无条件 setEntries([]) 写入新的数组状态,所以未配置 workspace roots 或 roots 尚未加载时会进入 render 循环,/browse 的空态也可能卡死。

Suggested fix:

const workspaceRoots = useMemo(
    () => selectedMachine?.metadata?.workspaceRoots ?? [],
    [selectedMachine?.metadata?.workspaceRoots]
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MAJOR] workspaceRoots should not be part of this reset trigger. useSSE replaces machine objects on normal sync updates, so this effect can clear currentPath, entries, and error while the user is still browsing the same machine. The root-selection effect above already reacts to root changes, so keep this reset tied to machineId only.\n\nSuggested fix:\ntsx\nuseEffect(() => {\n setSelectedRoot(workspaceRoots[0] ?? null)\n setCurrentPath(null)\n setEntries([])\n setError(null)\n}, [machineId])\n


const handleEntryClick = useCallback((entry: MachineDirectoryEntry) => {
if (entry.type !== 'directory' || !currentPath) return
Expand Down
Loading