Просмотр исходного кода

feature(frontend): improve chat overflow handling and syntax highlighting (#1402)

* improve overflow handling and syntax highlighting

* add reference to gh page
sp.wack 1 год назад
Родитель
Сommit
d8386366d9

+ 4 - 3
frontend/src/components/ChatInterface.tsx

@@ -12,6 +12,7 @@ import {
 import { Message } from "#/state/chatSlice";
 import { RootState } from "#/store";
 import ChatInput from "./ChatInput";
+import { code } from "./markdown/code";
 
 interface IChatBubbleProps {
   msg: Message;
@@ -57,10 +58,10 @@ function ChatBubble({ msg }: IChatBubbleProps): JSX.Element {
         className={`flex mb-0 min-w-0 ${msg?.sender === "user" && "flex-row-reverse ml-auto"}`}
       >
         <div
-          className={`${msg?.sender === "user" ? "bg-neutral-700" : "bg-neutral-500"} rounded-lg`}
+          className={`overflow-y-auto ${msg?.sender === "user" ? "bg-neutral-700" : "bg-neutral-500"} rounded-lg`}
         >
           <div className="p-3 prose prose-invert text-white">
-            <Markdown>{msg?.content}</Markdown>
+            <Markdown components={{ code }}>{msg?.content}</Markdown>
           </div>
         </div>
       </div>
@@ -102,7 +103,7 @@ function MessageList(): JSX.Element {
 
   return (
     <div className="flex-1 flex flex-col gap-3 pt-3 px-3 relative min-h-0">
-      <div className="overflow-y-auto flex flex-col h-full gap-3">
+      <div className="flex overflow-x-auto flex-col h-full gap-3">
         {newChatSequence.map((msg, index) => (
           <ChatBubble key={index} msg={msg} />
         ))}

+ 28 - 0
frontend/src/components/markdown/code.tsx

@@ -0,0 +1,28 @@
+import React from "react";
+import { ExtraProps } from "react-markdown";
+import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
+import { vscDarkPlus } from "react-syntax-highlighter/dist/esm/styles/prism";
+
+// See https://github.com/remarkjs/react-markdown?tab=readme-ov-file#use-custom-components-syntax-highlight
+
+/**
+ * Component to render code blocks in markdown.
+ */
+export function code({
+  children,
+  className,
+}: React.ClassAttributes<HTMLElement> &
+  React.HTMLAttributes<HTMLElement> &
+  ExtraProps) {
+  const match = /language-(\w+)/.exec(className || ""); // get the language
+
+  if (!match) {
+    return <code className={className}>{children}</code>;
+  }
+
+  return (
+    <SyntaxHighlighter style={vscDarkPlus} language={match?.[1]} PreTag="div">
+      {String(children).replace(/\n$/, "")}
+    </SyntaxHighlighter>
+  );
+}