diff --git a/frontend/src/components/tasks/TaskDetailsPanel.tsx b/frontend/src/components/tasks/TaskDetailsPanel.tsx index 2a03f1f0..8c2d9295 100644 --- a/frontend/src/components/tasks/TaskDetailsPanel.tsx +++ b/frontend/src/components/tasks/TaskDetailsPanel.tsx @@ -88,6 +88,7 @@ export function TaskDetailsPanel({ const [diff, setDiff] = useState(null); const [diffLoading, setDiffLoading] = useState(true); const [diffError, setDiffError] = useState(null); + const [isBackgroundRefreshing, setIsBackgroundRefreshing] = useState(false); const [expandedSections, setExpandedSections] = useState>( new Set() ); @@ -132,43 +133,54 @@ export function TaskDetailsPanel({ const diffLoadingRef = useRef(false); // Fetch diff when attempt changes - const fetchDiff = useCallback(async () => { - if (!projectId || !selectedAttempt?.id || !selectedAttempt?.task_id) { - setDiff(null); - setDiffLoading(false); - return; - } + const fetchDiff = useCallback( + async (isBackgroundRefresh = false) => { + if (!projectId || !selectedAttempt?.id || !selectedAttempt?.task_id) { + setDiff(null); + setDiffLoading(false); + return; + } - // Prevent multiple concurrent requests - if (diffLoadingRef.current) { - return; - } + // Prevent multiple concurrent requests + if (diffLoadingRef.current) { + return; + } - try { - diffLoadingRef.current = true; - setDiffLoading(true); - setDiffError(null); - const response = await makeRequest( - `/api/projects/${projectId}/tasks/${selectedAttempt.task_id}/attempts/${selectedAttempt.id}/diff` - ); + try { + diffLoadingRef.current = true; + if (isBackgroundRefresh) { + setIsBackgroundRefreshing(true); + } else { + setDiffLoading(true); + } + setDiffError(null); + const response = await makeRequest( + `/api/projects/${projectId}/tasks/${selectedAttempt.task_id}/attempts/${selectedAttempt.id}/diff` + ); - if (response.ok) { - const result: ApiResponse = await response.json(); - if (result.success && result.data) { - setDiff(result.data); + if (response.ok) { + const result: ApiResponse = await response.json(); + if (result.success && result.data) { + setDiff(result.data); + } else { + setDiffError('Failed to load diff'); + } } else { setDiffError('Failed to load diff'); } - } else { + } catch (err) { setDiffError('Failed to load diff'); + } finally { + diffLoadingRef.current = false; + if (isBackgroundRefresh) { + setIsBackgroundRefreshing(false); + } else { + setDiffLoading(false); + } } - } catch (err) { - setDiffError('Failed to load diff'); - } finally { - diffLoadingRef.current = false; - setDiffLoading(false); - } - }, [projectId, selectedAttempt?.id, selectedAttempt?.task_id]); + }, + [projectId, selectedAttempt?.id, selectedAttempt?.task_id] + ); useEffect(() => { if (isOpen) { @@ -185,11 +197,11 @@ export function TaskDetailsPanel({ if (isCodingAgentRunning) { // Immediately refresh diff when coding agent starts running - fetchDiff(); + fetchDiff(true); // Then refresh diff every 2 seconds while coding agent is active const interval = setInterval(() => { - fetchDiff(); + fetchDiff(true); }, 2000); return () => { @@ -867,9 +879,19 @@ export function TaskDetailsPanel({
-
- {diff.files.length} file - {diff.files.length !== 1 ? 's' : ''} changed +
+
+ {diff.files.length} file + {diff.files.length !== 1 ? 's' : ''} changed +
+ {isBackgroundRefreshing && ( +
+
+ + Updating... + +
+ )}