fix(chat): add voice unlock payment choices

This commit is contained in:
2026-06-25 14:41:21 +08:00
parent 5879b7acf3
commit ffc3db9a91
7 changed files with 201 additions and 2 deletions
+27
View File
@@ -23,6 +23,7 @@ import {
ChatQuotaExhaustedBanner,
ExternalBrowserDialog,
PwaInstallOverlay,
VoiceUnlockOptionsDialog,
} from "./components";
import styles from "./components/chat-screen.module.css";
@@ -40,6 +41,7 @@ export function ChatScreen() {
const router = useRouter();
const [showExternalBrowserDialog, setShowExternalBrowserDialog] =
useState(false);
const [showVoiceUnlockDialog, setShowVoiceUnlockDialog] = useState(false);
// isGuest 派生(chat-screen 是唯一知道这个值的地方 —— chat 机器无 isGuest 字段)
const isGuest = deriveIsGuest(authState.loginStatus);
@@ -60,6 +62,20 @@ export function ChatScreen() {
returnTo: "chat",
});
function navigateToSubscription(type: "vip" | "voice"): void {
const subscriptionUrl = ROUTE_BUILDERS.subscription(type, {
returnTo: "chat",
});
setShowVoiceUnlockDialog(false);
if (isGuest) {
router.push(ROUTE_BUILDERS.authWithRedirect(subscriptionUrl));
return;
}
router.push(subscriptionUrl);
}
useEffect(() => {
if (!authState.hasInitialized || authState.isLoading) return;
const isDev = AppEnvUtil.isDevelopment();
@@ -153,6 +169,10 @@ export function ChatScreen() {
router.push(chatPaywallSubscriptionUrl);
}
function handleUnlockVoiceMessage(): void {
setShowVoiceUnlockDialog(true);
}
return (
<MobileShell>
<div className={styles.shell}>
@@ -178,6 +198,7 @@ export function ChatScreen() {
unlockingPrivateMessageId={state.unlockingPrivateMessageId}
onUnlockPrivateMessage={handleUnlockPrivateMessage}
onUnlockImagePaywall={handleUnlockImagePaywall}
onUnlockVoiceMessage={handleUnlockVoiceMessage}
/>
{showPrivatePaywallBanner ? (
@@ -209,6 +230,12 @@ export function ChatScreen() {
onClose={() => setShowExternalBrowserDialog(false)}
onConfirm={() => void handleOpenExternalBrowser()}
/>
<VoiceUnlockOptionsDialog
open={showVoiceUnlockDialog}
onClose={() => setShowVoiceUnlockDialog(false)}
onBuyVoicePackage={() => navigateToSubscription("voice")}
onActivateVip={() => navigateToSubscription("vip")}
/>
</div>
</MobileShell>
);