fix(chat): unify insufficient credits prompt

This commit is contained in:
2026-07-16 11:37:11 +08:00
parent 4d24fbc849
commit 764bb5a862
4 changed files with 7 additions and 53 deletions
@@ -11,35 +11,13 @@ afterEach(() => {
});
describe("getInsufficientCreditsMessageLimitView", () => {
it("asks guests to log in for more free chats", () => {
expect(getInsufficientCreditsMessageLimitView("guest")).toEqual({
title: "Log in to get more free chats",
description: "Free chats refresh every day.",
ctaLabel: "Log in to continue",
action: "auth",
});
});
it("treats the transient not logged in state like guest", () => {
expect(getInsufficientCreditsMessageLimitView("notLoggedIn")).toEqual({
title: "Log in to get more free chats",
description: "Free chats refresh every day.",
ctaLabel: "Log in to continue",
action: "auth",
});
});
it.each(["email", "facebook", "google"] as const)(
"asks %s users to top up credits",
(loginStatus) => {
expect(getInsufficientCreditsMessageLimitView(loginStatus)).toEqual({
it("shows the same top-up prompt without checking login status", () => {
expect(getInsufficientCreditsMessageLimitView()).toEqual({
title: "Insufficient credits",
description: "Free chats refresh every day.",
ctaLabel: "Top up credits to continue",
action: "topup",
});
},
);
});
});
describe("shouldShowMessageLimitBanner", () => {
+2 -16
View File
@@ -12,13 +12,10 @@ export interface ExternalBrowserPromptState {
isInAppBrowser?: boolean;
}
export type InsufficientCreditsAction = "auth" | "topup";
export interface InsufficientCreditsMessageLimitView {
title: string;
description: string;
ctaLabel: string;
action: InsufficientCreditsAction;
}
export interface MessageLimitBannerState {
@@ -37,23 +34,12 @@ export function shouldShowMessageLimitBanner({
return upgradePromptVisible && upgradeReason === "insufficient_credits";
}
export function getInsufficientCreditsMessageLimitView(
loginStatus: LoginStatus,
): InsufficientCreditsMessageLimitView {
if (loginStatus === "guest" || loginStatus === "notLoggedIn") {
return {
title: "Log in to get more free chats",
description: "Free chats refresh every day.",
ctaLabel: "Log in to continue",
action: "auth",
};
}
export function getInsufficientCreditsMessageLimitView():
InsufficientCreditsMessageLimitView {
return {
title: "Insufficient credits",
description: "Free chats refresh every day.",
ctaLabel: "Top up credits to continue",
action: "topup",
};
}
-1
View File
@@ -88,7 +88,6 @@ export function ChatScreen() {
const messageLimitBanner = useChatMessageLimitBanner({
upgradePromptVisible: state.upgradePromptVisible,
upgradeReason: state.upgradeReason,
loginStatus: authState.loginStatus,
});
const firstRechargeOfferBanner = useFirstRechargeOfferBanner({
historyLoaded: state.historyLoaded,
@@ -2,9 +2,7 @@
import { useEffect, useRef } from "react";
import type { LoginStatus } from "@/data/dto/auth";
import { behaviorAnalytics } from "@/lib/analytics";
import { ROUTES } from "@/router/routes";
import { useAppNavigator } from "@/router/use-app-navigator";
import type { ChatUpgradeReason } from "@/stores/chat/chat-state";
import { useUserSelector } from "@/stores/user/user-context";
@@ -19,7 +17,6 @@ import {
export interface UseChatMessageLimitBannerInput {
upgradePromptVisible: boolean;
upgradeReason: ChatUpgradeReason | null;
loginStatus: LoginStatus;
}
export interface ChatMessageLimitBannerView
@@ -31,11 +28,10 @@ export interface ChatMessageLimitBannerView
export function useChatMessageLimitBanner({
upgradePromptVisible,
upgradeReason,
loginStatus,
}: UseChatMessageLimitBannerInput): ChatMessageLimitBannerView {
const navigator = useAppNavigator();
const isVip = useUserSelector((state) => state.context.isVip);
const view = getInsufficientCreditsMessageLimitView(loginStatus);
const view = getInsufficientCreditsMessageLimitView();
const visible = shouldShowMessageLimitBanner({
upgradePromptVisible,
upgradeReason,
@@ -59,11 +55,6 @@ export function useChatMessageLimitBanner({
}, [isVip, visible]);
function unlock(): void {
if (view.action === "auth") {
navigator.openAuth(ROUTES.chat);
return;
}
navigator.openSubscription({
type: getInsufficientCreditsSubscriptionType(isVip),
returnTo: "chat",