Skip to content

Commit f71ee48

Browse files
refactor(web): move ReferencedFileSourceListItemContainer into its own file
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 9c1c5a6 commit f71ee48

File tree

2 files changed

+113
-106
lines changed

2 files changed

+113
-106
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
'use client';
2+
3+
import { getFileSource } from "@/app/api/(client)/client";
4+
import { VscodeFileIcon } from "@/app/components/vscodeFileIcon";
5+
import { Skeleton } from "@/components/ui/skeleton";
6+
import { isServiceError, unwrapServiceError } from "@/lib/utils";
7+
import { useQuery } from "@tanstack/react-query";
8+
import { ReactCodeMirrorRef } from '@uiw/react-codemirror';
9+
import { memo, useCallback } from "react";
10+
import { FileReference, FileSource, Reference } from "../../types";
11+
import { ReferencedFileSourceListItem } from "./referencedFileSourceListItem";
12+
import isEqual from 'fast-deep-equal/react';
13+
14+
export interface ReferencedFileSourceListItemContainerProps {
15+
fileId: string;
16+
fileSource: FileSource;
17+
references: FileReference[];
18+
hoveredReference?: Reference;
19+
selectedReference?: Reference;
20+
onHoveredReferenceChanged: (reference?: Reference) => void;
21+
onSelectedReferenceChanged: (reference?: Reference) => void;
22+
isExpanded: boolean;
23+
onExpandedChanged: (fileId: string, isExpanded: boolean) => void;
24+
onEditorRef: (fileId: string, ref: ReactCodeMirrorRef | null) => void;
25+
}
26+
27+
const ReferencedFileSourceListItemContainerComponent = ({
28+
fileId,
29+
fileSource,
30+
references,
31+
hoveredReference,
32+
selectedReference,
33+
onHoveredReferenceChanged,
34+
onSelectedReferenceChanged,
35+
isExpanded,
36+
onExpandedChanged,
37+
onEditorRef,
38+
}: ReferencedFileSourceListItemContainerProps) => {
39+
const fileName = fileSource.path.split('/').pop() ?? fileSource.path;
40+
41+
const { data, isLoading, isError, error } = useQuery({
42+
queryKey: ['fileSource', fileSource.path, fileSource.repo, fileSource.revision],
43+
queryFn: () => unwrapServiceError(getFileSource({
44+
path: fileSource.path,
45+
repo: fileSource.repo,
46+
ref: fileSource.revision,
47+
})),
48+
staleTime: Infinity,
49+
});
50+
51+
const handleRef = useCallback((ref: ReactCodeMirrorRef | null) => {
52+
onEditorRef(fileId, ref);
53+
}, [fileId, onEditorRef]);
54+
55+
const handleExpandedChanged = useCallback((isExpanded: boolean) => {
56+
onExpandedChanged(fileId, isExpanded);
57+
}, [fileId, onExpandedChanged]);
58+
59+
if (isLoading) {
60+
return (
61+
<div className="space-y-2">
62+
<div className="flex items-center gap-2 p-2">
63+
<VscodeFileIcon fileName={fileName} className="w-4 h-4" />
64+
<span className="text-sm font-medium">{fileName}</span>
65+
</div>
66+
<Skeleton className="h-48 w-full" />
67+
</div>
68+
);
69+
}
70+
71+
if (isError || isServiceError(data)) {
72+
return (
73+
<div className="space-y-2">
74+
<div className="flex items-center gap-2 p-2">
75+
<VscodeFileIcon fileName={fileName} className="w-4 h-4" />
76+
<span className="text-sm font-medium">{fileName}</span>
77+
</div>
78+
<div className="p-4 text-sm text-destructive bg-destructive/10 rounded border">
79+
Failed to load file: {isServiceError(data) ? data.message : error?.message ?? 'Unknown error'}
80+
</div>
81+
</div>
82+
);
83+
}
84+
85+
const fileData = data!;
86+
87+
return (
88+
<ReferencedFileSourceListItem
89+
id={fileId}
90+
code={fileData.source}
91+
language={fileData.language}
92+
revision={fileSource.revision}
93+
repoName={fileSource.repo}
94+
repoCodeHostType={fileData.repoCodeHostType}
95+
repoDisplayName={fileData.repoDisplayName}
96+
repoWebUrl={fileData.repoExternalWebUrl}
97+
fileName={fileData.path}
98+
references={references}
99+
ref={handleRef}
100+
onSelectedReferenceChanged={onSelectedReferenceChanged}
101+
onHoveredReferenceChanged={onHoveredReferenceChanged}
102+
selectedReference={selectedReference}
103+
hoveredReference={hoveredReference}
104+
isExpanded={isExpanded}
105+
onExpandedChanged={handleExpandedChanged}
106+
/>
107+
);
108+
};
109+
110+
export const ReferencedFileSourceListItemContainer = memo(ReferencedFileSourceListItemContainerComponent, isEqual);

packages/web/src/features/chat/components/chatThread/referencedSourcesListView.tsx

Lines changed: 3 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
'use client';
22

