refactor(chat): consolidate unlock state
This commit is contained in:
@@ -80,7 +80,7 @@ export function useChatUnlockCoordinator({
|
|||||||
const chatState = useChatSelector(
|
const chatState = useChatSelector(
|
||||||
(state) => ({
|
(state) => ({
|
||||||
historyLoaded: state.context.historyLoaded,
|
historyLoaded: state.context.historyLoaded,
|
||||||
isUnlockingHistory: state.context.isUnlockingHistory,
|
isUnlockingHistory: state.matches({ userSession: "unlockingHistory" }),
|
||||||
lockedHistoryCount: state.context.lockedHistoryCount,
|
lockedHistoryCount: state.context.lockedHistoryCount,
|
||||||
unlockHistoryError: state.context.unlockHistoryError,
|
unlockHistoryError: state.context.unlockHistoryError,
|
||||||
unlockHistoryPromptVisible: state.context.unlockHistoryPromptVisible,
|
unlockHistoryPromptVisible: state.context.unlockHistoryPromptVisible,
|
||||||
|
|||||||
@@ -49,14 +49,8 @@ function makeChatState(overrides: Partial<ChatState> = {}): ChatState {
|
|||||||
paymentUnlockPending: false,
|
paymentUnlockPending: false,
|
||||||
unlockHistoryPromptVisible: false,
|
unlockHistoryPromptVisible: false,
|
||||||
lockedHistoryCount: 0,
|
lockedHistoryCount: 0,
|
||||||
isUnlockingHistory: false,
|
|
||||||
unlockHistoryError: null,
|
unlockHistoryError: null,
|
||||||
isUnlockingMessage: false,
|
unlockingMessage: null,
|
||||||
unlockingMessageId: null,
|
|
||||||
unlockingMessageKind: null,
|
|
||||||
unlockingRemoteMessageId: null,
|
|
||||||
unlockingLockType: null,
|
|
||||||
unlockingClientLockId: null,
|
|
||||||
unlockMessageError: null,
|
unlockMessageError: null,
|
||||||
unlockPaywallRequest: null,
|
unlockPaywallRequest: null,
|
||||||
...overrides,
|
...overrides,
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { createActor, waitFor } from "xstate";
|
import { createActor, fromPromise, waitFor } from "xstate";
|
||||||
|
|
||||||
import { ChatSendResponse } from "@/data/dto/chat";
|
import { ChatSendResponse } from "@/data/dto/chat";
|
||||||
|
import type {
|
||||||
|
UnlockMessageOutput,
|
||||||
|
UnlockMessageRequest,
|
||||||
|
} from "@/stores/chat/helper/unlock";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createTestChatMachine,
|
createTestChatMachine,
|
||||||
@@ -189,7 +193,6 @@ describe("chat unlock flow", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(actor.getSnapshot().context).toMatchObject({
|
expect(actor.getSnapshot().context).toMatchObject({
|
||||||
isUnlockingHistory: false,
|
|
||||||
unlockHistoryPromptVisible: true,
|
unlockHistoryPromptVisible: true,
|
||||||
unlockHistoryError: "Failed to unlock messages. Please try again.",
|
unlockHistoryError: "Failed to unlock messages. Please try again.",
|
||||||
});
|
});
|
||||||
@@ -237,7 +240,7 @@ describe("chat unlock flow", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(actor.getSnapshot().context.unlockPaywallRequest).toBeNull();
|
expect(actor.getSnapshot().context.unlockPaywallRequest).toBeNull();
|
||||||
expect(actor.getSnapshot().context.isUnlockingMessage).toBe(false);
|
expect(actor.getSnapshot().context.unlockingMessage).toBeNull();
|
||||||
expect(actor.getSnapshot().context.messages).toMatchObject([
|
expect(actor.getSnapshot().context.messages).toMatchObject([
|
||||||
{
|
{
|
||||||
id: "msg-private-locked",
|
id: "msg-private-locked",
|
||||||
@@ -485,7 +488,7 @@ describe("chat unlock flow", () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(actor.getSnapshot().context.messages[0]?.audioUrl).toBeUndefined();
|
expect(actor.getSnapshot().context.messages[0]?.audioUrl).toBeUndefined();
|
||||||
expect(actor.getSnapshot().context.isUnlockingMessage).toBe(false);
|
expect(actor.getSnapshot().context.unlockingMessage).toBeNull();
|
||||||
|
|
||||||
actor.stop();
|
actor.stop();
|
||||||
});
|
});
|
||||||
@@ -536,8 +539,7 @@ describe("chat unlock flow", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(actor.getSnapshot().context).toMatchObject({
|
expect(actor.getSnapshot().context).toMatchObject({
|
||||||
isUnlockingMessage: false,
|
unlockingMessage: null,
|
||||||
unlockingMessageId: null,
|
|
||||||
unlockMessageError: "not_found",
|
unlockMessageError: "not_found",
|
||||||
unlockPaywallRequest: null,
|
unlockPaywallRequest: null,
|
||||||
});
|
});
|
||||||
@@ -552,6 +554,92 @@ describe("chat unlock flow", () => {
|
|||||||
actor.stop();
|
actor.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("owns the active request in one object and ignores history refreshes while unlocking", async () => {
|
||||||
|
let capturedRequest: UnlockMessageRequest | null = null;
|
||||||
|
let resolveUnlock!: (output: UnlockMessageOutput) => void;
|
||||||
|
const unlockDeferred = new Promise<UnlockMessageOutput>((resolve) => {
|
||||||
|
resolveUnlock = resolve;
|
||||||
|
});
|
||||||
|
const originalMessage = {
|
||||||
|
id: "promotion:lock-1",
|
||||||
|
content: "",
|
||||||
|
isFromAI: true,
|
||||||
|
date: "2026-07-16",
|
||||||
|
locked: true,
|
||||||
|
lockReason: "image_paywall" as const,
|
||||||
|
imagePaywalled: true,
|
||||||
|
};
|
||||||
|
const machine = createTestChatMachine({
|
||||||
|
historyMessages: [originalMessage],
|
||||||
|
}).provide({
|
||||||
|
actors: {
|
||||||
|
unlockMessage: fromPromise<
|
||||||
|
UnlockMessageOutput,
|
||||||
|
UnlockMessageRequest
|
||||||
|
>(async ({ input }) => {
|
||||||
|
capturedRequest = input;
|
||||||
|
return unlockDeferred;
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const actor = createActor(machine).start();
|
||||||
|
|
||||||
|
actor.send({ type: "ChatUserLogin", token: "token" });
|
||||||
|
await waitFor(actor, (snapshot) =>
|
||||||
|
snapshot.matches({ userSession: "ready" }),
|
||||||
|
);
|
||||||
|
actor.send({
|
||||||
|
type: "ChatUnlockMessageRequested",
|
||||||
|
messageId: "promotion:lock-1",
|
||||||
|
remoteMessageId: "remote-1",
|
||||||
|
kind: "image",
|
||||||
|
lockType: "image_paywall",
|
||||||
|
clientLockId: "lock-1",
|
||||||
|
});
|
||||||
|
await waitFor(actor, (snapshot) =>
|
||||||
|
snapshot.matches({ userSession: "unlockingMessage" }),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(actor.getSnapshot().context.unlockingMessage).toEqual({
|
||||||
|
displayMessageId: "promotion:lock-1",
|
||||||
|
messageId: "remote-1",
|
||||||
|
kind: "image",
|
||||||
|
lockType: "image_paywall",
|
||||||
|
clientLockId: "lock-1",
|
||||||
|
});
|
||||||
|
actor.send({
|
||||||
|
type: "ChatNetworkHistoryLoaded",
|
||||||
|
output: {
|
||||||
|
messages: [],
|
||||||
|
localOverwritten: true,
|
||||||
|
localCount: 0,
|
||||||
|
networkCount: 0,
|
||||||
|
total: 0,
|
||||||
|
limit: 50,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(actor.getSnapshot().context.messages).toEqual([originalMessage]);
|
||||||
|
|
||||||
|
if (!capturedRequest) throw new Error("unlock actor did not start");
|
||||||
|
resolveUnlock({
|
||||||
|
displayMessageId: "promotion:lock-1",
|
||||||
|
request: capturedRequest,
|
||||||
|
response: makeUnlockPrivateResponse({
|
||||||
|
messageId: "remote-1",
|
||||||
|
image: {
|
||||||
|
type: "promotion",
|
||||||
|
url: "https://example.com/unlocked.jpg",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
await waitFor(actor, (snapshot) =>
|
||||||
|
snapshot.matches({ userSession: "ready" }),
|
||||||
|
);
|
||||||
|
expect(actor.getSnapshot().context.unlockingMessage).toBeNull();
|
||||||
|
|
||||||
|
actor.stop();
|
||||||
|
});
|
||||||
|
|
||||||
it("clears the insufficient credits prompt after payment succeeds", async () => {
|
it("clears the insufficient credits prompt after payment succeeds", async () => {
|
||||||
const actor = createActor(createTestChatMachine()).start();
|
const actor = createActor(createTestChatMachine()).start();
|
||||||
|
|
||||||
|
|||||||
@@ -86,10 +86,11 @@ function selectChatState(state: ChatSnapshot): SelectedChatState {
|
|||||||
isLoadingMoreHistory: state.context.isLoadingMoreHistory,
|
isLoadingMoreHistory: state.context.isLoadingMoreHistory,
|
||||||
unlockHistoryPromptVisible: state.context.unlockHistoryPromptVisible,
|
unlockHistoryPromptVisible: state.context.unlockHistoryPromptVisible,
|
||||||
lockedHistoryCount: state.context.lockedHistoryCount,
|
lockedHistoryCount: state.context.lockedHistoryCount,
|
||||||
isUnlockingHistory: state.context.isUnlockingHistory,
|
isUnlockingHistory: state.matches({ userSession: "unlockingHistory" }),
|
||||||
unlockHistoryError: state.context.unlockHistoryError,
|
unlockHistoryError: state.context.unlockHistoryError,
|
||||||
isUnlockingMessage: state.context.isUnlockingMessage,
|
isUnlockingMessage: state.matches({ userSession: "unlockingMessage" }),
|
||||||
unlockingMessageId: state.context.unlockingMessageId,
|
unlockingMessageId:
|
||||||
|
state.context.unlockingMessage?.displayMessageId ?? null,
|
||||||
unlockMessageError: state.context.unlockMessageError,
|
unlockMessageError: state.context.unlockMessageError,
|
||||||
unlockPaywallRequest: state.context.unlockPaywallRequest,
|
unlockPaywallRequest: state.context.unlockPaywallRequest,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,12 +6,16 @@ import type { ChatPromotionState } from "./helper/promotion";
|
|||||||
|
|
||||||
export type ChatUpgradeReason = "insufficient_credits";
|
export type ChatUpgradeReason = "insufficient_credits";
|
||||||
|
|
||||||
export interface ChatUnlockPaywallRequest {
|
export interface ChatUnlockMessageRequest {
|
||||||
displayMessageId: string;
|
displayMessageId: string;
|
||||||
messageId?: string;
|
messageId?: string;
|
||||||
kind: PendingChatUnlockKind;
|
kind: PendingChatUnlockKind;
|
||||||
lockType?: ChatLockType;
|
lockType?: ChatLockType;
|
||||||
clientLockId?: string;
|
clientLockId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChatUnlockPaywallRequest
|
||||||
|
extends ChatUnlockMessageRequest {
|
||||||
promotion?: PendingChatPromotion;
|
promotion?: PendingChatPromotion;
|
||||||
reason: string;
|
reason: string;
|
||||||
creditBalance: number;
|
creditBalance: number;
|
||||||
@@ -41,14 +45,8 @@ export interface ChatState {
|
|||||||
paymentUnlockPending: boolean;
|
paymentUnlockPending: boolean;
|
||||||
unlockHistoryPromptVisible: boolean;
|
unlockHistoryPromptVisible: boolean;
|
||||||
lockedHistoryCount: number;
|
lockedHistoryCount: number;
|
||||||
isUnlockingHistory: boolean;
|
|
||||||
unlockHistoryError: string | null;
|
unlockHistoryError: string | null;
|
||||||
isUnlockingMessage: boolean;
|
unlockingMessage: ChatUnlockMessageRequest | null;
|
||||||
unlockingMessageId: string | null;
|
|
||||||
unlockingMessageKind: PendingChatUnlockKind | null;
|
|
||||||
unlockingRemoteMessageId: string | null;
|
|
||||||
unlockingLockType: ChatLockType | null;
|
|
||||||
unlockingClientLockId: string | null;
|
|
||||||
unlockMessageError: string | null;
|
unlockMessageError: string | null;
|
||||||
unlockPaywallRequest: ChatUnlockPaywallRequest | null;
|
unlockPaywallRequest: ChatUnlockPaywallRequest | null;
|
||||||
}
|
}
|
||||||
@@ -74,14 +72,8 @@ export const initialState: ChatState = {
|
|||||||
paymentUnlockPending: false,
|
paymentUnlockPending: false,
|
||||||
unlockHistoryPromptVisible: false,
|
unlockHistoryPromptVisible: false,
|
||||||
lockedHistoryCount: 0,
|
lockedHistoryCount: 0,
|
||||||
isUnlockingHistory: false,
|
|
||||||
unlockHistoryError: null,
|
unlockHistoryError: null,
|
||||||
isUnlockingMessage: false,
|
unlockingMessage: null,
|
||||||
unlockingMessageId: null,
|
|
||||||
unlockingMessageKind: null,
|
|
||||||
unlockingRemoteMessageId: null,
|
|
||||||
unlockingLockType: null,
|
|
||||||
unlockingClientLockId: null,
|
|
||||||
unlockMessageError: null,
|
unlockMessageError: null,
|
||||||
unlockPaywallRequest: null,
|
unlockPaywallRequest: null,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -117,6 +117,22 @@ const guestSessionState = chatMachineSetup.createStateConfig({
|
|||||||
|
|
||||||
const userReadyState = chatMachineSetup.createStateConfig({
|
const userReadyState = chatMachineSetup.createStateConfig({
|
||||||
on: {
|
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: {
|
ChatSendMessage: {
|
||||||
guard: ({ context, event }) =>
|
guard: ({ context, event }) =>
|
||||||
context.canSendMessage && event.content.trim().length > 0,
|
context.canSendMessage && event.content.trim().length > 0,
|
||||||
@@ -158,26 +174,6 @@ const userSessionState = chatMachineSetup.createStateConfig({
|
|||||||
target: "#chat.idle",
|
target: "#chat.idle",
|
||||||
actions: "clearChatSession",
|
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: {
|
ChatHistoryLoadFailed: {
|
||||||
actions: "markHistoryLoadFailed",
|
actions: "markHistoryLoadFailed",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -33,12 +33,10 @@ const dismissUnlockHistoryPromptAction = sendMachineSetup.assign(() => ({
|
|||||||
const markUnlockHistoryStartedAction = sendMachineSetup.assign(() => ({
|
const markUnlockHistoryStartedAction = sendMachineSetup.assign(() => ({
|
||||||
paymentUnlockPending: false,
|
paymentUnlockPending: false,
|
||||||
unlockHistoryPromptVisible: false,
|
unlockHistoryPromptVisible: false,
|
||||||
isUnlockingHistory: true,
|
|
||||||
unlockHistoryError: null,
|
unlockHistoryError: null,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const markUnlockHistoryFailedAction = sendMachineSetup.assign(() => ({
|
const markUnlockHistoryFailedAction = sendMachineSetup.assign(() => ({
|
||||||
isUnlockingHistory: false,
|
|
||||||
unlockHistoryPromptVisible: true,
|
unlockHistoryPromptVisible: true,
|
||||||
unlockHistoryError: "Failed to unlock messages. Please try again.",
|
unlockHistoryError: "Failed to unlock messages. Please try again.",
|
||||||
}));
|
}));
|
||||||
@@ -46,14 +44,18 @@ const markUnlockHistoryFailedAction = sendMachineSetup.assign(() => ({
|
|||||||
const markUnlockMessageStartedAction = sendMachineSetup.assign(
|
const markUnlockMessageStartedAction = sendMachineSetup.assign(
|
||||||
({ event }) => {
|
({ event }) => {
|
||||||
if (event.type !== "ChatUnlockMessageRequested") return {};
|
if (event.type !== "ChatUnlockMessageRequested") return {};
|
||||||
|
const remoteMessageId =
|
||||||
|
event.remoteMessageId ?? (event.lockType ? undefined : event.messageId);
|
||||||
return {
|
return {
|
||||||
isUnlockingMessage: true,
|
unlockingMessage: {
|
||||||
unlockingMessageId: event.messageId,
|
displayMessageId: event.messageId,
|
||||||
unlockingMessageKind: event.kind,
|
...(remoteMessageId ? { messageId: remoteMessageId } : {}),
|
||||||
unlockingRemoteMessageId:
|
kind: event.kind,
|
||||||
event.remoteMessageId ?? (event.lockType ? null : event.messageId),
|
...(event.lockType ? { lockType: event.lockType } : {}),
|
||||||
unlockingLockType: event.lockType ?? null,
|
...(event.clientLockId
|
||||||
unlockingClientLockId: event.clientLockId ?? null,
|
? { clientLockId: event.clientLockId }
|
||||||
|
: {}),
|
||||||
|
},
|
||||||
unlockMessageError: null,
|
unlockMessageError: null,
|
||||||
unlockPaywallRequest: null,
|
unlockPaywallRequest: null,
|
||||||
};
|
};
|
||||||
@@ -66,12 +68,7 @@ const applyUnlockMessageSucceededAction = sendMachineSetup.assign(
|
|||||||
return {
|
return {
|
||||||
messages: applySingleUnlockOutput(context.messages, output),
|
messages: applySingleUnlockOutput(context.messages, output),
|
||||||
promotion: applyPromotionUnlockOutput(context.promotion, output),
|
promotion: applyPromotionUnlockOutput(context.promotion, output),
|
||||||
isUnlockingMessage: false,
|
unlockingMessage: null,
|
||||||
unlockingMessageId: null,
|
|
||||||
unlockingMessageKind: null,
|
|
||||||
unlockingRemoteMessageId: null,
|
|
||||||
unlockingLockType: null,
|
|
||||||
unlockingClientLockId: null,
|
|
||||||
unlockMessageError: null,
|
unlockMessageError: null,
|
||||||
unlockPaywallRequest: null,
|
unlockPaywallRequest: null,
|
||||||
creditBalance: output.response.creditBalance,
|
creditBalance: output.response.creditBalance,
|
||||||
@@ -88,12 +85,7 @@ const requestUnlockPaymentFromOutputAction = sendMachineSetup.assign(
|
|||||||
const shouldOpenPaywall = output.response.reason !== "not_found";
|
const shouldOpenPaywall = output.response.reason !== "not_found";
|
||||||
return {
|
return {
|
||||||
promotion: applyPromotionUnlockOutput(context.promotion, output),
|
promotion: applyPromotionUnlockOutput(context.promotion, output),
|
||||||
isUnlockingMessage: false,
|
unlockingMessage: null,
|
||||||
unlockingMessageId: null,
|
|
||||||
unlockingMessageKind: null,
|
|
||||||
unlockingRemoteMessageId: null,
|
|
||||||
unlockingLockType: null,
|
|
||||||
unlockingClientLockId: null,
|
|
||||||
unlockMessageError: output.response.reason,
|
unlockMessageError: output.response.reason,
|
||||||
unlockPaywallRequest: shouldOpenPaywall
|
unlockPaywallRequest: shouldOpenPaywall
|
||||||
? {
|
? {
|
||||||
@@ -105,7 +97,7 @@ const requestUnlockPaymentFromOutputAction = sendMachineSetup.assign(
|
|||||||
output.response.messageId || output.request.messageId,
|
output.response.messageId || output.request.messageId,
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
kind: context.unlockingMessageKind ?? "private",
|
kind: context.unlockingMessage?.kind ?? "private",
|
||||||
...(output.request.lockType
|
...(output.request.lockType
|
||||||
? { lockType: output.request.lockType }
|
? { lockType: output.request.lockType }
|
||||||
: {}),
|
: {}),
|
||||||
@@ -129,24 +121,15 @@ const requestUnlockPaymentFromOutputAction = sendMachineSetup.assign(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const requestUnlockPaymentFromErrorAction = sendMachineSetup.assign(
|
const requestUnlockPaymentFromErrorAction = sendMachineSetup.assign(
|
||||||
({ context }) => ({
|
({ context }) => {
|
||||||
isUnlockingMessage: false,
|
const request = context.unlockingMessage;
|
||||||
|
return {
|
||||||
|
unlockingMessage: null,
|
||||||
unlockMessageError: "unlock_failed",
|
unlockMessageError: "unlock_failed",
|
||||||
unlockPaywallRequest:
|
unlockPaywallRequest: request
|
||||||
context.unlockingMessageId && context.unlockingMessageKind
|
|
||||||
? {
|
? {
|
||||||
displayMessageId: context.unlockingMessageId,
|
...request,
|
||||||
...(context.unlockingRemoteMessageId
|
...(context.promotion?.message.id === request.displayMessageId
|
||||||
? { messageId: context.unlockingRemoteMessageId }
|
|
||||||
: {}),
|
|
||||||
kind: context.unlockingMessageKind,
|
|
||||||
...(context.unlockingLockType
|
|
||||||
? { lockType: context.unlockingLockType }
|
|
||||||
: {}),
|
|
||||||
...(context.unlockingClientLockId
|
|
||||||
? { clientLockId: context.unlockingClientLockId }
|
|
||||||
: {}),
|
|
||||||
...(context.promotion?.message.id === context.unlockingMessageId
|
|
||||||
? { promotion: context.promotion.session }
|
? { promotion: context.promotion.session }
|
||||||
: {}),
|
: {}),
|
||||||
reason: "unlock_failed",
|
reason: "unlock_failed",
|
||||||
@@ -155,12 +138,8 @@ const requestUnlockPaymentFromErrorAction = sendMachineSetup.assign(
|
|||||||
shortfallCredits: context.shortfallCredits,
|
shortfallCredits: context.shortfallCredits,
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
unlockingMessageId: null,
|
};
|
||||||
unlockingMessageKind: null,
|
},
|
||||||
unlockingRemoteMessageId: null,
|
|
||||||
unlockingLockType: null,
|
|
||||||
unlockingClientLockId: null,
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const clearUnlockPaywallRequestAction = sendMachineSetup.assign(() => ({
|
const clearUnlockPaywallRequestAction = sendMachineSetup.assign(() => ({
|
||||||
@@ -199,7 +178,6 @@ const applyUnlockHistoryOutputAction =
|
|||||||
paymentUnlockPending: false,
|
paymentUnlockPending: false,
|
||||||
unlockHistoryPromptVisible: insufficientBalance,
|
unlockHistoryPromptVisible: insufficientBalance,
|
||||||
lockedHistoryCount,
|
lockedHistoryCount,
|
||||||
isUnlockingHistory: false,
|
|
||||||
unlockHistoryError: insufficientBalance
|
unlockHistoryError: insufficientBalance
|
||||||
? `Insufficient credits. You still need ${event.output.shortfallCredits} credits.`
|
? `Insufficient credits. You still need ${event.output.shortfallCredits} credits.`
|
||||||
: null,
|
: null,
|
||||||
@@ -225,18 +203,11 @@ export const unlockingMessageState = unlockMachineSetup.createStateConfig({
|
|||||||
invoke: {
|
invoke: {
|
||||||
id: "unlockMessage",
|
id: "unlockMessage",
|
||||||
src: "unlockMessage",
|
src: "unlockMessage",
|
||||||
input: ({ context }) => ({
|
input: ({ context }) =>
|
||||||
displayMessageId: context.unlockingMessageId ?? "",
|
context.unlockingMessage ?? {
|
||||||
...(context.unlockingRemoteMessageId
|
displayMessageId: "",
|
||||||
? { messageId: context.unlockingRemoteMessageId }
|
kind: "private",
|
||||||
: {}),
|
},
|
||||||
...(context.unlockingLockType
|
|
||||||
? { lockType: context.unlockingLockType }
|
|
||||||
: {}),
|
|
||||||
...(context.unlockingClientLockId
|
|
||||||
? { clientLockId: context.unlockingClientLockId }
|
|
||||||
: {}),
|
|
||||||
}),
|
|
||||||
onDone: [
|
onDone: [
|
||||||
{
|
{
|
||||||
guard: ({ event }) => event.output.response.unlocked,
|
guard: ({ event }) => event.output.response.unlocked,
|
||||||
|
|||||||
Reference in New Issue
Block a user