fix: enable markdown rendering for user messages (#531)

* fix: enable markdown rendering for user messages

* fix: resolve unused parameter lint error

* fix: resolve lint errors (conditional hook and unused prop)
This commit is contained in:
Raph
2026-02-27 20:22:59 +02:00
committed by GitHub
parent b68a10571c
commit d948aa5557
@@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import type { Part } from '@opencode-ai/sdk/v2'; import type { Part } from '@opencode-ai/sdk/v2';
import type { AgentMentionInfo } from '../types'; import type { AgentMentionInfo } from '../types';
import { SimpleMarkdownRenderer } from '../../MarkdownRenderer';
type PartWithText = Part & { text?: string; content?: string; value?: string }; type PartWithText = Part & { text?: string; content?: string; value?: string };
@@ -53,10 +53,10 @@ const UserTextPart: React.FC<UserTextPartProps> = ({ part, messageId, agentMenti
} }
const styles = window.getComputedStyle(el); const styles = window.getComputedStyle(el);
const lineHeight = Number.parseFloat(styles.lineHeight); const lineHeight = parseFloat(styles.lineHeight);
const fontSize = Number.parseFloat(styles.fontSize); const fontSize = parseFloat(styles.fontSize);
const fallbackLineHeight = Number.isFinite(fontSize) ? fontSize * 1.4 : 20; const fallbackLineHeight = isFinite(fontSize) ? fontSize * 1.4 : 20;
const resolvedLineHeight = Number.isFinite(lineHeight) ? lineHeight : fallbackLineHeight; const resolvedLineHeight = isFinite(lineHeight) ? lineHeight : fallbackLineHeight;
setCollapseZoneHeight(Math.max(1, Math.round(resolvedLineHeight * CLAMP_LINES))); setCollapseZoneHeight(Math.max(1, Math.round(resolvedLineHeight * CLAMP_LINES)));
}; };
@@ -91,47 +91,34 @@ const UserTextPart: React.FC<UserTextPartProps> = ({ part, messageId, agentMenti
} }
}, [collapseZoneHeight, hasActiveSelectionInElement, isExpanded, isTruncated]); }, [collapseZoneHeight, hasActiveSelectionInElement, isExpanded, isTruncated]);
if (!textContent || textContent.trim().length === 0) { const processedContent = React.useMemo(() => {
return null;
}
// Render content with optional agent mention link
const renderContent = () => {
if (!agentMention?.token || !textContent.includes(agentMention.token)) { if (!agentMention?.token || !textContent.includes(agentMention.token)) {
return textContent; return textContent;
} }
const idx = textContent.indexOf(agentMention.token);
const before = textContent.slice(0, idx); const mentionHtml = `<a href="${buildMentionUrl(agentMention.name)}" class="text-primary hover:underline" target="_blank" rel="noopener noreferrer">${agentMention.token}</a>`;
const after = textContent.slice(idx + agentMention.token.length); return textContent.replace(agentMention.token, mentionHtml);
return ( }, [agentMention, textContent]);
<>
{before} if (!textContent || textContent.trim().length === 0) {
<a return null;
href={buildMentionUrl(agentMention.name)} }
className="text-primary hover:underline"
target="_blank"
rel="noopener noreferrer"
onClick={(e) => e.stopPropagation()}
>
{agentMention.token}
</a>
{after}
</>
);
};
return ( return (
<div className="relative" key={part.id || `${messageId}-user-text`}> <div className="relative" key={part.id || `${messageId}-user-text`}>
<div <div
className={cn( className={cn(
"break-words whitespace-pre-wrap font-sans typography-markdown", "break-words font-sans typography-markdown",
!isExpanded && "line-clamp-2", !isExpanded && "line-clamp-2",
isTruncated && !isExpanded && "cursor-pointer" isTruncated && !isExpanded && "cursor-pointer"
)} )}
ref={textRef} ref={textRef}
onClick={handleClick} onClick={handleClick}
> >
{renderContent()} <SimpleMarkdownRenderer
content={processedContent}
disableLinkSafety
/>
</div> </div>
</div> </div>
); );