feat: P3a 代码语法高亮 (highlight.js + CodeBlock组件)

This commit is contained in:
yuzhiran-dev
2026-05-18 12:06:30 +08:00
parent 21078ae287
commit 4de042abcd
6 changed files with 112 additions and 44 deletions
+13 -1
View File
@@ -8,6 +8,7 @@ import { getToken, apiFetch } from '@/lib/auth';
import { DEFAULT_MODEL } from '@/lib/models';
import { ModelSelector } from '@/components/ui/model-selector';
import { useT } from '@/i18n';
import { CodeBlock } from '@/components/ui/code-block';
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000/api/v1';
@@ -412,7 +413,18 @@ function SandboxPage() {
<div className="w-8 h-8 bg-brand-600 rounded-xl flex items-center justify-center text-white text-sm font-bold shrink-0">Y</div>
)}
<div className={`max-w-[75%] rounded-2xl px-4 py-2.5 text-sm leading-relaxed whitespace-pre-wrap ${msg.role === 'user' ? 'bg-brand-600 text-white rounded-tr-none' : 'bg-muted text-foreground rounded-tl-none'}`}>
{msg.content}
{(() => {
const parts = msg.content.split(/(```(?:\w+)?\n[\s\S]*?```)/g)
return parts.map((part, pi) => {
const match = part.match(/^```(\w*)\n([\s\S]*)```$/)
if (match) {
const [, lang, code] = match
return <CodeBlock key={pi} code={code.trim()} language={lang || undefined} />
}
if (pi > 0 && parts[pi-1].startsWith('```')) return null
return <span key={pi} className="whitespace-pre-wrap">{part}</span>
})
})()}
</div>
{msg.role === 'user' && (
<div className="w-8 h-8 bg-muted-foreground/20 rounded-xl flex items-center justify-center text-xs font-bold shrink-0"></div>