feat(chat): render commercial actions and persist greetings

This commit is contained in:
Codex
2026-07-23 14:52:34 +08:00
parent 3790fb813f
commit 05f625dd0b
26 changed files with 548 additions and 1 deletions
@@ -1,4 +1,7 @@
"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";
@@ -19,11 +22,14 @@ export interface MessageContentProps {
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 = (
@@ -46,11 +52,14 @@ export function MessageContent({
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;
@@ -125,6 +134,13 @@ export function MessageContent({
) : null}
</>
)}
{isFromAI && commercialAction ? (
<CommercialActionCard
action={commercialAction}
onActivate={onCommercialAction}
onDismiss={onCommercialActionDismiss}
/>
) : null}
</div>
);
}