Message markdown
This commit is contained in:
Generated
+1499
-3
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -26,11 +26,13 @@
|
|||||||
"next": "15.5.0",
|
"next": "15.5.0",
|
||||||
"react": "19.1.0",
|
"react": "19.1.0",
|
||||||
"react-dom": "19.1.0",
|
"react-dom": "19.1.0",
|
||||||
|
"react-markdown": "^10.1.0",
|
||||||
|
"remark-gfm": "^4.0.1",
|
||||||
"tailwind-merge": "^3.3.1"
|
"tailwind-merge": "^3.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20.19.11",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"tailwindcss": "^4",
|
"tailwindcss": "^4",
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default async function Server(params: {
|
|||||||
{
|
{
|
||||||
id: "1",
|
id: "1",
|
||||||
authorId: "user1",
|
authorId: "user1",
|
||||||
content: "Hello, this is a test message!",
|
content: `# Test\n### Hello World\n\nThis is a **markdown** message with _various_ elements:\n\n- Item 1\n- Item 2\n- Item 3\n\n[Click here](https://example.com) for more info.\n\n1. First\n2. Second\n3. Third`,
|
||||||
channelId: "1",
|
channelId: "1",
|
||||||
timestamp: new Date(),
|
timestamp: new Date(),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,13 +13,15 @@ import {
|
|||||||
import { SmilePlusIcon } from "lucide-react";
|
import { SmilePlusIcon } from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { format, isToday, isYesterday } from "date-fns";
|
import { format, isToday, isYesterday } from "date-fns";
|
||||||
|
import ReactMarkdown from "react-markdown";
|
||||||
|
import remarkGfm from "remark-gfm";
|
||||||
|
|
||||||
function MessageContainer({ message }: { message: Message }) {
|
function MessageContainer({ message }: { message: Message }) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3 rounded-lg p-4 hover:bg-accent">
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<div className="w-8 h-8 rounded-full bg-gray-400" />
|
<div className="w-8 h-8 rounded-full bg-gray-400" />
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col flex-1">
|
||||||
<span className="font-bold flex gap-1 items-center">
|
<span className="font-bold flex gap-1 items-center">
|
||||||
{message.authorId}
|
{message.authorId}
|
||||||
|
|
||||||
@@ -32,7 +34,44 @@ function MessageContainer({ message }: { message: Message }) {
|
|||||||
</p>
|
</p>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span className="text-sm text-foreground/85">{message.content}</span>
|
<span className="text-foreground/85 flex flex-col">
|
||||||
|
{message.content.split("\n\n").map((line, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<ReactMarkdown
|
||||||
|
remarkPlugins={[remarkGfm]}
|
||||||
|
components={{
|
||||||
|
h1: ({ node, ...props }) => (
|
||||||
|
<h1 className="text-3xl font-bold my-2" {...props} />
|
||||||
|
),
|
||||||
|
h2: ({ node, ...props }) => (
|
||||||
|
<h2 className="text-2xl font-bold my-2" {...props} />
|
||||||
|
),
|
||||||
|
h3: ({ node, ...props }) => (
|
||||||
|
<h3 className="text-xl font-bold my-2" {...props} />
|
||||||
|
),
|
||||||
|
h4: ({ node, ...props }) => (
|
||||||
|
<h4 className="text-lg font-bold my-2" {...props} />
|
||||||
|
),
|
||||||
|
h5: ({ node, ...props }) => (
|
||||||
|
<h5 className="text-base font-bold my-2" {...props} />
|
||||||
|
),
|
||||||
|
ul: ({ node, ...props }) => (
|
||||||
|
<ul className="list-disc list-inside my-2" {...props} />
|
||||||
|
),
|
||||||
|
ol: ({ node, ...props }) => (
|
||||||
|
<ol
|
||||||
|
className="list-decimal list-inside my-2"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{line}
|
||||||
|
</ReactMarkdown>
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,13 +82,13 @@ export default function MessageBox({ messages }: { messages: Message[] }) {
|
|||||||
const [text, setText] = useState("");
|
const [text, setText] = useState("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-screen w-full flex flex-col p-5 gap-5">
|
<div className="h-screen w-full flex flex-col py-5 pl-5 gap-5">
|
||||||
<div className="w-full flex-1 overflow-y-scroll flex gap-2 flex-col-reverse">
|
<div className="w-full flex-1 overflow-y-scroll flex gap-2 flex-col-reverse pr-5">
|
||||||
{messages.map((msg) => (
|
{messages.map((msg) => (
|
||||||
<MessageContainer key={msg.id} message={msg} />
|
<MessageContainer key={msg.id} message={msg} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex gap-3">
|
<div className="w-full flex gap-3 pr-5">
|
||||||
<Input
|
<Input
|
||||||
className=""
|
className=""
|
||||||
placeholder="Type a message..."
|
placeholder="Type a message..."
|
||||||
|
|||||||
Reference in New Issue
Block a user