mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-03-09 09:32:36 +01:00
style: temporarily remove scrolling, add better styling
This commit is contained in:
parent
e026fc7009
commit
ee126a2350
4 changed files with 63 additions and 65 deletions
|
|
@ -32,6 +32,7 @@ const ArtifactButton = ({ artifact }: { artifact: Artifact | null }) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
<br />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import * as Tabs from '@radix-ui/react-tabs';
|
import * as Tabs from '@radix-ui/react-tabs';
|
||||||
import { getFileExtension } from '~/utils/artifacts';
|
|
||||||
import useArtifacts from '~/hooks/Artifacts/useArtifacts';
|
import useArtifacts from '~/hooks/Artifacts/useArtifacts';
|
||||||
import { CodeMarkdown, CopyCodeButton } from './Code';
|
import { CodeMarkdown, CopyCodeButton } from './Code';
|
||||||
|
import { getFileExtension } from '~/utils/artifacts';
|
||||||
import { ArtifactPreview } from './ArtifactPreview';
|
import { ArtifactPreview } from './ArtifactPreview';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
|
|
||||||
|
|
@ -10,7 +10,6 @@ export default function Artifacts() {
|
||||||
isVisible,
|
isVisible,
|
||||||
activeTab,
|
activeTab,
|
||||||
setActiveTab,
|
setActiveTab,
|
||||||
isSubmitting,
|
|
||||||
currentIndex,
|
currentIndex,
|
||||||
cycleArtifact,
|
cycleArtifact,
|
||||||
currentArtifact,
|
currentArtifact,
|
||||||
|
|
@ -80,19 +79,13 @@ export default function Artifacts() {
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
<Tabs.Content
|
<Tabs.Content
|
||||||
value="code"
|
value="code"
|
||||||
className={cn(
|
className={cn('flex-grow overflow-x-auto overflow-y-scroll bg-gray-900 p-4')}
|
||||||
'flex-grow overflow-auto bg-gray-900',
|
|
||||||
isSubmitting ? 'submitting' : '',
|
|
||||||
isSubmitting && (currentArtifact.content?.length ?? 0) > 0 ? 'result-streaming' : '',
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<CodeMarkdown
|
<CodeMarkdown
|
||||||
showCursor={isSubmitting}
|
|
||||||
content={`\`\`\`${getFileExtension(currentArtifact.type)}\n${
|
content={`\`\`\`${getFileExtension(currentArtifact.type)}\n${
|
||||||
currentArtifact.content ?? ''
|
currentArtifact.content ?? ''
|
||||||
}\`\`\``}
|
}\`\`\``}
|
||||||
/>
|
/>
|
||||||
{/* hidden div to scroll to could go here */}
|
|
||||||
</Tabs.Content>
|
</Tabs.Content>
|
||||||
<Tabs.Content value="preview" className="flex-grow overflow-auto bg-white">
|
<Tabs.Content value="preview" className="flex-grow overflow-auto bg-white">
|
||||||
<ArtifactPreview artifact={currentArtifact} />
|
<ArtifactPreview artifact={currentArtifact} />
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,13 @@
|
||||||
import React, { useRef, RefObject, memo, useState } from 'react';
|
import React, { memo, useState } from 'react';
|
||||||
import rehypeKatex from 'rehype-katex';
|
import rehypeKatex from 'rehype-katex';
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
import rehypeHighlight from 'rehype-highlight';
|
import rehypeHighlight from 'rehype-highlight';
|
||||||
import copy from 'copy-to-clipboard';
|
import copy from 'copy-to-clipboard';
|
||||||
import { handleDoubleClick, cn, langSubset } from '~/utils';
|
import { handleDoubleClick, langSubset } from '~/utils';
|
||||||
import Clipboard from '~/components/svg/Clipboard';
|
import Clipboard from '~/components/svg/Clipboard';
|
||||||
import CheckMark from '~/components/svg/CheckMark';
|
import CheckMark from '~/components/svg/CheckMark';
|
||||||
import useLocalize from '~/hooks/useLocalize';
|
import useLocalize from '~/hooks/useLocalize';
|
||||||
|
|
||||||
type CodeBarProps = {
|
|
||||||
lang: string;
|
|
||||||
codeRef: RefObject<HTMLElement>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type CodeBlockProps = Pick<CodeBarProps, 'lang'> & {
|
|
||||||
codeChildren: React.ReactNode;
|
|
||||||
classProp?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const CodeBlock: React.FC<CodeBlockProps> = ({ lang, codeChildren, classProp = '' }) => {
|
|
||||||
const codeRef = useRef<HTMLElement>(null);
|
|
||||||
return (
|
|
||||||
<div className="w-full rounded-md bg-gray-900 text-xs text-white/80">
|
|
||||||
<div className={cn(classProp, 'overflow-y-auto p-4')}>
|
|
||||||
<code ref={codeRef} className={`hljs language-${lang} !whitespace-pre`}>
|
|
||||||
{codeChildren}
|
|
||||||
</code>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
type TCodeProps = {
|
type TCodeProps = {
|
||||||
inline: boolean;
|
inline: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|
@ -49,41 +26,38 @@ export const code: React.ElementType = memo(({ inline, className, children }: TC
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <CodeBlock lang={lang ?? 'text'} codeChildren={children} />;
|
return <code className={`hljs language-${lang} !whitespace-pre`}>{children}</code>;
|
||||||
});
|
});
|
||||||
|
|
||||||
const cursor = ' ';
|
export const CodeMarkdown = memo(({ content = '' }: { content: string }) => {
|
||||||
export const CodeMarkdown = memo(
|
const currentContent = content;
|
||||||
({ content = '', showCursor }: { content: string; showCursor?: boolean }) => {
|
const rehypePlugins = [
|
||||||
const currentContent = content;
|
[rehypeKatex, { output: 'mathml' }],
|
||||||
const rehypePlugins = [
|
[
|
||||||
[rehypeKatex, { output: 'mathml' }],
|
rehypeHighlight,
|
||||||
[
|
{
|
||||||
rehypeHighlight,
|
detect: true,
|
||||||
{
|
ignoreMissing: true,
|
||||||
detect: true,
|
subset: langSubset,
|
||||||
ignoreMissing: true,
|
},
|
||||||
subset: langSubset,
|
],
|
||||||
},
|
];
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
/* @ts-ignore */
|
/* @ts-ignore */
|
||||||
rehypePlugins={rehypePlugins}
|
rehypePlugins={rehypePlugins}
|
||||||
// linkTarget="_new"
|
// linkTarget="_new"
|
||||||
components={
|
components={
|
||||||
{ code } as {
|
{ code } as {
|
||||||
[key: string]: React.ElementType;
|
[key: string]: React.ElementType;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
>
|
}
|
||||||
{showCursor === true ? currentContent + cursor : currentContent}
|
>
|
||||||
</ReactMarkdown>
|
{currentContent}
|
||||||
);
|
</ReactMarkdown>
|
||||||
},
|
);
|
||||||
);
|
});
|
||||||
|
|
||||||
export const CopyCodeButton: React.FC<{ content: string }> = ({ content }) => {
|
export const CopyCodeButton: React.FC<{ content: string }> = ({ content }) => {
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
|
|
|
||||||
30
client/src/hooks/Artifacts/useAutoScroll.ts
Normal file
30
client/src/hooks/Artifacts/useAutoScroll.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { useState, useRef, useCallback, useEffect } from 'react';
|
||||||
|
import { useChatContext } from '~/Providers';
|
||||||
|
|
||||||
|
export default function useAutoScroll() {
|
||||||
|
const { isSubmitting } = useChatContext();
|
||||||
|
const [showScrollButton, setShowScrollButton] = useState(false);
|
||||||
|
const scrollableRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
const contentEndRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
|
const scrollToBottom = useCallback(() => {
|
||||||
|
if (scrollableRef.current) {
|
||||||
|
scrollableRef.current.scrollTop = scrollableRef.current.scrollHeight;
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleScroll = useCallback(() => {
|
||||||
|
if (scrollableRef.current) {
|
||||||
|
const { scrollTop, scrollHeight, clientHeight } = scrollableRef.current;
|
||||||
|
setShowScrollButton(scrollHeight - scrollTop - clientHeight > 100);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isSubmitting) {
|
||||||
|
scrollToBottom();
|
||||||
|
}
|
||||||
|
}, [isSubmitting, scrollToBottom]);
|
||||||
|
|
||||||
|
return { scrollableRef, contentEndRef, handleScroll, scrollToBottom, showScrollButton };
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue