mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-12 12:25:22 +00:00
Add filename highlighting
This commit is contained in:
parent
4e5deb22a1
commit
fa42eba35e
3 changed files with 78 additions and 29 deletions
|
|
@ -110,7 +110,7 @@ export const CodePreviewPanel = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-full">
|
<div className="flex flex-col h-full">
|
||||||
<div className="flex flex-row bg-cyan-200 dark:bg-cyan-900 items-center justify-between pr-3">
|
<div className="flex flex-row bg-cyan-200 dark:bg-cyan-900 items-center justify-between pr-3 py-0.5">
|
||||||
<div className="flex flex-row">
|
<div className="flex flex-row">
|
||||||
<div
|
<div
|
||||||
style={{ width: `${gutterWidth}px` }}
|
style={{ width: `${gutterWidth}px` }}
|
||||||
|
|
@ -132,25 +132,29 @@ export const CodePreviewPanel = ({
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row gap-1 items-center">
|
<div className="flex flex-row gap-1 items-center">
|
||||||
<p className="text-sm">{`${selectedMatchIndex + 1} of ${ranges.length}`}</p>
|
{file && file.matches.length > 0 && (
|
||||||
<Button
|
<>
|
||||||
variant="ghost"
|
<p className="text-sm">{`${selectedMatchIndex + 1} of ${ranges.length}`}</p>
|
||||||
size="icon"
|
<Button
|
||||||
className="h-6 w-6"
|
variant="ghost"
|
||||||
disabled={selectedMatchIndex === 0}
|
size="icon"
|
||||||
onClick={onUpClicked}
|
className="h-6 w-6"
|
||||||
>
|
disabled={selectedMatchIndex === 0}
|
||||||
<ArrowUp className="h-4 w-4" />
|
onClick={onUpClicked}
|
||||||
</Button>
|
>
|
||||||
<Button
|
<ArrowUp className="h-4 w-4" />
|
||||||
variant="ghost"
|
</Button>
|
||||||
size="icon"
|
<Button
|
||||||
className="h-6 w-6"
|
variant="ghost"
|
||||||
onClick={onDownClicked}
|
size="icon"
|
||||||
disabled={file ? selectedMatchIndex === ranges.length - 1 : true}
|
className="h-6 w-6"
|
||||||
>
|
onClick={onDownClicked}
|
||||||
<ArrowDown className="h-4 w-4" />
|
disabled={file ? selectedMatchIndex === ranges.length - 1 : true}
|
||||||
</Button>
|
>
|
||||||
|
<ArrowDown className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
|
|
|
||||||
|
|
@ -101,8 +101,10 @@ export default function SearchPage() {
|
||||||
<ResizablePanel minSize={20}>
|
<ResizablePanel minSize={20}>
|
||||||
<SearchResultsPanel
|
<SearchResultsPanel
|
||||||
fileMatches={fileMatches}
|
fileMatches={fileMatches}
|
||||||
onOpenFileMatch={(fileMatch, matchIndex) => {
|
onOpenFileMatch={(fileMatch) => {
|
||||||
setSelectedFile(fileMatch);
|
setSelectedFile(fileMatch);
|
||||||
|
}}
|
||||||
|
onMatchIndexChanged={(matchIndex) => {
|
||||||
setSelectedMatchIndex(matchIndex);
|
setSelectedMatchIndex(matchIndex);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -152,10 +154,15 @@ const CodePreviewWrapper = ({
|
||||||
|
|
||||||
const decodedSource = atob(source);
|
const decodedSource = atob(source);
|
||||||
|
|
||||||
|
// Filter out filename matches
|
||||||
|
const filteredMatches = fileMatch.ChunkMatches.filter((match) => {
|
||||||
|
return !match.FileName;
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content: decodedSource,
|
content: decodedSource,
|
||||||
filepath: fileMatch.FileName,
|
filepath: fileMatch.FileName,
|
||||||
matches: fileMatch.ChunkMatches,
|
matches: filteredMatches,
|
||||||
link: link,
|
link: link,
|
||||||
language: fileMatch.Language,
|
language: fileMatch.Language,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,14 @@ const MAX_MATCHES_TO_PREVIEW = 3;
|
||||||
|
|
||||||
interface SearchResultsPanelProps {
|
interface SearchResultsPanelProps {
|
||||||
fileMatches: SearchResultFile[];
|
fileMatches: SearchResultFile[];
|
||||||
onOpenFileMatch: (fileMatch: SearchResultFile, matchIndex: number) => void;
|
onOpenFileMatch: (fileMatch: SearchResultFile) => void;
|
||||||
|
onMatchIndexChanged: (matchIndex: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SearchResultsPanel = ({
|
export const SearchResultsPanel = ({
|
||||||
fileMatches,
|
fileMatches,
|
||||||
onOpenFileMatch,
|
onOpenFileMatch,
|
||||||
|
onMatchIndexChanged,
|
||||||
}: SearchResultsPanelProps) => {
|
}: SearchResultsPanelProps) => {
|
||||||
return (
|
return (
|
||||||
<ScrollArea className="h-full">
|
<ScrollArea className="h-full">
|
||||||
|
|
@ -32,8 +34,11 @@ export const SearchResultsPanel = ({
|
||||||
<FilePreview
|
<FilePreview
|
||||||
key={index}
|
key={index}
|
||||||
file={fileMatch}
|
file={fileMatch}
|
||||||
onOpenFile={(matchIndex) => {
|
onOpenFile={() => {
|
||||||
onOpenFileMatch(fileMatch, matchIndex);
|
onOpenFileMatch(fileMatch);
|
||||||
|
}}
|
||||||
|
onMatchIndexChanged={(matchIndex) => {
|
||||||
|
onMatchIndexChanged(matchIndex);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
@ -44,12 +49,14 @@ export const SearchResultsPanel = ({
|
||||||
|
|
||||||
interface FilePreviewProps {
|
interface FilePreviewProps {
|
||||||
file: SearchResultFile;
|
file: SearchResultFile;
|
||||||
onOpenFile: (matchIndex: number) => void;
|
onOpenFile: () => void;
|
||||||
|
onMatchIndexChanged: (matchIndex: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilePreview = ({
|
const FilePreview = ({
|
||||||
file,
|
file,
|
||||||
onOpenFile,
|
onOpenFile,
|
||||||
|
onMatchIndexChanged,
|
||||||
}: FilePreviewProps) => {
|
}: FilePreviewProps) => {
|
||||||
|
|
||||||
const [showAll, setShowAll] = useState(false);
|
const [showAll, setShowAll] = useState(false);
|
||||||
|
|
@ -69,6 +76,20 @@ const FilePreview = ({
|
||||||
return sortedMatches;
|
return sortedMatches;
|
||||||
}, [file, showAll]);
|
}, [file, showAll]);
|
||||||
|
|
||||||
|
const fileNameRange = useMemo(() => {
|
||||||
|
for (const match of matches) {
|
||||||
|
if (match.FileName && match.Ranges.length > 0) {
|
||||||
|
const range = match.Ranges[0];
|
||||||
|
return {
|
||||||
|
from: range.Start.Column - 1,
|
||||||
|
to: range.End.Column - 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}, [matches]);
|
||||||
|
|
||||||
const { repoIcon, repoName, repoLink } = useMemo(() => {
|
const { repoIcon, repoName, repoLink } = useMemo(() => {
|
||||||
const info = getRepoCodeHostInfo(file.Repository);
|
const info = getRepoCodeHostInfo(file.Repository);
|
||||||
if (info) {
|
if (info) {
|
||||||
|
|
@ -96,7 +117,12 @@ const FilePreview = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="bg-cyan-200 dark:bg-cyan-900 primary-foreground px-2 py-0.5 flex flex-row items-center justify-between border">
|
<div
|
||||||
|
className="bg-cyan-200 dark:bg-cyan-900 primary-foreground px-2 py-0.5 flex flex-row items-center justify-between border cursor-pointer"
|
||||||
|
onClick={() => {
|
||||||
|
onOpenFile();
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div className="flex flex-row gap-2 items-center">
|
<div className="flex flex-row gap-2 items-center">
|
||||||
{repoIcon}
|
{repoIcon}
|
||||||
<span
|
<span
|
||||||
|
|
@ -111,7 +137,18 @@ const FilePreview = ({
|
||||||
>
|
>
|
||||||
{repoName}
|
{repoName}
|
||||||
</span>
|
</span>
|
||||||
<span>· {file.FileName}</span>
|
<span>·</span>
|
||||||
|
{!fileNameRange ? (
|
||||||
|
<span>{file.FileName}</span>
|
||||||
|
) : (
|
||||||
|
<span>
|
||||||
|
{file.FileName.slice(0, fileNameRange.from)}
|
||||||
|
<span className="bg-yellow-200 dark:bg-blue-700">
|
||||||
|
{file.FileName.slice(fileNameRange.from, fileNameRange.to)}
|
||||||
|
</span>
|
||||||
|
{file.FileName.slice(fileNameRange.to)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{matches.map((match, index) => {
|
{matches.map((match, index) => {
|
||||||
|
|
@ -132,7 +169,8 @@ const FilePreview = ({
|
||||||
const matchIndex = matches.slice(0, index).reduce((acc, match) => {
|
const matchIndex = matches.slice(0, index).reduce((acc, match) => {
|
||||||
return acc + match.Ranges.length;
|
return acc + match.Ranges.length;
|
||||||
}, 0);
|
}, 0);
|
||||||
onOpenFile(matchIndex);
|
onOpenFile();
|
||||||
|
onMatchIndexChanged(matchIndex);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CodePreview
|
<CodePreview
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue