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:
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user