1import { useAtomValue } from "@effect/atom-react";
2import type { ScopedThreadRef } from "@t3tools/contracts";
3import type { DraftId } from "~/composerDraftStore";
4import { useParams } from "@tanstack/react-router";
5import * as Atom from "effect/reactivity/Atom";
6import * as AsyncResult from "effect/reactivity/AsyncResult";
7
8import { useProject, useThreadShell } from "~/state/entities";
9import { jjEnvironment } from "~/state/jj";
10import { resolveThreadRouteRef } from "~/threadRoutes";
11
12import DiffPanel from "../DiffPanel";
13import { DiffPanelLoadingState, DiffPanelShell, type DiffPanelMode } from "../DiffPanelShell";
14import { JjReviewPanel } from "./JjReviewPanel";
15
16const NO_STACK = Atom.make(AsyncResult.success(null));
17
18/** The right panel's diff surface: the jj review panel inside a jj workspace, T3's diff panel otherwise. */
19export default function DiffSurface(props: {
20 mode?: DiffPanelMode;
21 composerDraftTarget: ScopedThreadRef | DraftId;
22 workspaceMutationId: string | null;
23}) {
24 const mode = props.mode ?? "inline";
25 const threadRef = useParams({ strict: false, select: (params) => resolveThreadRouteRef(params) });
26 const thread = useThreadShell(threadRef);
27 const project = useProject(
28 thread?.projectId ? { environmentId: thread.environmentId, projectId: thread.projectId } : null,
29 );
30 const cwd = thread?.worktreePath ?? project?.workspaceRoot;
31 const stack = useAtomValue(
32 thread && cwd
33 ? jjEnvironment.stack({ environmentId: thread.environmentId, input: { cwd } })
34 : NO_STACK,
35 );
36
37 if (stack._tag === "Initial") {
38 return (
39 <DiffPanelShell mode={mode} header={null}>
40 <DiffPanelLoadingState label="Loading changes…" />
41 </DiffPanelShell>
42 );
43 }
44 if (stack._tag === "Success" && stack.value && thread && cwd) {
45 return (
46 <JjReviewPanel
47 mode={mode}
48 environmentId={thread.environmentId}
49 threadRef={threadRef}
50 cwd={cwd}
51 stack={stack.value}
52 composerDraftTarget={props.composerDraftTarget}
53 />
54 );
55 }
56 return <DiffPanel {...props} />;
57}