Files
Jyotisha/frontend/src/lib/redeem-paywall-once.ts
T
Jesse_ChenandClaude Opus 5.5 dec36bce01 feat(birth-sky): poster-only dialog, date/time/city caption, slower reveal, paywall on first refused send (P1–P5, BUG-1080)
TASK-birth-sky-polish-20260928.
- P1: chart page dialog shows only the picture on a dimmed stage, 「保存图片」 below, icon × in the corner.
- P2: BFF returns one server-built `caption` (「1994年5月18日 07:40 · 杭州」); printed under the fact line in all three places; adopted time adds 「 · 校正后」.
- P3: convergence 3 s + words 2.5 s + fade 1 s; settled frame still equals the exported cover.
- P4: redeem paywall no longer opens when the starter home appears; first send refused for credits opens it, later ones open billing; convergence dialog portalled to <body>. BUG-1080 investigating (Chrome repro rules out the overlay covering the convergence).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 00:03:46 +08:00

24 lines
955 B
TypeScript

/**
* When the redeem paywall opens (TASK-birth-sky-polish-20260928 P4).
*
* It no longer opens by itself when the starter home appears — that collided
* with the first-chart star convergence (BUG-1080). Instead the first send on
* this page that is refused for lack of credits (the pre-flight balance check
* or a 402) opens it; every later refusal opens billing as before. The caller
* keeps the typed question in the composer either way.
*/
export type RedeemPaywallGate = Readonly<{
uiPreview: boolean;
/** Page-lifetime flag: the paywall has been shown once. */
shown?: { current: boolean };
open?: (open: boolean) => void;
}>;
/** True when it opened the paywall; false means the caller opens billing. */
export function tryOpenRedeemPaywall(gate: RedeemPaywallGate): boolean {
if (gate.uiPreview || !gate.shown || !gate.open || gate.shown.current) return false;
gate.shown.current = true;
gate.open(true);
return true;
}