From 9c2d012261f6f5dff3358315fec906f2e88821c7 Mon Sep 17 00:00:00 2001 From: pyschonoice Date: Thu, 28 Aug 2025 18:09:41 +0530 Subject: [PATCH] fix: improve chat message ui --- frontend/bun.lock | 11 ++++++ frontend/components/ui/ui-input.tsx | 57 +++++++++++++++++++++-------- frontend/lib/markdown.ts | 33 +++++++++++++++++ frontend/package.json | 4 ++ 4 files changed, 90 insertions(+), 15 deletions(-) create mode 100644 frontend/lib/markdown.ts diff --git a/frontend/bun.lock b/frontend/bun.lock index 6c2ff42a..ac026622 100644 --- a/frontend/bun.lock +++ b/frontend/bun.lock @@ -39,6 +39,7 @@ "clsx": "^2.1.1", "cmdk": "^1.1.1", "framer-motion": "^12.16.0", + "input-otp": "^1.4.2", "lucide-react": "^0.514.0", "next": "^15.2.3", "next-auth": "5.0.0-beta.25", @@ -59,11 +60,15 @@ "react-turnstile": "^1.1.4", "recharts": "2.15.4", "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", "server-only": "^0.0.1", "sonner": "^2.0.7", "stripe": "^18.2.1", "superjson": "^2.2.1", "tailwind-merge": "^3.3.1", + "turndown": "^7.2.1", + "unified": "^11.0.5", "zod": "^3.24.2", }, "devDependencies": { @@ -258,6 +263,8 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.30", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q=="], + "@mixmark-io/domino": ["@mixmark-io/domino@2.2.0", "", {}, "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="], "@next/env": ["@next/env@15.5.0", "", {}, "sha512-sDaprBAfzCQiOgo2pO+LhnV0Wt2wBgartjrr+dpcTORYVnnXD0gwhHhiiyIih9hQbq+JnbqH4odgcFWhqCGidw=="], @@ -1012,6 +1019,8 @@ "inline-style-parser": ["inline-style-parser@0.2.4", "", {}, "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q=="], + "input-otp": ["input-otp@1.4.2", "", { "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA=="], + "internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="], "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="], @@ -1552,6 +1561,8 @@ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "turndown": ["turndown@7.2.1", "", { "dependencies": { "@mixmark-io/domino": "^2.2.0" } }, "sha512-7YiPJw6rLClQL3oUKN3KgMaXeJJ2lAyZItclgKDurqnH61so4k4IH/qwmMva0zpuJc/FhRExBBnk7EbeFANlgQ=="], + "tw-animate-css": ["tw-animate-css@1.3.7", "", {}, "sha512-lvLb3hTIpB5oGsk8JmLoAjeCHV58nKa2zHYn8yWOoG5JJusH3bhJlF2DLAZ/5NmJ+jyH3ssiAx/2KmbhavJy/A=="], "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], diff --git a/frontend/components/ui/ui-input.tsx b/frontend/components/ui/ui-input.tsx index 9e1c0b9f..1b7f0ed0 100644 --- a/frontend/components/ui/ui-input.tsx +++ b/frontend/components/ui/ui-input.tsx @@ -15,6 +15,8 @@ import { import ReactMarkdown from "react-markdown"; import SyntaxHighlighter from "react-syntax-highlighter"; import remarkGfm from "remark-gfm"; +import remarkBreaks from "remark-breaks"; +import { processOutput } from "@/lib/markdown"; import { Geist_Mono } from "next/font/google"; import { cn } from "@/lib/utils"; import TabsSuggestion from "./tabs-suggestion"; @@ -32,6 +34,8 @@ import { useConversationContext } from "@/contexts/conversation-context"; import { useGlobalKeyPress } from "@/hooks/useGlobalKeyPress"; import { useExecutionContext } from "@/contexts/execution-context"; + + const geistMono = Geist_Mono({ subsets: ["latin"], variable: "--font-mono", @@ -356,7 +360,7 @@ const UIInput = ({ )} > ); }, + p: (props) => ( +

{props.children}

+ ), strong: (props) => ( {props.children} ), + em: (props) => ( + {props.children} + ), + del: (props) => ( + {props.children} + ), a: (props) => ( - + {props.children} ), + blockquote: (props) => ( +
{props.children}
+ ), + table: (props) => ( +
+ {props.children}
+
+ ), + thead: (props) => ( + {props.children} + ), + tr: (props) => ( + {props.children} + ), + th: (props) => ( + {props.children} + ), + td: (props) => ( + {props.children} + ), h1: (props) => ( -

- {props.children} -

+

{props.children}

), h2: (props) => ( -

- {props.children} -

+

{props.children}

), h3: (props) => ( -

- {props.children} -

+

{props.children}

+ ), + hr: () => ( +
), }} > - {message.content} + {processOutput(message.content)}
diff --git a/frontend/lib/markdown.ts b/frontend/lib/markdown.ts new file mode 100644 index 00000000..ef5b11fe --- /dev/null +++ b/frontend/lib/markdown.ts @@ -0,0 +1,33 @@ + +import { unified } from "unified"; +import remarkParse from "remark-parse"; +import remarkStringify from "remark-stringify"; +import remarkGfm from "remark-gfm"; + +export function processOutput(raw: string): string { + if (!raw) return raw; + try { + const file = unified() + .use(remarkParse) + .use(remarkGfm) + .use(remarkStringify as any) + .data("settings", { + bullet: "-", + bulletOrdered: ".", + listItemIndent: "one", + fences: true, + fence: "`", + emphasis: "_", + strong: "*", + rule: "*", + ruleRepetition: 3, + ruleSpaces: true, + setext: false, + tightDefinitions: true, + }) + .processSync(raw); + return String(file).trim(); + } catch { + return raw; + } +} \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index c07aa556..309725c1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -75,11 +75,15 @@ "react-turnstile": "^1.1.4", "recharts": "2.15.4", "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", "server-only": "^0.0.1", "sonner": "^2.0.7", "stripe": "^18.2.1", "superjson": "^2.2.1", "tailwind-merge": "^3.3.1", + "turndown": "^7.2.1", + "unified": "^11.0.5", "zod": "^3.24.2" }, "devDependencies": {