"use client"; import type { CommercialAction } from "@/data/schemas/chat"; import { CommercialActionCard } from "./commercial-action-card"; import { ImageBubble } from "./image-bubble"; import { LockedImageMessageCard } from "./locked-image-message-card"; import { PrivateMessageCard } from "./private-message-card"; import { TextBubble } from "./text-bubble"; import { VoiceBubble } from "./voice-bubble"; import styles from "./chat-area.module.css"; export interface MessageContentProps { characterId: string; displayMessageId: string; remoteMessageId?: string; content: string; imageUrl?: string | null; imagePaywalled?: boolean; audioUrl?: string | null; isFromAI: boolean; locked?: boolean | null; lockReason?: string | null; lockedPrivate?: boolean | null; privateMessageHint?: string | null; commercialAction?: CommercialAction | null; isUnlockingMessage?: boolean; onUnlockPrivateMessage?: ChatMessageAction; onUnlockVoiceMessage?: ChatMessageAction; onUnlockImageMessage?: ChatMessageAction; onOpenImage?: (displayMessageId: string) => void; onCommercialAction?: (action: CommercialAction) => void; onCommercialActionDismiss?: (action: CommercialAction) => void; } type ChatMessageAction = ( displayMessageId: string, remoteMessageId?: string, ) => void; const IMAGE_PLACEHOLDER = "[图片]"; export function MessageContent({ characterId, displayMessageId, remoteMessageId, content, imageUrl, imagePaywalled, audioUrl, isFromAI, locked, lockReason, lockedPrivate, privateMessageHint, commercialAction, isUnlockingMessage, onUnlockPrivateMessage, onUnlockVoiceMessage, onUnlockImageMessage, onOpenImage, onCommercialAction, onCommercialActionDismiss, }: MessageContentProps) { const hasImage = imageUrl != null && imageUrl.length > 0; const hasAudio = audioUrl != null && audioUrl.length > 0; const hasText = content.length > 0 && content !== IMAGE_PLACEHOLDER; const isLockedPrivateMessage = lockedPrivate === true || (locked === true && lockReason === "private_message"); const isLockedVoiceMessage = locked === true && lockReason === "voice_message"; const isLockedImageMessage = locked === true && (lockReason === "image_paywall" || lockReason === "image"); const shouldRenderVoiceMessage = hasAudio || isLockedVoiceMessage; const handleUnlockPrivateMessage = onUnlockPrivateMessage ? () => onUnlockPrivateMessage(displayMessageId, remoteMessageId) : undefined; const handleUnlockVoiceMessage = isLockedVoiceMessage && onUnlockVoiceMessage ? () => onUnlockVoiceMessage(displayMessageId, remoteMessageId) : undefined; const handleUnlockImageMessage = isLockedImageMessage && onUnlockImageMessage ? () => onUnlockImageMessage(displayMessageId, remoteMessageId) : undefined; return (
{isLockedPrivateMessage ? ( ) : isLockedImageMessage && !hasImage ? ( ) : ( <> {hasImage && imageUrl && ( )} {shouldRenderVoiceMessage ? ( ) : null} {hasText && !shouldRenderVoiceMessage ? ( ) : null} )} {isFromAI && commercialAction ? ( ) : null}
); }