refactor(chat): remove private unlock machine flow
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user