mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-30 17:13:15 +00:00
lint
This commit is contained in:
@@ -5,7 +5,10 @@ import { useTranslation } from 'react-i18next';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import { oneLight, vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
||||
import {
|
||||
oneLight,
|
||||
vscDarkPlus,
|
||||
} from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
||||
import rehypeKatex from 'rehype-katex';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkMath from 'remark-math';
|
||||
@@ -26,7 +29,10 @@ import CopyButton from '../components/CopyButton';
|
||||
import Sidebar from '../components/Sidebar';
|
||||
import SpeakButton from '../components/TextToSpeechButton';
|
||||
import { useDarkTheme, useOutsideAlerter } from '../hooks';
|
||||
import { selectChunks, selectSelectedDocs } from '../preferences/preferenceSlice';
|
||||
import {
|
||||
selectChunks,
|
||||
selectSelectedDocs,
|
||||
} from '../preferences/preferenceSlice';
|
||||
import classes from './ConversationBubble.module.css';
|
||||
import { FEEDBACK, MESSAGE_TYPE } from './conversationModels';
|
||||
import { ToolCallsType } from './types';
|
||||
@@ -106,19 +112,19 @@ const ConversationBubble = forwardRef<
|
||||
>
|
||||
<Avatar
|
||||
size="SMALL"
|
||||
className="mt-2 text-2xl flex-shrink-0"
|
||||
className="mt-2 flex-shrink-0 text-2xl"
|
||||
avatar={
|
||||
<img className="rounded-full mr-1" width={30} src={UserIcon} />
|
||||
<img className="mr-1 rounded-full" width={30} src={UserIcon} />
|
||||
}
|
||||
/>
|
||||
{!isEditClicked && (
|
||||
<>
|
||||
<div className="flex flex-col mr-2">
|
||||
<div className="mr-2 flex flex-col">
|
||||
<div
|
||||
style={{
|
||||
wordBreak: 'break-word',
|
||||
}}
|
||||
className="text-sm sm:text-base ml-2 mr-2 flex items-center rounded-[28px] bg-gradient-to-b from-medium-purple to-slate-blue py-[14px] px-[19px] text-white max-w-full whitespace-pre-wrap leading-normal"
|
||||
className="ml-2 mr-2 flex max-w-full items-center whitespace-pre-wrap rounded-[28px] bg-gradient-to-b from-medium-purple to-slate-blue px-[19px] py-[14px] text-sm leading-normal text-white sm:text-base"
|
||||
>
|
||||
{message}
|
||||
</div>
|
||||
@@ -128,7 +134,7 @@ const ConversationBubble = forwardRef<
|
||||
setIsEditClicked(true);
|
||||
setEditInputBox(message ?? '');
|
||||
}}
|
||||
className={`flex-shrink-0 h-fit mt-3 p-2 cursor-pointer rounded-full hover:bg-light-silver dark:hover:bg-[#35363B] flex items-center ${isQuestionHovered || isEditClicked ? 'visible' : 'invisible'}`}
|
||||
className={`mt-3 flex h-fit flex-shrink-0 cursor-pointer items-center rounded-full p-2 hover:bg-light-silver dark:hover:bg-[#35363B] ${isQuestionHovered || isEditClicked ? 'visible' : 'invisible'}`}
|
||||
>
|
||||
<img src={Edit} alt="Edit" className="cursor-pointer" />
|
||||
</button>
|
||||
@@ -137,7 +143,7 @@ const ConversationBubble = forwardRef<
|
||||
{isEditClicked && (
|
||||
<div
|
||||
ref={editableQueryRef}
|
||||
className="w-full mx-auto bg-transparent p-4 rounded-lg flex flex-col gap-4"
|
||||
className="mx-auto flex w-full flex-col gap-4 rounded-lg bg-transparent p-4"
|
||||
>
|
||||
<textarea
|
||||
placeholder={t('conversation.edit.placeholder')}
|
||||
@@ -152,17 +158,17 @@ const ConversationBubble = forwardRef<
|
||||
}}
|
||||
rows={5}
|
||||
value={editInputBox}
|
||||
className="w-full resize-none border border-silver dark:border-philippine-grey rounded-3xl px-4 py-3 text-base leading-relaxed text-carbon dark:text-chinese-white dark:bg-raisin-black focus:outline-none"
|
||||
className="w-full resize-none rounded-3xl border border-silver px-4 py-3 text-base leading-relaxed text-carbon focus:outline-none dark:border-philippine-grey dark:bg-raisin-black dark:text-chinese-white"
|
||||
/>
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<button
|
||||
className="px-4 py-2 text-purple-30 text-sm font-semibold hover:text-chinese-black-2 dark:hover:text-[#B9BCBE] hover:bg-gainsboro dark:hover:bg-onyx-2 transition-colors rounded-full"
|
||||
className="rounded-full px-4 py-2 text-sm font-semibold text-purple-30 transition-colors hover:bg-gainsboro hover:text-chinese-black-2 dark:hover:bg-onyx-2 dark:hover:text-[#B9BCBE]"
|
||||
onClick={() => setIsEditClicked(false)}
|
||||
>
|
||||
{t('conversation.edit.cancel')}
|
||||
</button>
|
||||
<button
|
||||
className="rounded-full bg-purple-30 hover:bg-violets-are-blue dark:hover:bg-royal-purple px-4 py-2 text-white text-sm font-medium transition-colors"
|
||||
className="rounded-full bg-purple-30 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-violets-are-blue dark:hover:bg-royal-purple"
|
||||
onClick={handleEditClick}
|
||||
>
|
||||
{t('conversation.edit.update')}
|
||||
@@ -192,7 +198,10 @@ const ConversationBubble = forwardRef<
|
||||
const processMarkdownContent = (content: string) => {
|
||||
const processedContent = preprocessLaTeX(content);
|
||||
|
||||
const contentSegments: Array<{type: 'text' | 'mermaid', content: string}> = [];
|
||||
const contentSegments: Array<{
|
||||
type: 'text' | 'mermaid';
|
||||
content: string;
|
||||
}> = [];
|
||||
|
||||
let lastIndex = 0;
|
||||
const regex = /```mermaid\n([\s\S]*?)```/g;
|
||||
@@ -219,7 +228,7 @@ const ConversationBubble = forwardRef<
|
||||
bubble = (
|
||||
<div
|
||||
ref={ref}
|
||||
className={`flex flex-wrap self-start ${className} group flex-col dark:text-bright-gray`}
|
||||
className={`flex flex-wrap self-start ${className} group flex-col dark:text-bright-gray`}
|
||||
>
|
||||
{DisableSourceFE ||
|
||||
type === 'ERROR' ||
|
||||
@@ -378,9 +387,9 @@ const ConversationBubble = forwardRef<
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
className={`fade-in-bubble ml-2 mr-5 flex max-w-[90vw] rounded-[28px] bg-gray-1000 py-[18px] px-7 dark:bg-gun-metal md:max-w-[70vw] lg:max-w-[50vw] ${
|
||||
className={`fade-in-bubble ml-2 mr-5 flex max-w-[90vw] rounded-[28px] bg-gray-1000 px-7 py-[18px] dark:bg-gun-metal md:max-w-[70vw] lg:max-w-[50vw] ${
|
||||
type === 'ERROR'
|
||||
? 'relative flex-row items-center rounded-full border border-transparent bg-[#FFE7E7] p-2 py-5 text-sm font-normal text-red-3000 dark:border-red-2000 dark:text-white'
|
||||
? 'relative flex-row items-center rounded-full border border-transparent bg-[#FFE7E7] p-2 py-5 text-sm font-normal text-red-3000 dark:border-red-2000 dark:text-white'
|
||||
: 'flex-col rounded-3xl'
|
||||
}`}
|
||||
>
|
||||
@@ -397,25 +406,38 @@ const ConversationBubble = forwardRef<
|
||||
rehypePlugins={[rehypeKatex]}
|
||||
components={{
|
||||
code(props) {
|
||||
const { children, className, node, ref, ...rest } = props;
|
||||
const match = /language-(\w+)/.exec(className || '');
|
||||
const {
|
||||
children,
|
||||
className,
|
||||
node,
|
||||
ref,
|
||||
...rest
|
||||
} = props;
|
||||
const match = /language-(\w+)/.exec(
|
||||
className || '',
|
||||
);
|
||||
const language = match ? match[1] : '';
|
||||
|
||||
return match ? (
|
||||
<div className="group relative rounded-[14px] overflow-hidden border border-light-silver dark:border-raisin-black">
|
||||
<div className="flex justify-between items-center px-2 py-1 bg-platinum dark:bg-eerie-black-2">
|
||||
<div className="group relative overflow-hidden rounded-[14px] border border-light-silver dark:border-raisin-black">
|
||||
<div className="flex items-center justify-between bg-platinum px-2 py-1 dark:bg-eerie-black-2">
|
||||
<span className="text-xs font-medium text-just-black dark:text-chinese-white">
|
||||
{language}
|
||||
</span>
|
||||
<CopyButton
|
||||
textToCopy={String(children).replace(/\n$/, '')}
|
||||
textToCopy={String(children).replace(
|
||||
/\n$/,
|
||||
'',
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<SyntaxHighlighter
|
||||
{...rest}
|
||||
PreTag="div"
|
||||
language={language}
|
||||
style={isDarkTheme ? vscDarkPlus : oneLight}
|
||||
style={
|
||||
isDarkTheme ? vscDarkPlus : oneLight
|
||||
}
|
||||
className="!mt-0"
|
||||
customStyle={{
|
||||
margin: 0,
|
||||
@@ -461,30 +483,37 @@ const ConversationBubble = forwardRef<
|
||||
},
|
||||
thead({ children }) {
|
||||
return (
|
||||
<thead className="text-xs uppercase text-gray-900 dark:text-bright-gray bg-gray-50 dark:bg-[#26272E]/50">
|
||||
<thead className="bg-gray-50 text-xs uppercase text-gray-900 dark:bg-[#26272E]/50 dark:text-bright-gray">
|
||||
{children}
|
||||
</thead>
|
||||
);
|
||||
},
|
||||
tr({ children }) {
|
||||
return (
|
||||
<tr className="border-b border-gray-200 dark:border-silver/40 odd:bg-white dark:odd:bg-[#26272E] even:bg-gray-50 dark:even:bg-[#26272E]/50">
|
||||
<tr className="border-b border-gray-200 odd:bg-white even:bg-gray-50 dark:border-silver/40 dark:odd:bg-[#26272E] dark:even:bg-[#26272E]/50">
|
||||
{children}
|
||||
</tr>
|
||||
);
|
||||
},
|
||||
th({ children }) {
|
||||
return <th className="px-6 py-3">{children}</th>;
|
||||
return (
|
||||
<th className="px-6 py-3">{children}</th>
|
||||
);
|
||||
},
|
||||
td({ children }) {
|
||||
return <td className="px-6 py-3">{children}</td>;
|
||||
return (
|
||||
<td className="px-6 py-3">{children}</td>
|
||||
);
|
||||
},
|
||||
}}
|
||||
>
|
||||
{segment.content}
|
||||
</ReactMarkdown>
|
||||
) : (
|
||||
<div className="my-4 w-full" style={{ minWidth: '100%' }}>
|
||||
<div
|
||||
className="my-4 w-full"
|
||||
style={{ minWidth: '100%' }}
|
||||
>
|
||||
<MermaidRenderer
|
||||
code={segment.content}
|
||||
isLoading={isStreaming}
|
||||
@@ -502,16 +531,14 @@ const ConversationBubble = forwardRef<
|
||||
{message && (
|
||||
<div className="my-2 ml-2 flex justify-start">
|
||||
<div
|
||||
className={`relative mr-2 block items-center justify-center lg:invisible
|
||||
${type !== 'ERROR' ? 'group-hover:lg:visible' : 'hidden'}`}
|
||||
className={`relative mr-2 block items-center justify-center lg:invisible ${type !== 'ERROR' ? 'group-hover:lg:visible' : 'hidden'}`}
|
||||
>
|
||||
<div>
|
||||
<CopyButton textToCopy={message} />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`relative mr-2 block items-center justify-center lg:invisible
|
||||
${type !== 'ERROR' ? 'group-hover:lg:visible' : 'hidden'}`}
|
||||
className={`relative mr-2 block items-center justify-center lg:invisible ${type !== 'ERROR' ? 'group-hover:lg:visible' : 'hidden'}`}
|
||||
>
|
||||
<div>
|
||||
<SpeakButton text={message} />
|
||||
@@ -529,8 +556,7 @@ const ConversationBubble = forwardRef<
|
||||
feedback === 'LIKE' || isLikeClicked
|
||||
? 'visible'
|
||||
: 'lg:invisible'
|
||||
} ${type !== 'ERROR' ? 'group-hover:lg:visible' : ''}
|
||||
${feedback === 'DISLIKE' && type !== 'ERROR' ? 'hidden' : ''}`}
|
||||
} ${type !== 'ERROR' ? 'group-hover:lg:visible' : ''} ${feedback === 'DISLIKE' && type !== 'ERROR' ? 'hidden' : ''}`}
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
@@ -541,12 +567,11 @@ const ConversationBubble = forwardRef<
|
||||
}`}
|
||||
>
|
||||
<Like
|
||||
className={`cursor-pointer
|
||||
${
|
||||
isLikeClicked || feedback === 'LIKE'
|
||||
? 'fill-white-3000 stroke-purple-30 dark:fill-transparent'
|
||||
: 'fill-none stroke-gray-4000'
|
||||
}`}
|
||||
className={`cursor-pointer ${
|
||||
isLikeClicked || feedback === 'LIKE'
|
||||
? 'fill-white-3000 stroke-purple-30 dark:fill-transparent'
|
||||
: 'fill-none stroke-gray-4000'
|
||||
}`}
|
||||
onClick={() => {
|
||||
if (feedback === undefined || feedback === null) {
|
||||
handleFeedback?.('LIKE');
|
||||
@@ -570,8 +595,7 @@ const ConversationBubble = forwardRef<
|
||||
feedback === 'DISLIKE' || isLikeClicked
|
||||
? 'visible'
|
||||
: 'lg:invisible'
|
||||
} ${type !== 'ERROR' ? 'group-hover:lg:visible' : ''}
|
||||
${feedback === 'LIKE' && type !== 'ERROR' ? 'hidden' : ''}`}
|
||||
} ${type !== 'ERROR' ? 'group-hover:lg:visible' : ''} ${feedback === 'LIKE' && type !== 'ERROR' ? 'hidden' : ''}`}
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
@@ -585,7 +609,7 @@ const ConversationBubble = forwardRef<
|
||||
className={`cursor-pointer ${
|
||||
isDislikeClicked || feedback === 'DISLIKE'
|
||||
? 'fill-white-3000 stroke-red-2000 dark:fill-transparent'
|
||||
: 'fill-none stroke-gray-4000'
|
||||
: 'fill-none stroke-gray-4000'
|
||||
}`}
|
||||
onClick={() => {
|
||||
if (feedback === undefined || feedback === null) {
|
||||
@@ -633,7 +657,7 @@ function AllSources(sources: AllSourcesProps) {
|
||||
<div className="h-full w-full">
|
||||
<div className="w-full">
|
||||
<p className="text-left text-xl">{`${sources.sources.length} Sources`}</p>
|
||||
<div className="mx-1 mt-2 h-[0.8px] w-full rounded-full bg-[#C4C4C4]/40 lg:w-[95%] "></div>
|
||||
<div className="mx-1 mt-2 h-[0.8px] w-full rounded-full bg-[#C4C4C4]/40 lg:w-[95%]"></div>
|
||||
</div>
|
||||
<div className="mt-6 flex h-[90%] w-60 flex-col items-center gap-4 overflow-y-auto sm:w-80">
|
||||
{sources.sources.map((source, index) => (
|
||||
@@ -674,7 +698,7 @@ export default ConversationBubble;
|
||||
function ToolCalls({ toolCalls }: { toolCalls: ToolCallsType[] }) {
|
||||
const [isToolCallsOpen, setIsToolCallsOpen] = useState(false);
|
||||
return (
|
||||
<div className="mb-4 w-full flex flex-col flex-wrap items-start self-start lg:flex-nowrap">
|
||||
<div className="mb-4 flex w-full flex-col flex-wrap items-start self-start lg:flex-nowrap">
|
||||
<div className="my-2 flex flex-row items-center justify-center gap-3">
|
||||
<Avatar
|
||||
className="h-[26px] w-[30px] text-xl"
|
||||
@@ -705,12 +729,12 @@ function ToolCalls({ toolCalls }: { toolCalls: ToolCallsType[] }) {
|
||||
<Accordion
|
||||
key={`tool-call-${index}`}
|
||||
title={`${toolCall.tool_name} - ${toolCall.action_name.substring(0, toolCall.action_name.lastIndexOf('_'))}`}
|
||||
className="w-full rounded-[20px] bg-gray-1000 dark:bg-gun-metal hover:bg-[#F1F1F1] dark:hover:bg-[#2C2E3C]"
|
||||
className="w-full rounded-[20px] bg-gray-1000 hover:bg-[#F1F1F1] dark:bg-gun-metal dark:hover:bg-[#2C2E3C]"
|
||||
titleClassName="px-6 py-2 text-sm font-semibold"
|
||||
>
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex flex-col border border-silver dark:border-silver/20 rounded-2xl">
|
||||
<p className="flex flex-row items-center justify-between px-2 py-1 text-sm font-semibold bg-black/10 dark:bg-[#191919] rounded-t-2xl break-words">
|
||||
<div className="flex flex-col rounded-2xl border border-silver dark:border-silver/20">
|
||||
<p className="flex flex-row items-center justify-between break-words rounded-t-2xl bg-black/10 px-2 py-1 text-sm font-semibold dark:bg-[#191919]">
|
||||
<span style={{ fontFamily: 'IBMPlexMono-Medium' }}>
|
||||
Arguments
|
||||
</span>{' '}
|
||||
@@ -718,17 +742,17 @@ function ToolCalls({ toolCalls }: { toolCalls: ToolCallsType[] }) {
|
||||
textToCopy={JSON.stringify(toolCall.arguments, null, 2)}
|
||||
/>
|
||||
</p>
|
||||
<p className="p-2 font-mono text-sm dark:tex dark:bg-[#222327] rounded-b-2xl break-words">
|
||||
<p className="dark:tex break-words rounded-b-2xl p-2 font-mono text-sm dark:bg-[#222327]">
|
||||
<span
|
||||
className="text-black dark:text-gray-400 leading-[23px]"
|
||||
className="leading-[23px] text-black dark:text-gray-400"
|
||||
style={{ fontFamily: 'IBMPlexMono-Medium' }}
|
||||
>
|
||||
{JSON.stringify(toolCall.arguments, null, 2)}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col border border-silver dark:border-silver/20 rounded-2xl">
|
||||
<p className="flex flex-row items-center justify-between px-2 py-1 text-sm font-semibold bg-black/10 dark:bg-[#191919] rounded-t-2xl break-words">
|
||||
<div className="flex flex-col rounded-2xl border border-silver dark:border-silver/20">
|
||||
<p className="flex flex-row items-center justify-between break-words rounded-t-2xl bg-black/10 px-2 py-1 text-sm font-semibold dark:bg-[#191919]">
|
||||
<span style={{ fontFamily: 'IBMPlexMono-Medium' }}>
|
||||
Response
|
||||
</span>{' '}
|
||||
@@ -736,9 +760,9 @@ function ToolCalls({ toolCalls }: { toolCalls: ToolCallsType[] }) {
|
||||
textToCopy={JSON.stringify(toolCall.result, null, 2)}
|
||||
/>
|
||||
</p>
|
||||
<p className="p-2 font-mono text-sm dark:tex dark:bg-[#222327] rounded-b-2xl break-words">
|
||||
<p className="dark:tex break-words rounded-b-2xl p-2 font-mono text-sm dark:bg-[#222327]">
|
||||
<span
|
||||
className="text-black dark:text-gray-400 leading-[23px]"
|
||||
className="leading-[23px] text-black dark:text-gray-400"
|
||||
style={{ fontFamily: 'IBMPlexMono-Medium' }}
|
||||
>
|
||||
{JSON.stringify(toolCall.result, null, 2)}
|
||||
@@ -766,7 +790,7 @@ function Thought({
|
||||
const [isThoughtOpen, setIsThoughtOpen] = useState(true);
|
||||
|
||||
return (
|
||||
<div className="mb-4 w-full flex flex-col flex-wrap items-start self-start lg:flex-nowrap">
|
||||
<div className="mb-4 flex w-full flex-col flex-wrap items-start self-start lg:flex-nowrap">
|
||||
<div className="my-2 flex flex-row items-center justify-center gap-3">
|
||||
<Avatar
|
||||
className="h-[26px] w-[30px] text-xl"
|
||||
@@ -792,7 +816,7 @@ function Thought({
|
||||
</div>
|
||||
{isThoughtOpen && (
|
||||
<div className="fade-in ml-2 mr-5 max-w-[90vw] md:max-w-[70vw] lg:max-w-[50vw]">
|
||||
<div className="rounded-[28px] bg-gray-1000 py-[18px] px-7 dark:bg-gun-metal">
|
||||
<div className="rounded-[28px] bg-gray-1000 px-7 py-[18px] dark:bg-gun-metal">
|
||||
<ReactMarkdown
|
||||
className="fade-in whitespace-pre-wrap break-words leading-normal"
|
||||
remarkPlugins={[remarkGfm, remarkMath]}
|
||||
@@ -804,8 +828,8 @@ function Thought({
|
||||
const language = match ? match[1] : '';
|
||||
|
||||
return match ? (
|
||||
<div className="group relative rounded-[14px] overflow-hidden border border-light-silver dark:border-raisin-black">
|
||||
<div className="flex justify-between items-center px-2 py-1 bg-platinum dark:bg-eerie-black-2">
|
||||
<div className="group relative overflow-hidden rounded-[14px] border border-light-silver dark:border-raisin-black">
|
||||
<div className="flex items-center justify-between bg-platinum px-2 py-1 dark:bg-eerie-black-2">
|
||||
<span className="text-xs font-medium text-just-black dark:text-chinese-white">
|
||||
{language}
|
||||
</span>
|
||||
@@ -859,14 +883,14 @@ function Thought({
|
||||
},
|
||||
thead({ children }) {
|
||||
return (
|
||||
<thead className="text-xs uppercase text-gray-900 dark:text-bright-gray bg-gray-50 dark:bg-[#26272E]/50">
|
||||
<thead className="bg-gray-50 text-xs uppercase text-gray-900 dark:bg-[#26272E]/50 dark:text-bright-gray">
|
||||
{children}
|
||||
</thead>
|
||||
);
|
||||
},
|
||||
tr({ children }) {
|
||||
return (
|
||||
<tr className="border-b border-gray-200 dark:border-silver/40 odd:bg-white dark:odd:bg-[#26272E] even:bg-gray-50 dark:even:bg-[#26272E]/50">
|
||||
<tr className="border-b border-gray-200 odd:bg-white even:bg-gray-50 dark:border-silver/40 dark:odd:bg-[#26272E] dark:even:bg-[#26272E]/50">
|
||||
{children}
|
||||
</tr>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user