@@ -0,0 +1,26 @@ +import DsMarkdown, { ConfigProvider } from 'ds-markdown' + +import { ruRU } from './ds-markdown-locale' + +interface DsMarkdownContentProps { + content: string + streaming: boolean +} + +const STREAMING_INTERVAL = 20 + +export function DsMarkdownContent({ content, streaming }: DsMarkdownContentProps) { + return ( + + + {content} + + + ) +} @@ -0,0 +1,22 @@ +export const ruRU = { + codeBlock: { + copy: 'Копировать', + copied: 'Скопировано', + download: 'Скачать', + downloaded: 'Скачано', + }, + mermaid: { + diagram: 'Диаграмма', + code: 'Код', + zoomOut: 'Уменьшить', + zoomIn: 'Увеличить', + download: 'Скачать', + fullScreen: 'На весь экран', + exitFullScreen: 'Выйти из полноэкранного режима', + downloadImage: 'Скачать изображение', + downloadedImage: 'Скачано', + copyImage: 'Копировать изображение', + copiedImage: 'Скопировано', + fitInView: 'По размеру страницы', + }, +} as const @@ -3,35 +3,40 @@ overflow-wrap: anywhere; word-break: break-word; - p, - li, - h1, - h2, - h3, - h4, - h5, - h6, - blockquote { + :global(.ds-markdown) { + background-color: transparent !important; + color: inherit; + font-size: inherit; + line-height: inherit; + min-height: 0; + padding: 0; + } + + :global(.ds-markdown) p, + :global(.ds-markdown) li, + :global(.ds-markdown) h1, + :global(.ds-markdown) h2, + :global(.ds-markdown) h3, + :global(.ds-markdown) h4, + :global(.ds-markdown) h5, + :global(.ds-markdown) h6, + :global(.ds-markdown) blockquote { overflow-wrap: anywhere; word-break: break-word; } - table { + :global(.ds-markdown) table { display: block; max-width: 100%; overflow-x: auto; } - pre { + :global(.ds-markdown) pre { max-width: 100%; - white-space: pre-wrap; - word-break: break-word; - overflow-x: hidden; } -} -.inlineCode { - border-radius: 15px; - white-space: pre-wrap; - word-break: break-word; + :global(.md-code-block-banner) :global(.ds-button) { + font-family: 'Inter', sans-serif; + font-weight: 500; + } } @@ -1,49 +1,25 @@ -import React from 'react' -import ReactMarkdown from 'react-markdown' import dynamic from 'next/dynamic' -import remarkGfm from 'remark-gfm' import styles from './markdown.module.scss' +const DsMarkdownContent = dynamic(() => import('./ds-markdown-content').then((mod) => mod.DsMarkdownContent), { + ssr: false, +}) + interface IProps { id?: string content: string + streaming?: boolean } -export const Markdown = ({ content, id = 'markdown'}: IProps) => { - const LazyCode = dynamic(() => import('#/widgets/chat-gpt-field/ui/code')) +export const Markdown = ({ content, id = 'markdown', streaming = false }: IProps) => { + if (!content) { + return null + } return (
- - - {children} - - - ) : ( - <> - - {children} - - - ) - }, - }} - > - {content} - +
) } @@ -130,7 +130,7 @@ export function BotMessage(props: any) { position: 'relative', padding: '15px 23px', border: `1px solid #303035`, - color: '#A6A5A5', + color: '#f9fafb', boxShadow: 'none', lineHeight: '22.5px', fontSize: '15px', @@ -157,7 +157,10 @@ export function BotMessage(props: any) { ) : ( '' )} - + = memo( <>{desktop && modelType !== 'deepl' && } ) : ( messageResponse?.map((message, idx) => { + const isStreaming = + loading && + message.from_model && + message.uid.startsWith('streaming:') && + idx === messageResponse.length - 1 + return ( = memo( modelTitle={modelTitle} deleteMessage={deleteMessage} device={device} + isStreaming={isStreaming} /> ) }) @@ -19,6 +19,7 @@ interface IProps { device: 'mobile' | 'desktop' setResendValue: (value: string) => void onLoadImage?: (event: React.ChangeEvent | null, file?: File) => void + isStreaming?: boolean } export const IsNextDay = memo( @@ -35,6 +36,7 @@ export const IsNextDay = memo( modelType, device, setResendValue, + isStreaming, }: IProps) => { if (messageResponse && message.created_at) { const date = getDateFromString(message.created_at) @@ -72,6 +74,7 @@ export const IsNextDay = memo( isNewMessage={isNewMessage} modelType={modelType} device={device} + isStreaming={isStreaming} /> ) @@ -108,6 +111,7 @@ export const IsNextDay = memo( isNewMessage={isNewMessage} modelType={modelType} device={device} + isStreaming={isStreaming} /> ) @@ -126,6 +130,7 @@ export const IsNextDay = memo( isNewMessage={isNewMessage} modelType={modelType} device={device} + isStreaming={isStreaming} /> ) } @@ -26,6 +26,7 @@ interface IMessagesList { modelTitle: string | undefined setResendValue: (value: string) => void onLoadImage?: (event: React.ChangeEvent | null, file?: File) => void + isStreaming?: boolean } export const UserMessage = React.memo(function UserMessage({ setCurrentSrc, setModal, ...props }: IMessagesList) { @@ -828,6 +829,7 @@ export const UserMessage = React.memo(function UserMessage({ setCurrentSrc, setM message={props.message} desktop={desktop} modelType={props.modelType} + isStreaming={props.isStreaming} /> )} @@ -1,3 +1 @@ -.inlineCode { - border-radius: 15px; -} + @@ -54,6 +54,7 @@ "cookie": "^0.5.0", "cross-env": "^7.0.3", "dayjs": "^1.11.8", + "ds-markdown": "^1.2.0", "eslint-plugin-simple-import-sort": "^10.0.0", "framer-motion": "^12.23.12", "i18next": "^23.4.1", @@ -3991,6 +3991,13 @@ __metadata: languageName: node linkType: hard +"@types/katex@npm:^0.16.0": + version: 0.16.8 + resolution: "@types/katex@npm:0.16.8" + checksum: 10c0/0661609353f4f5e62bd2dc78da99e842761c6474b19f2268b195bbe9dbf20e6f766a31155d79eec2e7c3eff4e7eba4b30f4f519e9c6a11c75bb45e257a2ddb69 + languageName: node + linkType: hard + "@types/lodash.debounce@npm:^4.0.9": version: 4.0.9 resolution: "@types/lodash.debounce@npm:4.0.9" @@ -5260,6 +5267,13 @@ __metadata: languageName: node linkType: hard +"classnames@npm:^2.5.1": + version: 2.5.1 + resolution: "classnames@npm:2.5.1" + checksum: 10c0/afff4f77e62cea2d79c39962980bf316bacb0d7c49e13a21adaadb9221e1c6b9d3cdb829d8bb1b23c406f4e740507f37e1dcf506f7e3b7113d17c5bab787aa69 + languageName: node + linkType: hard + "cli-cursor@npm:^5.0.0": version: 5.0.0 resolution: "cli-cursor@npm:5.0.0" @@ -5378,6 +5392,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:^8.3.0": + version: 8.3.0 + resolution: "commander@npm:8.3.0" + checksum: 10c0/8b043bb8322ea1c39664a1598a95e0495bfe4ca2fad0d84a92d7d1d8d213e2a155b441d2470c8e08de7c4a28cf2bc6e169211c49e1b21d9f7edc6ae4d9356060 + languageName: node + linkType: hard + "commondir@npm:^1.0.1": version: 1.0.1 resolution: "commondir@npm:1.0.1" @@ -5924,6 +5945,27 @@ __metadata: languageName: node linkType: hard +"ds-markdown@npm:^1.2.0": + version: 1.2.0 + resolution: "ds-markdown@npm:1.2.0" + dependencies: + classnames: "npm:^2.5.1" + katex: "npm:^0.16.22" + react-markdown: "npm:^10.1.0" + react-markdown-typer: "npm:1.0.5" + react-syntax-highlighter: "npm:^15.6.1" + rehype-katex: "npm:^7.0.1" + remark-gfm: "npm:^4.0.1" + remark-math: "npm:^6.0.0" + unified: "npm:^11.0.5" + unist-util-visit: "npm:^5.0.0" + peerDependencies: + react: ">=18.0.0" + react-dom: ">=18.0.0" + checksum: 10c0/100d53f26be8d2260681e167a7616d68e685de0541599fa06ec55c5d6c00be305f5f5cc8d380f867026966d5c10d6a5f7b18ab2e487a06c215af25d6c9bc7bb1 + languageName: node + linkType: hard + "dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1": version: 1.0.1 resolution: "dunder-proto@npm:1.0.1" @@ -7141,6 +7183,68 @@ __metadata: languageName: node linkType: hard +"hast-util-from-dom@npm:^5.0.0": + version: 5.0.1 + resolution: "hast-util-from-dom@npm:5.0.1" + dependencies: + "@types/hast": "npm:^3.0.0" + hastscript: "npm:^9.0.0" + web-namespaces: "npm:^2.0.0" + checksum: 10c0/9a90381e048107a093a3da758bb17b67aaf5322e222f02497f841c4990abf94aa177d38d5b9bf61ad07b3601d0409f34f5b556d89578cc189230c6b994d2af77 + languageName: node + linkType: hard + +"hast-util-from-html-isomorphic@npm:^2.0.0": + version: 2.0.0 + resolution: "hast-util-from-html-isomorphic@npm:2.0.0" + dependencies: + "@types/hast": "npm:^3.0.0" + hast-util-from-dom: "npm:^5.0.0" + hast-util-from-html: "npm:^2.0.0" + unist-util-remove-position: "npm:^5.0.0" + checksum: 10c0/fc68d9245e794483a802d5c85a9f6c25959e00db78cc796411efc965134f3206f9cc9fa38134572ea781ad74663e801f1f83202007b208e27a770855566a62b6 + languageName: node + linkType: hard + +"hast-util-from-html@npm:^2.0.0": + version: 2.0.3 + resolution: "hast-util-from-html@npm:2.0.3" + dependencies: + "@types/hast": "npm:^3.0.0" + devlop: "npm:^1.1.0" + hast-util-from-parse5: "npm:^8.0.0" + parse5: "npm:^7.0.0" + vfile: "npm:^6.0.0" + vfile-message: "npm:^4.0.0" + checksum: 10c0/993ef707c1a12474c8d4094fc9706a72826c660a7e308ea54c50ad893353d32e139b7cbc67510c2e82feac572b320e3b05aeb13d0f9c6302d61261f337b46764 + languageName: node + linkType: hard + +"hast-util-from-parse5@npm:^8.0.0": + version: 8.0.3 + resolution: "hast-util-from-parse5@npm:8.0.3" + dependencies: + "@types/hast": "npm:^3.0.0" + "@types/unist": "npm:^3.0.0" + devlop: "npm:^1.0.0" + hastscript: "npm:^9.0.0" + property-information: "npm:^7.0.0" + vfile: "npm:^6.0.0" + vfile-location: "npm:^5.0.0" + web-namespaces: "npm:^2.0.0" + checksum: 10c0/40ace6c0ad43c26f721c7499fe408e639cde917b2350c9299635e6326559855896dae3c3ebf7440df54766b96c4276a7823e8f376a2b6a28b37b591f03412545 + languageName: node + linkType: hard + +"hast-util-is-element@npm:^3.0.0": + version: 3.0.0 + resolution: "hast-util-is-element@npm:3.0.0" + dependencies: + "@types/hast": "npm:^3.0.0" + checksum: 10c0/f5361e4c9859c587ca8eb0d8343492f3077ccaa0f58a44cd09f35d5038f94d65152288dcd0c19336ef2c9491ec4d4e45fde2176b05293437021570aa0bc3613b + languageName: node + linkType: hard + "hast-util-parse-selector@npm:^2.0.0": version: 2.2.5 resolution: "hast-util-parse-selector@npm:2.2.5" @@ -7148,6 +7252,15 @@ __metadata: languageName: node linkType: hard +"hast-util-parse-selector@npm:^4.0.0": + version: 4.0.0 + resolution: "hast-util-parse-selector@npm:4.0.0" + dependencies: + "@types/hast": "npm:^3.0.0" + checksum: 10c0/5e98168cb44470dc274aabf1a28317e4feb09b1eaf7a48bbaa8c1de1b43a89cd195cb1284e535698e658e3ec26ad91bc5e52c9563c36feb75abbc68aaf68fb9f + languageName: node + linkType: hard + "hast-util-to-jsx-runtime@npm:^2.0.0": version: 2.3.6 resolution: "hast-util-to-jsx-runtime@npm:2.3.6" @@ -7171,6 +7284,18 @@ __metadata: languageName: node linkType: hard +"hast-util-to-text@npm:^4.0.0": + version: 4.0.2 + resolution: "hast-util-to-text@npm:4.0.2" + dependencies: + "@types/hast": "npm:^3.0.0" + "@types/unist": "npm:^3.0.0" + hast-util-is-element: "npm:^3.0.0" + unist-util-find-after: "npm:^5.0.0" + checksum: 10c0/93ecc10e68fe5391c6e634140eb330942e71dea2724c8e0c647c73ed74a8ec930a4b77043b5081284808c96f73f2bee64ee416038ece75a63a467e8d14f09946 + languageName: node + linkType: hard + "hast-util-whitespace@npm:^3.0.0": version: 3.0.0 resolution: "hast-util-whitespace@npm:3.0.0" @@ -7193,6 +7318,19 @@ __metadata: languageName: node linkType: hard +"hastscript@npm:^9.0.0": + version: 9.0.1 + resolution: "hastscript@npm:9.0.1" + dependencies: + "@types/hast": "npm:^3.0.0" + comma-separated-tokens: "npm:^2.0.0" + hast-util-parse-selector: "npm:^4.0.0" + property-information: "npm:^7.0.0" + space-separated-tokens: "npm:^2.0.0" + checksum: 10c0/18dc8064e5c3a7a2ae862978e626b97a254e1c8a67ee9d0c9f06d373bba155ed805fc5b5ce21b990fb7bc174624889e5e1ce1cade264f1b1d58b48f994bc85ce + languageName: node + linkType: hard + "hermes-estree@npm:0.25.1": version: 0.25.1 resolution: "hermes-estree@npm:0.25.1" @@ -8558,6 +8696,17 @@ __metadata: languageName: node linkType: hard +"katex@npm:^0.16.0, katex@npm:^0.16.22": + version: 0.16.47 + resolution: "katex@npm:0.16.47" + dependencies: + commander: "npm:^8.3.0" + bin: + katex: cli.js + checksum: 10c0/b10f4d0651c60771a48444879e4227255e26e2b2ec061b1ee4b08934863ad2324ba8dbb772455f7768aeb14dfcc13bcd309174a0ddd5ef954a607f644a197710 + languageName: node + linkType: hard + "keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -8928,6 +9077,21 @@ __metadata: languageName: node linkType: hard +"mdast-util-math@npm:^3.0.0": + version: 3.0.0 + resolution: "mdast-util-math@npm:3.0.0" + dependencies: + "@types/hast": "npm:^3.0.0" + "@types/mdast": "npm:^4.0.0" + devlop: "npm:^1.0.0" + longest-streak: "npm:^3.0.0" + mdast-util-from-markdown: "npm:^2.0.0" + mdast-util-to-markdown: "npm:^2.1.0" + unist-util-remove-position: "npm:^5.0.0" + checksum: 10c0/d4e839e38719f26872ed78aac18339805a892f1b56585a9cb8668f34e221b4f0660b9dfe49ec96dbbe79fd1b63b648608a64046d8286bcd2f9d576e80b48a0a1 + languageName: node + linkType: hard + "mdast-util-mdx-expression@npm:^2.0.0": version: 2.0.1 resolution: "mdast-util-mdx-expression@npm:2.0.1" @@ -9003,7 +9167,7 @@ __metadata: languageName: node linkType: hard -"mdast-util-to-markdown@npm:^2.0.0": +"mdast-util-to-markdown@npm:^2.0.0, mdast-util-to-markdown@npm:^2.1.0": version: 2.1.2 resolution: "mdast-util-to-markdown@npm:2.1.2" dependencies: @@ -9174,6 +9338,21 @@ __metadata: languageName: node linkType: hard +"micromark-extension-math@npm:^3.0.0": + version: 3.1.0 + resolution: "micromark-extension-math@npm:3.1.0" + dependencies: + "@types/katex": "npm:^0.16.0" + devlop: "npm:^1.0.0" + katex: "npm:^0.16.0" + micromark-factory-space: "npm:^2.0.0" + micromark-util-character: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + checksum: 10c0/56e6f2185a4613f9d47e7e98cf8605851c990957d9229c942b005e286c8087b61dc9149448d38b2f8be6d42cc6a64aad7e1f2778ddd86fbbb1a2f48a3ca1872f + languageName: node + linkType: hard + "micromark-factory-destination@npm:^2.0.0": version: 2.0.1 resolution: "micromark-factory-destination@npm:2.0.1" @@ -10512,6 +10691,18 @@ __metadata: languageName: node linkType: hard +"react-markdown-typer@npm:1.0.5": + version: 1.0.5 + resolution: "react-markdown-typer@npm:1.0.5" + dependencies: + react-markdown: "npm:^10.1.0" + peerDependencies: + react: ">=18.0.0" + react-dom: ">=18.0.0" + checksum: 10c0/d8577b917ff425fff76fcb0f5928cab26a80ca8caf6384a743d28e706818763a32ad3bd192ff82558696814a459924759e55322f0d5f8951aa3f31f5c90839ec + languageName: node + linkType: hard + "react-markdown@npm:^10.1.0": version: 10.1.0 resolution: "react-markdown@npm:10.1.0" @@ -10553,7 +10744,7 @@ __metadata: languageName: node linkType: hard -"react-syntax-highlighter@npm:^15.5.0": +"react-syntax-highlighter@npm:^15.5.0, react-syntax-highlighter@npm:^15.6.1": version: 15.6.6 resolution: "react-syntax-highlighter@npm:15.6.6" dependencies: @@ -10713,6 +10904,21 @@ __metadata: languageName: node linkType: hard +"rehype-katex@npm:^7.0.1": + version: 7.0.1 + resolution: "rehype-katex@npm:7.0.1" + dependencies: + "@types/hast": "npm:^3.0.0" + "@types/katex": "npm:^0.16.0" + hast-util-from-html-isomorphic: "npm:^2.0.0" + hast-util-to-text: "npm:^4.0.0" + katex: "npm:^0.16.0" + unist-util-visit-parents: "npm:^6.0.0" + vfile: "npm:^6.0.0" + checksum: 10c0/73c770319536128b75055d904d06951789d00a0552c11724c0dac2e244dcb21041630552d118a11cc42233fdcd1bfee525e78a0020fde635bd916cceb281dfb1 + languageName: node + linkType: hard + "remark-gfm@npm:^4.0.1": version: 4.0.1 resolution: "remark-gfm@npm:4.0.1" @@ -10727,6 +10933,18 @@ __metadata: languageName: node linkType: hard +"remark-math@npm:^6.0.0": + version: 6.0.0 + resolution: "remark-math@npm:6.0.0" + dependencies: + "@types/mdast": "npm:^4.0.0" + mdast-util-math: "npm:^3.0.0" + micromark-extension-math: "npm:^3.0.0" + unified: "npm:^11.0.0" + checksum: 10c0/859613c4db194bb6b3c9c063661dc52b8ceda9c5cf3256b42f73d93eb8f38a6d634eb5f976fe094425f6f1035aaf329eb49ada314feb3b2b1073326b6d3aaa02 + languageName: node + linkType: hard + "remark-parse@npm:^11.0.0": version: 11.0.0 resolution: "remark-parse@npm:11.0.0" @@ -12127,6 +12345,7 @@ __metadata: cross-env: "npm:^7.0.3" cross-fetch: "npm:^4.1.0" dayjs: "npm:^1.11.8" + ds-markdown: "npm:^1.2.0" eslint: "npm:^9.39.4" eslint-config-next: "npm:^16.0.0" eslint-config-prettier: "npm:^10.1.0" @@ -12234,7 +12453,7 @@ __metadata: languageName: node linkType: hard -"unified@npm:^11.0.0": +"unified@npm:^11.0.0, unified@npm:^11.0.5": version: 11.0.5 resolution: "unified@npm:11.0.5" dependencies: @@ -12249,6 +12468,16 @@ __metadata: languageName: node linkType: hard +"unist-util-find-after@npm:^5.0.0": + version: 5.0.0 + resolution: "unist-util-find-after@npm:5.0.0" + dependencies: + "@types/unist": "npm:^3.0.0" + unist-util-is: "npm:^6.0.0" + checksum: 10c0/a7cea473c4384df8de867c456b797ff1221b20f822e1af673ff5812ed505358b36f47f3b084ac14c3622cb879ed833b71b288e8aa71025352a2aab4c2925a6eb + languageName: node + linkType: hard + "unist-util-is@npm:^6.0.0": version: 6.0.1 resolution: "unist-util-is@npm:6.0.1" @@ -12267,6 +12496,16 @@ __metadata: languageName: node linkType: hard +"unist-util-remove-position@npm:^5.0.0": + version: 5.0.0 + resolution: "unist-util-remove-position@npm:5.0.0" + dependencies: + "@types/unist": "npm:^3.0.0" + unist-util-visit: "npm:^5.0.0" + checksum: 10c0/e8c76da4399446b3da2d1c84a97c607b37d03d1d92561e14838cbe4fdcb485bfc06c06cfadbb808ccb72105a80643976d0660d1fe222ca372203075be9d71105 + languageName: node + linkType: hard + "unist-util-stringify-position@npm:^4.0.0": version: 4.0.0 resolution: "unist-util-stringify-position@npm:4.0.0" @@ -12479,6 +12718,16 @@ __metadata: languageName: node linkType: hard +"vfile-location@npm:^5.0.0": + version: 5.0.3 + resolution: "vfile-location@npm:5.0.3" + dependencies: + "@types/unist": "npm:^3.0.0" + vfile: "npm:^6.0.0" + checksum: 10c0/1711f67802a5bc175ea69750d59863343ed43d1b1bb25c0a9063e4c70595e673e53e2ed5cdbb6dcdc370059b31605144d95e8c061b9361bcc2b036b8f63a4966 + languageName: node + linkType: hard + "vfile-message@npm:^4.0.0": version: 4.0.3 resolution: "vfile-message@npm:4.0.3" @@ -12524,6 +12773,13 @@ __metadata: languageName: node linkType: hard +"web-namespaces@npm:^2.0.0": + version: 2.0.1 + resolution: "web-namespaces@npm:2.0.1" + checksum: 10c0/df245f466ad83bd5cd80bfffc1674c7f64b7b84d1de0e4d2c0934fb0782e0a599164e7197a4bce310ee3342fd61817b8047ff04f076a1ce12dd470584142a4bd + languageName: node + linkType: hard + "webidl-conversions@npm:^3.0.0": version: 3.0.1 resolution: "webidl-conversions@npm:3.0.1"