Files
cozsweet-frontend-nextjs/src/app/chat/components/message-content.tsx
T

83 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
/**
* MessageContent 消息内容容器
*
* 决定渲染 ImageBubble 还是 TextBubble
* - 有 imageUrl:渲染 ImageBubble(图片)
* - 有 content 且非 "[图片]" 占位符:渲染 TextBubble(文字)
* - 两者都有:图片在上,文字在下
*/
import { ImageBubble } from "./image-bubble";
import { PrivateMessageCard } from "./private-message-card";
import { TextBubble } from "./text-bubble";
export interface MessageContentProps {
messageId?: string;
content: string;
imageUrl?: string | null;
imagePaywalled?: boolean;
isFromAI: boolean;
privateLocked?: boolean | null;
privateHint?: string | null;
isUnlockingPrivate?: boolean;
onUnlockPrivateMessage?: (messageId: string) => void;
onUnlockImagePaywall?: () => void;
}
const IMAGE_PLACEHOLDER = "[图片]";
export function MessageContent({
messageId,
content,
imageUrl,
imagePaywalled,
isFromAI,
privateLocked,
privateHint,
isUnlockingPrivate = false,
onUnlockPrivateMessage,
onUnlockImagePaywall,
}: MessageContentProps) {
const hasImage = imageUrl != null && imageUrl.length > 0;
const hasText = content.length > 0 && content !== IMAGE_PLACEHOLDER;
const isLockedPrivateMessage = privateLocked === true;
return (
<div
style={{
display: "flex",
flexDirection: "column",
// 关键:在 row flex 父中撑开(不依赖 content 循环)—— 让 TextBubble 能拿到真实宽度
flex: "1 1 0",
// 防超长 content(图片 / 超长 url)撑爆父
minWidth: 0,
alignItems: isFromAI ? "flex-start" : "flex-end",
gap: 8,
}}
>
{isLockedPrivateMessage ? (
<PrivateMessageCard
hint={privateHint}
isUnlocking={isUnlockingPrivate}
onUnlock={
messageId
? () => onUnlockPrivateMessage?.(messageId)
: undefined
}
/>
) : (
<>
{hasImage && imageUrl && (
<ImageBubble
imageUrl={imageUrl}
imagePaywalled={imagePaywalled}
onUnlockImagePaywall={onUnlockImagePaywall}
/>
)}
{hasText && <TextBubble content={content} isFromAI={isFromAI} />}
</>
)}
</div>
);
}