Skip to content
Merged
21 changes: 19 additions & 2 deletions apps/web/src/components/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ import {
useThreadRefs,
useThreadVisibleTurnItems,
useThreadCheckpointSummaries,
readThreadShell,
waitForThreadShell,
} from "../state/entities";
import { environmentShell } from "../state/shell";
Expand Down Expand Up @@ -563,6 +564,9 @@ const EMPTY_FEEDBACK_SUBMISSIONS: ReadonlyArray<CodexFeedbackSubmission> = [];
// second, and every server-side visit is a full command dispatch plus a
// broadcast to all shell subscribers.
const VISIT_DISPATCH_THROTTLE_MS = 10_000;
// Long enough for a just-launched child's shell to sync. A thread with no shell waits
// this long before the deleted toast.
const RELATED_THREAD_SHELL_WAIT_MS = 1_000;
const EMPTY_PROVIDER_SKILLS: ServerProvider["skills"] = [];
function useDraftHeroLayoutTransition(
isDraftHeroState: boolean,
Expand Down Expand Up @@ -5104,10 +5108,23 @@ export default function ChatView(props: ChatViewProps) {
}
};
const handleStopBackgroundWorkStable = useStableCallback(handleStopBackgroundWork);
const onOpenRelatedThread = (threadId: ThreadId) => {
const onOpenRelatedThread = async (threadId: ThreadId) => {
const threadRef = scopeThreadRef(environmentId, threadId);
const environmentLive =
appAtomRegistry.get(environmentShell.stateValueAtom(environmentId)).status === "live";
// A just-launched child can reach this timeline before its shell syncs.
if (environmentLive && readThreadShell(threadRef) === null) {
await waitForThreadShell(threadRef, RELATED_THREAD_SHELL_WAIT_MS);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
const shell = readThreadShell(threadRef);
// The thread route sends a missing thread to the start page, so stay here instead.
if (shell === null ? environmentLive : shell.deletedAt != null) {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
toastManager.add({ type: "info", title: "This thread was deleted" });
return;
}
void navigate({
to: "/$environmentId/$threadId",
params: buildThreadRouteParams(scopeThreadRef(environmentId, threadId)),
params: buildThreadRouteParams(threadRef),
});
};
const onOpenRelatedThreadStable = useStableCallback(onOpenRelatedThread);
Expand Down
Loading