refactor(chat): centralize unlock coordination

This commit is contained in:
2026-07-15 19:11:59 +08:00
parent 590dee417b
commit 47876484fc
5 changed files with 546 additions and 387 deletions
+17 -42
View File
@@ -1,59 +1,34 @@
"use client";
import { shallowEqual } from "@xstate/react";
import {
useChatDispatch,
useChatSelector,
} from "@/stores/chat/chat-context";
import type { ChatUnlockPaywallRequest } from "@/stores/chat/chat-state";
import type { ChatUnlockDialogModel } from "../hooks/use-chat-unlock-coordinator";
import { HistoryUnlockDialog } from "./history-unlock-dialog";
import { InsufficientCreditsDialog } from "./insufficient-credits-dialog";
export interface ChatUnlockDialogsProps {
unlockPaywallRequest: ChatUnlockPaywallRequest | null;
onCloseInsufficientCreditsDialog: () => void;
onConfirmInsufficientCreditsDialog: () => void;
includeHistoryUnlock?: boolean;
model: ChatUnlockDialogModel;
}
export function ChatUnlockDialogs({
unlockPaywallRequest,
onCloseInsufficientCreditsDialog,
onConfirmInsufficientCreditsDialog,
includeHistoryUnlock = true,
model,
}: ChatUnlockDialogsProps) {
const chatState = useChatSelector(
(state) => ({
isUnlockingHistory: state.context.isUnlockingHistory,
lockedHistoryCount: state.context.lockedHistoryCount,
unlockHistoryError: state.context.unlockHistoryError,
unlockHistoryPromptVisible: state.context.unlockHistoryPromptVisible,
}),
shallowEqual,
);
const chatDispatch = useChatDispatch();
return (
<>
{includeHistoryUnlock ? (
<HistoryUnlockDialog
open={chatState.unlockHistoryPromptVisible}
lockedCount={chatState.lockedHistoryCount}
isLoading={chatState.isUnlockingHistory}
errorMessage={chatState.unlockHistoryError}
onClose={() => chatDispatch({ type: "ChatUnlockHistoryDismissed" })}
onConfirm={() => chatDispatch({ type: "ChatUnlockHistoryConfirmed" })}
/>
) : null}
<HistoryUnlockDialog
open={model.historyUnlock.open}
lockedCount={model.historyUnlock.lockedCount}
isLoading={model.historyUnlock.isLoading}
errorMessage={model.historyUnlock.errorMessage}
onClose={model.closeHistoryUnlock}
onConfirm={model.confirmHistoryUnlock}
/>
<InsufficientCreditsDialog
open={unlockPaywallRequest !== null}
creditBalance={unlockPaywallRequest?.creditBalance ?? 0}
requiredCredits={unlockPaywallRequest?.requiredCredits ?? 0}
shortfallCredits={unlockPaywallRequest?.shortfallCredits ?? 0}
onClose={onCloseInsufficientCreditsDialog}
onConfirm={onConfirmInsufficientCreditsDialog}
open={model.unlockPaywallRequest !== null}
creditBalance={model.unlockPaywallRequest?.creditBalance ?? 0}
requiredCredits={model.unlockPaywallRequest?.requiredCredits ?? 0}
shortfallCredits={model.unlockPaywallRequest?.shortfallCredits ?? 0}
onClose={model.closePaywall}
onConfirm={model.confirmPaywall}
/>
</>
);