3-
import { getFileSource } from "@/app/api/(client)/client";
4-
import { VscodeFileIcon } from "@/app/components/vscodeFileIcon";
53
import { ScrollArea } from "@/components/ui/scroll-area";
6-
import { Skeleton } from "@/components/ui/skeleton";
7-
import { isServiceError, unwrapServiceError } from "@/lib/utils";
8-
import { useQuery } from "@tanstack/react-query";
9-
import { ReactCodeMirrorRef } from '@uiw/react-codemirror';
4+
import { ReactCodeMirrorRef } from "@uiw/react-codemirror";
105
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
116
import scrollIntoView from 'scroll-into-view-if-needed';
127
import { FileReference, FileSource, Reference } from "../../types";
138
import { tryResolveFileReference } from '../../utils';
14-
import { ReferencedFileSourceListItem } from "./referencedFileSourceListItem";
9+
import { ReferencedFileSourceListItemContainer } from "./referencedFileSourceListItemContainer";
1510
import isEqual from 'fast-deep-equal/react';
1611

1712
interface ReferencedSourcesListViewProps {
@@ -200,7 +195,7 @@ const ReferencedSourcesListViewComponent = ({
200195
const selectedReferenceInFile = referencesInFile.some(r => r.id === selectedReference?.id) ? selectedReference : undefined;
201196

202197
return (
203-
<FileSourceItem
198+
<ReferencedFileSourceListItemContainer
204199
key={fileId}
205200
fileId={fileId}
206201
fileSource={fileSource}
@@ -222,101 +217,3 @@ const ReferencedSourcesListViewComponent = ({
222217

223218
// Memoize to prevent unnecessary re-renders
224219
export const ReferencedSourcesListView = memo(ReferencedSourcesListViewComponent, isEqual);
225-
226-
interface FileSourceItemProps {
227-
fileId: string;
228-
fileSource: FileSource;
229-
references: FileReference[];
230-
hoveredReference?: Reference;
231-
selectedReference?: Reference;
232-
onHoveredReferenceChanged: (reference?: Reference) => void;
233-
onSelectedReferenceChanged: (reference?: Reference) => void;
234-
isExpanded: boolean;
235-
onExpandedChanged: (fileId: string, isExpanded: boolean) => void;
236-
onEditorRef: (fileId: string, ref: ReactCodeMirrorRef | null) => void;
237-
}
238-
239-
const FileSourceItemComponent = ({
240-
fileId,
241-
fileSource,
242-
references,
243-
hoveredReference,
244-
selectedReference,
245-
onHoveredReferenceChanged,
246-
onSelectedReferenceChanged,
247-
isExpanded,
248-
onExpandedChanged,
249-
onEditorRef,
250-
}: FileSourceItemProps) => {
251-
const fileName = fileSource.path.split('/').pop() ?? fileSource.path;
252-
253-
const { data, isLoading, isError, error } = useQuery({
254-
queryKey: ['fileSource', fileSource.path, fileSource.repo, fileSource.revision],
255-
queryFn: () => unwrapServiceError(getFileSource({
256-
path: fileSource.path,
257-
repo: fileSource.repo,
258-
ref: fileSource.revision,
259-
})),
260-
staleTime: Infinity,
261-
});
262-
263-
const handleRef = useCallback((ref: ReactCodeMirrorRef | null) => {
264-
onEditorRef(fileId, ref);
265-
}, [fileId, onEditorRef]);
266-
267-
const handleExpandedChanged = useCallback((isExpanded: boolean) => {
268-
onExpandedChanged(fileId, isExpanded);
269-
}, [fileId, onExpandedChanged]);
270-
271-
if (isLoading) {
272-
return (
273-
<div className="space-y-2">
274-
<div className="flex items-center gap-2 p-2">
275-
<VscodeFileIcon fileName={fileName} className="w-4 h-4" />
276-
<span className="text-sm font-medium">{fileName}</span>
277-
</div>
278-
<Skeleton className="h-48 w-full" />
279-
</div>
280-
);
281-
}
282-
283-
if (isError || isServiceError(data)) {
284-
return (
285-
<div className="space-y-2">
286-
<div className="flex items-center gap-2 p-2">
287-
<VscodeFileIcon fileName={fileName} className="w-4 h-4" />
288-
<span className="text-sm font-medium">{fileName}</span>
289-
</div>
290-
<div className="p-4 text-sm text-destructive bg-destructive/10 rounded border">
291-
Failed to load file: {isServiceError(data) ? data.message : error?.message ?? 'Unknown error'}
292-
</div>
293-
</div>
294-
);
295-
}
296-
297-
const fileData = data!;
298-
299-
return (
300-
<ReferencedFileSourceListItem
301-
id={fileId}
302-
code={fileData.source}
303-
language={fileData.language}
304-
revision={fileSource.revision}
305-
repoName={fileSource.repo}
306-
repoCodeHostType={fileData.repoCodeHostType}
307-
repoDisplayName={fileData.repoDisplayName}
308-
repoWebUrl={fileData.repoExternalWebUrl}
309-
fileName={fileData.path}
310-
references={references}
311-
ref={handleRef}
312-
onSelectedReferenceChanged={onSelectedReferenceChanged}
313-
onHoveredReferenceChanged={onHoveredReferenceChanged}
314-
selectedReference={selectedReference}
315-
hoveredReference={hoveredReference}
316-
isExpanded={isExpanded}
317-
onExpandedChanged={handleExpandedChanged}
318-
/>
319-
);
320-
};
321-
322-
const FileSourceItem = memo(FileSourceItemComponent, isEqual);

0 commit comments

Comments
 (0)