"use client"; import type { ChatAction, CommercialAction } from "@/data/schemas/chat"; import { ChatActionCard } from "./chat-action-card"; 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; chatAction?: ChatAction | null; isUnlockingMessage?: boolean; onUnlockPrivateMessage?: ChatMessageAction; onUnlockVoiceMessage?: ChatMessageAction; onUnlockImageMessage?: ChatMessageAction; onOpenImage?: (displayMessageId: string) => void; onCommercialAction?: (action: CommercialAction) => void; onCommercialActionDismiss?: (action: CommercialAction) => void; onChatActionViewed?: (action: ChatAction) => void; onChatAction?: (action: ChatAction) => void | Promise; onChatActionDismiss?: (action: ChatAction) => 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, chatAction, isUnlockingMessage, onUnlockPrivateMessage, onUnlockVoiceMessage, onUnlockImageMessage, onOpenImage, onCommercialAction, onCommercialActionDismiss, onChatActionViewed, onChatAction, onChatActionDismiss, }: 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 && chatAction ? ( ) : isFromAI && commercialAction ? ( ) : null}
); }