feat(chat): add private message unlock flow
This commit is contained in:
@@ -8,7 +8,7 @@ import type { LoginStatus } from "@/data/dto/auth";
|
||||
import { AppStorage } from "@/data/storage/app/app_storage";
|
||||
import { AuthStorage } from "@/data/storage/auth/auth_storage";
|
||||
import { UserStorage } from "@/data/storage/user/user_storage";
|
||||
import { useChatState } from "@/stores/chat/chat-context";
|
||||
import { useChatDispatch, useChatState } from "@/stores/chat/chat-context";
|
||||
import { AppEnvUtil, BrowserDetector, todayString, UrlLauncherUtil } from "@/utils";
|
||||
import { ROUTE_BUILDERS, ROUTES } from "@/router/routes";
|
||||
|
||||
@@ -35,6 +35,7 @@ function deriveIsGuest(loginStatus: LoginStatus): boolean {
|
||||
|
||||
export function ChatScreen() {
|
||||
const state = useChatState();
|
||||
const chatDispatch = useChatDispatch();
|
||||
const authState = useAuthState();
|
||||
const [showExternalBrowserDialog, setShowExternalBrowserDialog] =
|
||||
useState(false);
|
||||
@@ -48,8 +49,16 @@ export function ChatScreen() {
|
||||
state.paywallReason === "daily_limit";
|
||||
const showPhotoPaywallBanner =
|
||||
state.paywallTriggered && state.paywallReason === "photo_paywall";
|
||||
const showExhaustedBanner =
|
||||
showDailyLimitBanner || showPhotoPaywallBanner;
|
||||
const showPrivatePaywallBanner =
|
||||
state.paywallTriggered && state.paywallReason === "private_paywall";
|
||||
const showInlineUpgradeBanner =
|
||||
showPhotoPaywallBanner || showPrivatePaywallBanner;
|
||||
const inlineUpgradeTitle = showPrivatePaywallBanner
|
||||
? "Unlock VIP to view private messages"
|
||||
: "Unlock VIP to view Elio's photos";
|
||||
const inlineUpgradeCta = showPrivatePaywallBanner
|
||||
? "Activate VIP to view private messages"
|
||||
: "Activate VIP to view photos";
|
||||
|
||||
const externalBrowserPromptShownRef = useRef(false);
|
||||
|
||||
@@ -122,6 +131,10 @@ export function ChatScreen() {
|
||||
UrlLauncherUtil.openUrlWithExternalBrowser(ROUTES.splash);
|
||||
}
|
||||
|
||||
function handleUnlockPrivateMessage(messageId: string): void {
|
||||
chatDispatch({ type: "ChatUnlockPrivateMessage", messageId });
|
||||
}
|
||||
|
||||
return (
|
||||
<MobileShell>
|
||||
<div className={styles.shell}>
|
||||
@@ -144,20 +157,19 @@ export function ChatScreen() {
|
||||
messages={state.messages}
|
||||
isReplyingAI={state.isReplyingAI}
|
||||
isGuest={isGuest}
|
||||
unlockingPrivateMessageId={state.unlockingPrivateMessageId}
|
||||
onUnlockPrivateMessage={handleUnlockPrivateMessage}
|
||||
/>
|
||||
|
||||
{showExhaustedBanner ? (
|
||||
{showInlineUpgradeBanner ? (
|
||||
<ChatQuotaExhaustedBanner
|
||||
title={inlineUpgradeTitle}
|
||||
ctaLabel={inlineUpgradeCta}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{showDailyLimitBanner ? (
|
||||
<ChatQuotaExhaustedBanner
|
||||
title={
|
||||
showPhotoPaywallBanner
|
||||
? "Unlock VIP to view Elio's photos"
|
||||
: undefined
|
||||
}
|
||||
ctaLabel={
|
||||
showPhotoPaywallBanner
|
||||
? "Activate VIP to view photos"
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<ChatInputBar disabled={state.isReplyingAI} />
|
||||
|
||||
Reference in New Issue
Block a user