refactor(chat): consolidate unlock state

This commit is contained in:
2026-07-16 19:49:08 +08:00
parent b5990bca8b
commit acabf165cd
7 changed files with 152 additions and 110 deletions
+16 -20
View File
@@ -117,6 +117,22 @@ const guestSessionState = chatMachineSetup.createStateConfig({
const userReadyState = chatMachineSetup.createStateConfig({
on: {
ChatNetworkHistoryLoaded: [
{
guard: ({ context, event }) =>
event.type === "ChatNetworkHistoryLoaded" &&
context.paymentUnlockPending &&
shouldPromptUnlockHistory(event.output.messages),
actions: "showUnlockHistoryPromptFromNetwork",
},
{
guard: ({ context }) => context.paymentUnlockPending,
actions: "applyNetworkHistoryLoadedAndClearPayment",
},
{
actions: "applyNetworkHistoryLoaded",
},
],
ChatSendMessage: {
guard: ({ context, event }) =>
context.canSendMessage && event.content.trim().length > 0,
@@ -158,26 +174,6 @@ const userSessionState = chatMachineSetup.createStateConfig({
target: "#chat.idle",
actions: "clearChatSession",
},
ChatNetworkHistoryLoaded: [
{
guard: ({ context, event }) =>
event.type === "ChatNetworkHistoryLoaded" &&
context.paymentUnlockPending &&
shouldPromptUnlockHistory(event.output.messages),
target: ".ready",
actions: "showUnlockHistoryPromptFromNetwork",
},
{
guard: ({ context }) => context.paymentUnlockPending,
target: ".ready",
actions: "applyNetworkHistoryLoadedAndClearPayment",
},
{
guard: ({ context }) =>
!context.isUnlockingHistory && !context.isUnlockingMessage,
actions: "applyNetworkHistoryLoaded",
},
],
ChatHistoryLoadFailed: {
actions: "markHistoryLoadFailed",
},
+29 -58
View File
@@ -33,12 +33,10 @@ const dismissUnlockHistoryPromptAction = sendMachineSetup.assign(() => ({
const markUnlockHistoryStartedAction = sendMachineSetup.assign(() => ({
paymentUnlockPending: false,
unlockHistoryPromptVisible: false,
isUnlockingHistory: true,
unlockHistoryError: null,
}));
const markUnlockHistoryFailedAction = sendMachineSetup.assign(() => ({
isUnlockingHistory: false,
unlockHistoryPromptVisible: true,
unlockHistoryError: "Failed to unlock messages. Please try again.",
}));
@@ -46,14 +44,18 @@ const markUnlockHistoryFailedAction = sendMachineSetup.assign(() => ({
const markUnlockMessageStartedAction = sendMachineSetup.assign(
({ event }) => {
if (event.type !== "ChatUnlockMessageRequested") return {};
const remoteMessageId =
event.remoteMessageId ?? (event.lockType ? undefined : event.messageId);
return {
isUnlockingMessage: true,
unlockingMessageId: event.messageId,
unlockingMessageKind: event.kind,
unlockingRemoteMessageId:
event.remoteMessageId ?? (event.lockType ? null : event.messageId),
unlockingLockType: event.lockType ?? null,
unlockingClientLockId: event.clientLockId ?? null,
unlockingMessage: {
displayMessageId: event.messageId,
...(remoteMessageId ? { messageId: remoteMessageId } : {}),
kind: event.kind,
...(event.lockType ? { lockType: event.lockType } : {}),
...(event.clientLockId
? { clientLockId: event.clientLockId }
: {}),
},
unlockMessageError: null,
unlockPaywallRequest: null,
};
@@ -66,12 +68,7 @@ const applyUnlockMessageSucceededAction = sendMachineSetup.assign(
return {
messages: applySingleUnlockOutput(context.messages, output),
promotion: applyPromotionUnlockOutput(context.promotion, output),
isUnlockingMessage: false,
unlockingMessageId: null,
unlockingMessageKind: null,
unlockingRemoteMessageId: null,
unlockingLockType: null,
unlockingClientLockId: null,
unlockingMessage: null,
unlockMessageError: null,
unlockPaywallRequest: null,
creditBalance: output.response.creditBalance,
@@ -88,12 +85,7 @@ const requestUnlockPaymentFromOutputAction = sendMachineSetup.assign(
const shouldOpenPaywall = output.response.reason !== "not_found";
return {
promotion: applyPromotionUnlockOutput(context.promotion, output),
isUnlockingMessage: false,
unlockingMessageId: null,
unlockingMessageKind: null,
unlockingRemoteMessageId: null,
unlockingLockType: null,
unlockingClientLockId: null,
unlockingMessage: null,
unlockMessageError: output.response.reason,
unlockPaywallRequest: shouldOpenPaywall
? {
@@ -105,7 +97,7 @@ const requestUnlockPaymentFromOutputAction = sendMachineSetup.assign(
output.response.messageId || output.request.messageId,
}
: {}),
kind: context.unlockingMessageKind ?? "private",
kind: context.unlockingMessage?.kind ?? "private",
...(output.request.lockType
? { lockType: output.request.lockType }
: {}),
@@ -129,24 +121,15 @@ const requestUnlockPaymentFromOutputAction = sendMachineSetup.assign(
);
const requestUnlockPaymentFromErrorAction = sendMachineSetup.assign(
({ context }) => ({
isUnlockingMessage: false,
unlockMessageError: "unlock_failed",
unlockPaywallRequest:
context.unlockingMessageId && context.unlockingMessageKind
({ context }) => {
const request = context.unlockingMessage;
return {
unlockingMessage: null,
unlockMessageError: "unlock_failed",
unlockPaywallRequest: request
? {
displayMessageId: context.unlockingMessageId,
...(context.unlockingRemoteMessageId
? { messageId: context.unlockingRemoteMessageId }
: {}),
kind: context.unlockingMessageKind,
...(context.unlockingLockType
? { lockType: context.unlockingLockType }
: {}),
...(context.unlockingClientLockId
? { clientLockId: context.unlockingClientLockId }
: {}),
...(context.promotion?.message.id === context.unlockingMessageId
...request,
...(context.promotion?.message.id === request.displayMessageId
? { promotion: context.promotion.session }
: {}),
reason: "unlock_failed",
@@ -155,12 +138,8 @@ const requestUnlockPaymentFromErrorAction = sendMachineSetup.assign(
shortfallCredits: context.shortfallCredits,
}
: null,
unlockingMessageId: null,
unlockingMessageKind: null,
unlockingRemoteMessageId: null,
unlockingLockType: null,
unlockingClientLockId: null,
}),
};
},
);
const clearUnlockPaywallRequestAction = sendMachineSetup.assign(() => ({
@@ -199,7 +178,6 @@ const applyUnlockHistoryOutputAction =
paymentUnlockPending: false,
unlockHistoryPromptVisible: insufficientBalance,
lockedHistoryCount,
isUnlockingHistory: false,
unlockHistoryError: insufficientBalance
? `Insufficient credits. You still need ${event.output.shortfallCredits} credits.`
: null,
@@ -225,18 +203,11 @@ export const unlockingMessageState = unlockMachineSetup.createStateConfig({
invoke: {
id: "unlockMessage",
src: "unlockMessage",
input: ({ context }) => ({
displayMessageId: context.unlockingMessageId ?? "",
...(context.unlockingRemoteMessageId
? { messageId: context.unlockingRemoteMessageId }
: {}),
...(context.unlockingLockType
? { lockType: context.unlockingLockType }
: {}),
...(context.unlockingClientLockId
? { clientLockId: context.unlockingClientLockId }
: {}),
}),
input: ({ context }) =>
context.unlockingMessage ?? {
displayMessageId: "",
kind: "private",
},
onDone: [
{
guard: ({ event }) => event.output.response.unlocked,