Skip to content

Commit

Permalink
File explanation bug fixes and improvements (BloopAI#848)
Browse files Browse the repository at this point in the history
* fix headers sizes

* file highlights fixes

* highlight lines of code when hovering over file chip

* open file modal instead of navigation for folder chip in article response

* fix repo status in repo cards

* disable continue button is email is invalid
  • Loading branch information
anastasiya1155 committed Aug 11, 2023
1 parent 1210678 commit 2a00e63
Show file tree
Hide file tree
Showing 19 changed files with 412 additions and 146 deletions.
37 changes: 35 additions & 2 deletions client/src/components/Chat/ConversationMessage/FileChip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, {
SetStateAction,
useEffect,
useRef,
useState,
} from 'react';
import FileIcon from '../../FileIcon';
import { ArrowOut } from '../../../icons';
Expand All @@ -18,6 +19,7 @@ type Props = {
lines?: [number, number];
fileChips?: MutableRefObject<HTMLButtonElement[]>;
setFileHighlights?: Dispatch<SetStateAction<FileHighlightsType>>;
setHoveredLines?: Dispatch<SetStateAction<[number, number] | null>>;
};

const FileChip = ({
Expand All @@ -28,8 +30,16 @@ const FileChip = ({
lines,
fileChips,
setFileHighlights,
setHoveredLines,
}: Props) => {
const ref = useRef<HTMLButtonElement>(null);
const [isHovered, setHovered] = useState(false);
const [, setRendered] = useState(false);

useEffect(() => {
// a hack to make this component rerender once when fileChips are updated
setRendered(true);
}, []);

useEffect(() => {
let chip = ref.current;
Expand All @@ -53,7 +63,7 @@ const FileChip = ({
useEffect(() => {
if (lines && index > -1 && setFileHighlights) {
setFileHighlights((prev) => {
const newHighlights = { ...prev };
const newHighlights = JSON.parse(JSON.stringify(prev));
if (!newHighlights[filePath]) {
newHighlights[filePath] = [];
}
Expand All @@ -64,7 +74,6 @@ const FileChip = ({
)})`,
index,
};
// newHighlights[filePath] = newHighlights[filePath].filter((h) => !!h);
if (JSON.stringify(prev) === JSON.stringify(newHighlights)) {
return prev;
}
Expand All @@ -73,13 +82,37 @@ const FileChip = ({
}
}, [lines, filePath, index]);

useEffect(() => {
if (setHoveredLines && lines && index > -1) {
setHoveredLines((prev) => {
if (
isHovered &&
(!prev || prev[0] !== lines[0] || prev[1] !== lines[1])
) {
return lines;
}
if (
!isHovered &&
prev &&
prev[0] === lines[0] &&
prev[1] === lines[1]
) {
return null;
}
return prev;
});
}
}, [isHovered]);

return (
<button
className={`inline-flex items-center bg-chat-bg-shade rounded-4 overflow-hidden
text-label-base hover:text-label-title border border-transparent hover:border-chat-bg-border
cursor-pointer align-middle ellipsis`}
ref={ref}
onClick={onClick}
onMouseLeave={() => (setHoveredLines ? setHovered(false) : {})}
onMouseEnter={() => (setHoveredLines ? setHovered(true) : {})}
>
{!!lines && (
<span
Expand Down
1 change: 0 additions & 1 deletion client/src/components/Chat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,6 @@ const Chat = () => {
threadId,
navigatedItem?.path,
navigatedItem?.type,
selectedLines,
selectedBranch,
t,
queryIdToEdit,
Expand Down
4 changes: 3 additions & 1 deletion client/src/components/CodeBlock/Code/CodeLine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Props = {
highlightColor?: string | null;
leftHighlight?: boolean;
removePaddings?: boolean;
hoveredBackground?: boolean;
};

const CodeLine = ({
Expand All @@ -62,6 +63,7 @@ const CodeLine = ({
lineNumberToShow = lineNumber + 1,
leftHighlight,
removePaddings,
hoveredBackground,
}: Props) => {
const codeRef = useRef<HTMLTableCellElement>(null);

Expand Down Expand Up @@ -164,7 +166,7 @@ const CodeLine = ({
lineHidden ? 'opacity-0' : ''
} ${
blameLine?.start && lineNumber !== 0 ? ' border-t border-bg-border' : ''
}`}
} ${hoveredBackground ? 'bg-bg-base' : ''}`}
data-line-number={lineNumber}
style={style}
onMouseDown={(e) => {
Expand Down
6 changes: 5 additions & 1 deletion client/src/components/CodeBlock/CodeFull/CodeContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ const CodeContainer = ({
});
const { selectedBranch } = useContext(SearchContext.SelectedBranch);
const { navigatedItem } = useContext(AppNavigationContext);
const { fileHighlights } = useContext(FileHighlightsContext);
const { fileHighlights, hoveredLines } = useContext(
FileHighlightsContext.Values,
);

const getHoverableContent = useCallback(
(hoverableRange: Range, tokenRange: Range, lineNumber?: number) => {
Expand Down Expand Up @@ -178,6 +180,7 @@ const CodeContainer = ({
language={language}
relativePath={relativePath}
highlights={fileHighlights[relativePath]}
hoveredLines={hoveredLines}
{...otherProps}
/>
) : (
Expand All @@ -193,6 +196,7 @@ const CodeContainer = ({
language={language}
relativePath={relativePath}
highlights={fileHighlights[relativePath]}
hoveredLines={hoveredLines}
{...otherProps}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type Props = {
| { lines: [number, number]; color: string; index: number }
| undefined
)[];
hoveredLines: [number, number] | null;
};

const CodeContainerFull = ({
Expand All @@ -59,6 +60,7 @@ const CodeContainerFull = ({
handleRefsDefsClick,
relativePath,
highlights,
hoveredLines,
}: Props) => {
const ref = useRef<HTMLDivElement>(null);
const popupRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -171,6 +173,11 @@ const CodeContainerFull = ({
? highlights[highlightForLine]?.color
: highlightColor
}
hoveredBackground={
!!hoveredLines &&
index >= hoveredLines[0] &&
index <= hoveredLines[1]
}
searchTerm={searchTerm}
>
{line.map((token, i) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Props = {
| { lines: [number, number]; color: string; index: number }
| undefined
)[];
hoveredLines: [number, number] | null;
};

const CodeContainerVirtualized = ({
Expand All @@ -69,6 +70,7 @@ const CodeContainerVirtualized = ({
highlightColor,
relativePath,
highlights,
hoveredLines,
}: Props) => {
const ref = useRef<FixedSizeList>(null);
const listProps = useMemo(
Expand Down Expand Up @@ -174,6 +176,11 @@ const CodeContainerVirtualized = ({
}
searchTerm={searchTerm}
stylesGenerated={style}
hoveredBackground={
!!hoveredLines &&
index >= hoveredLines[0] &&
index <= hoveredLines[1]
}
>
{tokens[index].map((token, i) => (
<Token
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/CodeBlock/CodeFull/ExplainButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ const ExplainButton = ({
setSubmittedQuery(
`#explain_${relativePath}:${
currentSelection[0]![0] + 1
}-${currentSelection[1]![0] + 1}`,
}-${currentSelection[1]![0] + 1}-${Date.now()}`,
);
setChatOpen(true);
setPopupPosition(null);
Expand Down
8 changes: 4 additions & 4 deletions client/src/components/IdeNavigation/NavigationPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ const NavigationPanel = ({ repoName, children }: Props) => {
);
return (
<div className="min-h-full relative flex max-w-[30vw]" style={{ width }}>
<div className="flex flex-1 divide-y divide-bg-border bg-bg-base flex-col border-r border-bg-border min-h-full select-none overflow-auto">
<div className="flex flex-1 bg-bg-base flex-col border-r border-bg-border min-h-full select-none overflow-auto">
<div
className="w-full border-b border-bg-border flex justify-between py-7 px-8 select-none cursor-pointer"
className="w-full border-b border-bg-border flex justify-between h-12 flex-shrink-0 px-6 select-none cursor-pointer"
onClick={() => navigateRepoPath(repoName)}
>
<TextField
value={repoName}
value={repoName.replace(/^github\.com\//, '')}
icon={<GitHubLogo />}
className={'ellipsis'}
className={'ellipsis subhead-s'}
/>
</div>
<div className="flex-1 overflow-auto flex flex-col min-h-full">
Expand Down
142 changes: 142 additions & 0 deletions client/src/components/MarkdownWithCode/CodeRenderer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import {
Dispatch,
memo,
MutableRefObject,
ReactNode,
SetStateAction,
useCallback,
useMemo,
} from 'react';
import FileChip from '../Chat/ConversationMessage/FileChip';
import CodeWithBreadcrumbs from '../../pages/ArticleResponse/CodeWithBreadcrumbs';
import { FileHighlightsType } from '../../types/general';
import NewCode from './NewCode';

type Props = {
children: ReactNode[];
repoName: string;
fileChips: MutableRefObject<never[]>;
hideCode?: boolean;
updateScrollToIndex: (lines: string) => void;
openFileModal: (
path: string,
scrollToLine?: string | undefined,
highlightColor?: string | undefined,
) => void;
setFileHighlights: Dispatch<SetStateAction<FileHighlightsType>>;
setHoveredLines: Dispatch<SetStateAction<[number, number] | null>>;
className?: string;
propsJSON: string;
inline?: boolean;
};

const CodeRenderer = ({
className,
children,
inline,
hideCode,
updateScrollToIndex,
fileChips,
setFileHighlights,
setHoveredLines,
openFileModal,
repoName,
propsJSON,
}: Props) => {
const matchLang = useMemo(
() =>
/lang:(\w+)/.exec(className || '') ||
/language-(\w+)/.exec(className || ''),
[className],
);
const matchType = useMemo(
() => /language-type:(\w+)/.exec(className || ''),
[className],
);
const matchPath = useMemo(
() => /path:(.+),/.exec(className || ''),
[className],
);
const matchLines = useMemo(
() => /lines:(.+)/.exec(className || ''),
[className],
);
const code = useMemo(
() =>
typeof children[0] === 'string' ? children[0].replace(/\n$/, '') : '',
[children],
);
const lines = useMemo(
() => matchLines?.[1].split('-').map((l) => Number(l)) || [],
[matchLines],
);
const colorPreview = useMemo(
() =>
children[0] &&
children.length === 1 &&
typeof children[0] === 'string' &&
/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(children[0]) ? (
<span
className="w-3 h-3 inline-block"
style={{ backgroundColor: children[0] }}
/>
) : null,
[children],
);

const linesToUse: [number, number] | undefined = useMemo(
() => [lines[0] - 1, (lines[1] ?? lines[0]) - 1],
[lines],
);

const handleChipClick = useCallback(() => {
updateScrollToIndex(`${lines[0] - 1}_${(lines[1] ?? lines[0]) - 1}`);
}, [updateScrollToIndex, lines]);

return (
<>
{!inline &&
(matchType?.[1] || matchLang?.[1]) &&
typeof children[0] === 'string' ? (
matchType?.[1] === 'Quoted' ? (
hideCode ? (
<FileChip
fileName={matchPath?.[1] || ''}
filePath={matchPath?.[1] || ''}
skipIcon={false}
onClick={handleChipClick}
lines={linesToUse}
fileChips={fileChips}
setFileHighlights={setFileHighlights}
setHoveredLines={setHoveredLines}
/>
) : (
<CodeWithBreadcrumbs
code={code}
language={matchLang?.[1] || ''}
filePath={matchPath?.[1] || ''}
onResultClick={openFileModal}
startLine={lines[0] ? lines[0] - 1 : null}
repoName={repoName}
/>
)
) : (
<NewCode code={code} language={matchLang?.[1] || ''} />
)
) : colorPreview ? (
<span className="inline-flex gap-1.5 items-center">
{colorPreview}
<code {...JSON.parse(propsJSON)} className={className}>
{children}
</code>
</span>
) : (
<code {...JSON.parse(propsJSON)} className={className}>
{children}
</code>
)}
</>
);
};

export default memo(CodeRenderer);
Loading

0 comments on commit 2a00e63

Please sign in to comment.