@@ -3,8 +3,10 @@ import { useCallback, useEffect, useMemo, useRef } from "react";
33import type { EnvironmentId , OrchestrationCheckpointSummary , ThreadId } from "@t3tools/contracts" ;
44
55import { getEnvironmentClient } from "../../state/environment-session-registry" ;
6+ import { checkpointDiffManager , loadCheckpointDiff } from "../../state/use-checkpoint-diff" ;
67import { useSelectedThreadWorktree } from "../../state/use-selected-thread-worktree" ;
78import { useSelectedThreadDetail } from "../../state/use-thread-detail" ;
9+ import { useReviewDiffPreview } from "./reviewDiffPreviewState" ;
810import {
911 buildReviewSectionItems ,
1012 getDefaultReviewSectionId ,
@@ -13,7 +15,6 @@ import {
1315} from "./reviewModel" ;
1416import {
1517 setReviewAsyncError ,
16- setReviewGitDiffsLoading ,
1718 setReviewGitSections ,
1819 setReviewSelectedSectionId ,
1920 setReviewTurnDiffLoading ,
@@ -29,13 +30,23 @@ export function useReviewSections(input: {
2930 const { environmentId, reviewCache, threadId } = input ;
3031 const selectedThread = useSelectedThreadDetail ( ) ;
3132 const { selectedThreadCwd } = useSelectedThreadWorktree ( ) ;
32- const { error, loadingGitDiffs, loadingTurnIds } = reviewCache . asyncState ;
33+ const diffPreview = useReviewDiffPreview ( { environmentId, cwd : selectedThreadCwd } ) ;
34+ const refreshDiffPreview = diffPreview . refresh ;
35+ const { loadingTurnIds } = reviewCache . asyncState ;
36+ const error = diffPreview . error ?? reviewCache . asyncState . error ;
37+ const loadingGitDiffs = diffPreview . isPending ;
3338 const turnDiffByIdRef = useRef ( reviewCache . turnDiffById ) ;
3439
3540 useEffect ( ( ) => {
3641 turnDiffByIdRef . current = reviewCache . turnDiffById ;
3742 } , [ reviewCache . turnDiffById ] ) ;
3843
44+ useEffect ( ( ) => {
45+ if ( reviewCache . threadKey && diffPreview . data ) {
46+ setReviewGitSections ( reviewCache . threadKey , diffPreview . data . sources ) ;
47+ }
48+ } , [ diffPreview . data , reviewCache . threadKey ] ) ;
49+
3950 const readyCheckpoints = useMemo (
4051 ( ) => getReadyReviewCheckpoints ( selectedThread ?. checkpoints ?? [ ] ) ,
4152 [ selectedThread ?. checkpoints ] ,
@@ -78,42 +89,6 @@ export function useReviewSections(input: {
7889 [ reviewCache . selectedSectionId , reviewSections ] ,
7990 ) ;
8091
81- const loadGitDiffs = useCallback ( async ( ) => {
82- if ( ! environmentId || ! selectedThreadCwd ) {
83- return ;
84- }
85-
86- const client = getEnvironmentClient ( environmentId ) ;
87- if ( ! client ) {
88- if ( reviewCache . threadKey ) {
89- setReviewAsyncError ( reviewCache . threadKey , "Remote connection is not ready." ) ;
90- }
91- return ;
92- }
93-
94- if ( reviewCache . threadKey ) {
95- setReviewGitDiffsLoading ( reviewCache . threadKey , true ) ;
96- setReviewAsyncError ( reviewCache . threadKey , null ) ;
97- }
98- try {
99- const result = await client . review . getDiffPreview ( { cwd : selectedThreadCwd } ) ;
100- if ( reviewCache . threadKey ) {
101- setReviewGitSections ( reviewCache . threadKey , result . sources ) ;
102- }
103- } catch ( cause ) {
104- if ( reviewCache . threadKey ) {
105- setReviewAsyncError (
106- reviewCache . threadKey ,
107- cause instanceof Error ? cause . message : "Failed to load review diffs." ,
108- ) ;
109- }
110- } finally {
111- if ( reviewCache . threadKey ) {
112- setReviewGitDiffsLoading ( reviewCache . threadKey , false ) ;
113- }
114- }
115- } , [ environmentId , reviewCache . threadKey , selectedThreadCwd ] ) ;
116-
11792 const loadTurnDiff = useCallback (
11893 async ( checkpoint : OrchestrationCheckpointSummary , force = false ) => {
11994 if ( ! environmentId || ! threadId ) {
@@ -129,8 +104,23 @@ export function useReviewSections(input: {
129104 return ;
130105 }
131106
132- const client = getEnvironmentClient ( environmentId ) ;
133- if ( ! client ) {
107+ const target = {
108+ environmentId,
109+ threadId,
110+ fromTurnCount : Math . max ( 0 , checkpoint . checkpointTurnCount - 1 ) ,
111+ toTurnCount : checkpoint . checkpointTurnCount ,
112+ ignoreWhitespace : false ,
113+ cacheScope : sectionId ,
114+ } ;
115+ const cached = checkpointDiffManager . getSnapshot ( target ) . data ;
116+ if ( ! force && cached ) {
117+ if ( reviewCache . threadKey ) {
118+ setReviewTurnDiff ( reviewCache . threadKey , sectionId , cached . diff ) ;
119+ }
120+ return ;
121+ }
122+
123+ if ( ! getEnvironmentClient ( environmentId ) ) {
134124 if ( reviewCache . threadKey ) {
135125 setReviewAsyncError ( reviewCache . threadKey , "Remote connection is not ready." ) ;
136126 }
@@ -142,13 +132,11 @@ export function useReviewSections(input: {
142132 setReviewAsyncError ( reviewCache . threadKey , null ) ;
143133 }
144134 try {
145- const result = await client . orchestration . getTurnDiff ( {
146- threadId,
147- fromTurnCount : Math . max ( 0 , checkpoint . checkpointTurnCount - 1 ) ,
148- toTurnCount : checkpoint . checkpointTurnCount ,
149- } ) ;
135+ const result = await loadCheckpointDiff ( target , { force } ) ;
150136 if ( reviewCache . threadKey ) {
151- setReviewTurnDiff ( reviewCache . threadKey , sectionId , result . diff ) ;
137+ if ( result ) {
138+ setReviewTurnDiff ( reviewCache . threadKey , sectionId , result . diff ) ;
139+ }
152140 }
153141 } catch ( cause ) {
154142 if ( reviewCache . threadKey ) {
@@ -166,10 +154,6 @@ export function useReviewSections(input: {
166154 [ environmentId , reviewCache . threadKey , threadId ] ,
167155 ) ;
168156
169- useEffect ( ( ) => {
170- void loadGitDiffs ( ) ;
171- } , [ loadGitDiffs ] ) ;
172-
173157 useEffect ( ( ) => {
174158 if ( ! hasReviewSections ) {
175159 return ;
@@ -237,8 +221,8 @@ export function useReviewSections(input: {
237221 return ;
238222 }
239223
240- await loadGitDiffs ( ) ;
241- } , [ checkpointBySectionId , loadGitDiffs , loadTurnDiff , selectedSection ] ) ;
224+ refreshDiffPreview ( ) ;
225+ } , [ checkpointBySectionId , loadTurnDiff , refreshDiffPreview , selectedSection ] ) ;
242226
243227 const selectSection = useCallback (
244228 ( sectionId : string ) => {
0 commit comments