refactor(chat): remove private unlock machine flow

This commit is contained in:
2026-06-26 19:17:29 +08:00
parent b6f18a1ef3
commit 1b73c3ac10
11 changed files with 27 additions and 302 deletions
+8 -30
View File
@@ -49,12 +49,6 @@ export function ChatScreen() {
state.upgradePromptVisible && state.upgradeReason === "daily_limit";
const messageLimitTitle = "The limit for free chat times\nhas been reached";
const showPrivatePaywallBanner =
state.upgradePromptVisible && state.upgradeReason === "private_message";
const inlineUpgradeTitle = "Unlock VIP to view private messages";
const inlineUpgradeCta = "Activate VIP to view private messages";
const externalBrowserPromptShownRef = useRef(false);
const chatPaywallSubscriptionUrl = ROUTE_BUILDERS.subscription("vip", {
returnTo: "chat",
@@ -129,7 +123,7 @@ export function ChatScreen() {
UrlLauncherUtil.openUrlWithExternalBrowser(ROUTES.splash);
}
function handleUnlockPrivateMessage(): void {
function openChatPaywallSubscription(): void {
if (isGuest) {
router.push(ROUTE_BUILDERS.authWithRedirect(chatPaywallSubscriptionUrl));
return;
@@ -137,28 +131,20 @@ export function ChatScreen() {
router.push(chatPaywallSubscriptionUrl);
}
function handleUnlockPrivateMessage(): void {
openChatPaywallSubscription();
}
function handleUnlockImagePaywall(): void {
if (isGuest) {
router.push(ROUTE_BUILDERS.authWithRedirect(chatPaywallSubscriptionUrl));
return;
}
router.push(chatPaywallSubscriptionUrl);
openChatPaywallSubscription();
}
function handleMessageLimitUnlock(): void {
if (isGuest) {
router.push(ROUTE_BUILDERS.authWithRedirect(chatPaywallSubscriptionUrl));
return;
}
router.push(chatPaywallSubscriptionUrl);
openChatPaywallSubscription();
}
function handleUnlockVoiceMessage(): void {
if (isGuest) {
router.push(ROUTE_BUILDERS.authWithRedirect(chatPaywallSubscriptionUrl));
return;
}
router.push(chatPaywallSubscriptionUrl);
openChatPaywallSubscription();
}
return (
@@ -183,19 +169,11 @@ export function ChatScreen() {
messages={state.messages}
isReplyingAI={state.isReplyingAI}
isGuest={isGuest}
unlockingPrivateMessageId={state.unlockingPrivateMessageId}
onUnlockPrivateMessage={handleUnlockPrivateMessage}
onUnlockImagePaywall={handleUnlockImagePaywall}
onUnlockVoiceMessage={handleUnlockVoiceMessage}
/>
{showPrivatePaywallBanner ? (
<ChatQuotaExhaustedBanner
title={inlineUpgradeTitle}
ctaLabel={inlineUpgradeCta}
/>
) : null}
{showMessageLimitBanner ? (
<ChatQuotaExhaustedBanner
title={messageLimitTitle}
+2 -11
View File
@@ -26,8 +26,7 @@ export interface ChatAreaProps {
messages: readonly UiMessage[];
isReplyingAI: boolean;
isGuest: boolean;
unlockingPrivateMessageId?: string | null;
onUnlockPrivateMessage?: (messageId: string) => void;
onUnlockPrivateMessage?: () => void;
onUnlockImagePaywall?: () => void;
onUnlockVoiceMessage?: () => void;
}
@@ -35,7 +34,6 @@ export interface ChatAreaProps {
export function ChatArea({
messages,
isReplyingAI,
unlockingPrivateMessageId,
onUnlockPrivateMessage,
onUnlockImagePaywall,
onUnlockVoiceMessage,
@@ -60,7 +58,6 @@ export function ChatArea({
{renderMessagesWithDateHeaders(
messages,
unlockingPrivateMessageId,
onUnlockPrivateMessage,
onUnlockImagePaywall,
onUnlockVoiceMessage,
@@ -74,8 +71,7 @@ export function ChatArea({
/** 渲染消息列表(按日期分组插入分隔条) */
function renderMessagesWithDateHeaders(
messages: readonly UiMessage[],
unlockingPrivateMessageId?: string | null,
onUnlockPrivateMessage?: (messageId: string) => void,
onUnlockPrivateMessage?: () => void,
onUnlockImagePaywall?: () => void,
onUnlockVoiceMessage?: () => void,
) {
@@ -94,7 +90,6 @@ function renderMessagesWithDateHeaders(
) : (
<MessageBubble
key={item.key}
id={item.message.id}
content={item.message.content}
imageUrl={item.message.imageUrl}
imagePaywalled={item.message.imagePaywalled}
@@ -104,10 +99,6 @@ function renderMessagesWithDateHeaders(
lockReason={item.message.lockReason}
lockedPrivate={item.message.lockedPrivate}
privateMessageHint={item.message.privateMessageHint}
isUnlockingPrivate={
item.message.id != null &&
item.message.id === unlockingPrivateMessageId
}
onUnlockPrivateMessage={onUnlockPrivateMessage}
onUnlockImagePaywall={onUnlockImagePaywall}
onUnlockVoiceMessage={onUnlockVoiceMessage}
+1 -9
View File
@@ -15,7 +15,6 @@ import { MessageContent } from "./message-content";
import styles from "./chat-area.module.css";
export interface MessageBubbleProps {
id?: string;
content: string;
imageUrl?: string | null;
imagePaywalled?: boolean;
@@ -25,14 +24,12 @@ export interface MessageBubbleProps {
lockReason?: string | null;
lockedPrivate?: boolean | null;
privateMessageHint?: string | null;
isUnlockingPrivate?: boolean;
onUnlockPrivateMessage?: (messageId: string) => void;
onUnlockPrivateMessage?: () => void;
onUnlockImagePaywall?: () => void;
onUnlockVoiceMessage?: () => void;
}
export function MessageBubble({
id,
content,
imageUrl,
imagePaywalled,
@@ -42,7 +39,6 @@ export function MessageBubble({
lockReason,
lockedPrivate,
privateMessageHint,
isUnlockingPrivate,
onUnlockPrivateMessage,
onUnlockImagePaywall,
onUnlockVoiceMessage,
@@ -55,7 +51,6 @@ export function MessageBubble({
<MessageAvatar isFromAI={true} />
<div style={{ width: 8 }} />
<MessageContent
messageId={id}
content={content}
imageUrl={imageUrl}
imagePaywalled={imagePaywalled}
@@ -65,7 +60,6 @@ export function MessageBubble({
lockReason={lockReason}
lockedPrivate={lockedPrivate}
privateMessageHint={privateMessageHint}
isUnlockingPrivate={isUnlockingPrivate}
onUnlockPrivateMessage={onUnlockPrivateMessage}
onUnlockImagePaywall={onUnlockImagePaywall}
onUnlockVoiceMessage={onUnlockVoiceMessage}
@@ -79,7 +73,6 @@ export function MessageBubble({
<div className={styles.bubbleRowUser} aria-label="User message">
<div style={{ width: 43 }} /> {/* 占位 */}
<MessageContent
messageId={id}
content={content}
imageUrl={imageUrl}
imagePaywalled={imagePaywalled}
@@ -89,7 +82,6 @@ export function MessageBubble({
lockReason={lockReason}
lockedPrivate={lockedPrivate}
privateMessageHint={privateMessageHint}
isUnlockingPrivate={isUnlockingPrivate}
onUnlockPrivateMessage={onUnlockPrivateMessage}
onUnlockImagePaywall={onUnlockImagePaywall}
onUnlockVoiceMessage={onUnlockVoiceMessage}
+4 -12
View File
@@ -5,7 +5,6 @@ import { TextBubble } from "./text-bubble";
import { VoiceBubble } from "./voice-bubble";
export interface MessageContentProps {
messageId?: string;
content: string;
imageUrl?: string | null;
imagePaywalled?: boolean;
@@ -15,8 +14,7 @@ export interface MessageContentProps {
lockReason?: string | null;
lockedPrivate?: boolean | null;
privateMessageHint?: string | null;
isUnlockingPrivate?: boolean;
onUnlockPrivateMessage?: (messageId: string) => void;
onUnlockPrivateMessage?: () => void;
onUnlockImagePaywall?: () => void;
onUnlockVoiceMessage?: () => void;
}
@@ -24,7 +22,6 @@ export interface MessageContentProps {
const IMAGE_PLACEHOLDER = "[图片]";
export function MessageContent({
messageId,
content,
imageUrl,
imagePaywalled,
@@ -34,7 +31,6 @@ export function MessageContent({
lockReason,
lockedPrivate,
privateMessageHint,
isUnlockingPrivate = false,
onUnlockPrivateMessage,
onUnlockImagePaywall,
onUnlockVoiceMessage,
@@ -63,12 +59,8 @@ export function MessageContent({
{isLockedPrivateMessage ? (
<PrivateMessageCard
hint={privateMessageHint}
isUnlocking={isUnlockingPrivate}
onUnlock={
messageId
? () => onUnlockPrivateMessage?.(messageId)
: undefined
}
isUnlocking={false}
onUnlock={onUnlockPrivateMessage}
/>
) : (
<>
@@ -85,7 +77,7 @@ export function MessageContent({
isFromAI={isFromAI}
locked={isLockedVoiceMessage}
hint={privateMessageHint}
isUnlocking={isUnlockingPrivate}
isUnlocking={false}
onUnlock={
isLockedVoiceMessage
? onUnlockVoiceMessage