diff --git a/src/app/chat/chat-screen.tsx b/src/app/chat/chat-screen.tsx
index cd37a89e..9b12b18a 100644
--- a/src/app/chat/chat-screen.tsx
+++ b/src/app/chat/chat-screen.tsx
@@ -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() {
{/* isGuest 派生自 auth.loginStatus */}
-
+
+ }
+ />
-
-
);
diff --git a/src/app/chat/components/chat-header.module.css b/src/app/chat/components/chat-header.module.css
index 971080f6..bb7708b9 100644
--- a/src/app/chat/components/chat-header.module.css
+++ b/src/app/chat/components/chat-header.module.css
@@ -4,7 +4,8 @@
.header {
flex: 0 0 auto;
display: flex;
- align-items: center;
+ flex-direction: column;
+ align-items: stretch;
padding: 0;
background: transparent;
}
@@ -33,7 +34,6 @@
/* 登录模式行容器(Dart: Container(margin-left 12, padding: vertical 8 / horizontal 12)) */
.headerRow {
- width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
diff --git a/src/app/chat/components/chat-header.tsx b/src/app/chat/components/chat-header.tsx
index d60c7ac7..8a63cb28 100644
--- a/src/app/chat/components/chat-header.tsx
+++ b/src/app/chat/components/chat-header.tsx
@@ -5,6 +5,7 @@
* 图标:lucide-react (游客 banner)+ (菜单按钮)
* tree-shakable,currentColor 继承父 color
*/
+import type { ReactNode } from "react";
import { Lock, Menu } from "lucide-react";
import { useRouter } from "next/navigation";
@@ -14,9 +15,10 @@ import styles from "./chat-header.module.css";
export interface ChatHeaderProps {
isGuest: boolean;
+ offerBanner?: ReactNode;
}
-export function ChatHeader({ isGuest }: ChatHeaderProps) {
+export function ChatHeader({ isGuest, offerBanner }: ChatHeaderProps) {
const router = useRouter();
if (isGuest) {
@@ -37,6 +39,8 @@ export function ChatHeader({ isGuest }: ChatHeaderProps) {
return (