feat(chat): show first recharge offer in header

This commit is contained in:
2026-07-02 18:45:08 +08:00
parent efd89de0b0
commit 3592c6bb56
14 changed files with 427 additions and 350 deletions
+14 -17
View File
@@ -24,7 +24,7 @@ import {
ChatInputBar,
ChatInsufficientCreditsBanner,
ExternalBrowserDialog,
FirstRechargeOfferDialog,
FirstRechargeOfferBanner,
HistoryUnlockDialog,
InsufficientCreditsDialog,
PwaInstallOverlay,
@@ -36,7 +36,7 @@ import {
isChatDevelopmentEnvironment,
shouldStartExternalBrowserPrompt,
} from "./chat-screen.helpers";
import { useFirstRechargeOfferDialog } from "./hooks/use-first-recharge-offer-dialog";
import { useFirstRechargeOfferBanner } from "./hooks/use-first-recharge-offer-banner";
import { useChatUnlockNavigationFlow } from "./hooks/use-chat-unlock-navigation-flow";
import styles from "./components/chat-screen.module.css";
@@ -65,15 +65,9 @@ export function ChatScreen() {
const messageLimitTitle =
"Insufficient credits\nTop up to continue chatting";
const messageLimitCtaLabel = "Top up credits to continue";
const hasBlockingDialog =
showExternalBrowserDialog ||
showMessageLimitBanner ||
state.unlockHistoryPromptVisible ||
unlockPaywallRequest !== null;
const firstRechargeOfferDialog = useFirstRechargeOfferDialog({
const firstRechargeOfferBanner = useFirstRechargeOfferBanner({
historyLoaded: state.historyLoaded,
loginStatus: authState.loginStatus,
hasBlockingDialog,
});
const externalBrowserPromptShownRef = useRef(false);
@@ -159,7 +153,17 @@ export function ChatScreen() {
<div className={styles.layout}>
{/* isGuest 派生自 auth.loginStatus */}
<ChatHeader isGuest={isGuest} />
<ChatHeader
isGuest={isGuest}
offerBanner={
<FirstRechargeOfferBanner
visible={firstRechargeOfferBanner.visible}
discountPercent={firstRechargeOfferBanner.discountPercent}
onClick={firstRechargeOfferBanner.claim}
onClose={firstRechargeOfferBanner.close}
/>
}
/>
<ChatArea
messages={state.messages}
@@ -211,13 +215,6 @@ export function ChatScreen() {
onClose={closeInsufficientCreditsDialog}
onConfirm={confirmInsufficientCreditsDialog}
/>
<FirstRechargeOfferDialog
open={firstRechargeOfferDialog.open}
discountPercent={firstRechargeOfferDialog.discountPercent}
onClose={firstRechargeOfferDialog.close}
onClaim={firstRechargeOfferDialog.claim}
/>
</div>
</MobileShell>
);