fix(workspace): avoid UI stalls when switching (#489)

This commit is contained in:
ben
2026-02-06 23:40:40 -08:00
committed by GitHub
parent c45a6e2961
commit b2a006f338
2 changed files with 22 additions and 10 deletions

View File

@@ -65,6 +65,7 @@ import type {
ResetOpenworkMode,
SettingsTab,
SkillCard,
SidebarSessionItem,
TodoItem,
View,
WorkspaceSessionGroup,
@@ -1426,7 +1427,7 @@ export default function App() {
type SidebarWorkspaceSessionsStatus = WorkspaceSessionGroup["status"];
const [sidebarSessionsByWorkspaceId, setSidebarSessionsByWorkspaceId] = createSignal<
Record<string, Session[]>
Record<string, SidebarSessionItem[]>
>({});
const [sidebarSessionStatusByWorkspaceId, setSidebarSessionStatusByWorkspaceId] = createSignal<
Record<string, SidebarWorkspaceSessionsStatus>
@@ -1438,7 +1439,7 @@ export default function App() {
const pruneSidebarSessionState = (workspaceIds: Set<string>) => {
setSidebarSessionsByWorkspaceId((prev) => {
let changed = false;
const next: Record<string, Session[]> = {};
const next: Record<string, SidebarSessionItem[]> = {};
for (const [id, list] of Object.entries(prev)) {
if (!workspaceIds.has(id)) {
changed = true;
@@ -1560,9 +1561,18 @@ export default function App() {
? list.filter((session) => normalizeDirectoryPath(session.directory) === root)
: list;
const sorted = sortSessionsByActivity(filtered);
const items: SidebarSessionItem[] = sorted.map((session) => ({
id: session.id,
title: session.title,
slug: session.slug,
time: session.time,
directory: session.directory,
}));
setSidebarSessionsByWorkspaceId((prev) => ({
...prev,
[id]: sortSessionsByActivity(filtered),
[id]: items,
}));
setSidebarSessionStatusByWorkspaceId((prev) => ({ ...prev, [id]: "ready" }));
} catch (error) {
@@ -1582,6 +1592,8 @@ export default function App() {
: list;
for (const ws of ordered) {
await refreshSidebarWorkspaceSessions(ws.id);
// Yield so long refresh passes don't block UI / timers.
await new Promise<void>((resolve) => setTimeout(resolve, 0));
}
};
@@ -1628,13 +1640,7 @@ export default function App() {
const groupSessions = sessionsById[workspace.id] ?? [];
return {
workspace,
sessions: groupSessions.map((session) => ({
id: session.id,
title: session.title,
slug: session.slug,
time: session.time,
directory: session.directory,
})),
sessions: groupSessions,
status: statusById[workspace.id] ?? "idle",
error: errorById[workspace.id] ?? null,
};

View File

@@ -515,6 +515,12 @@ export function createWorkspaceStore(options: {
setConnectingWorkspaceId(id);
updateWorkspaceConnectionState(id, { status: "connecting", message: null });
// Allow the UI to paint the "switching" state before we kick off work that can
// trigger expensive reactive updates (e.g. sidebar session refreshes).
if (typeof window !== "undefined" && typeof window.requestAnimationFrame === "function") {
await new Promise<void>((resolve) => window.requestAnimationFrame(() => resolve()));
}
try {
if (isRemote) {
options.setStartupPreference("server");