Files
cozsweet-frontend-nextjs/src/stores/chat/machine/history-flow.ts
T

165 lines
4.9 KiB
TypeScript

import {
applyOlderHistoryLoadedOutput,
applyHistoryLoadedOutput,
applyNetworkHistoryLoadedOutput,
canLoadMoreHistory,
} from "../helper/history";
import {
countLockedHistoryMessages,
shouldPromptUnlockHistory,
} from "../helper/unlock";
import type { ChatState } from "../chat-state";
import { baseChatMachineSetup } from "./setup";
import { getCharacterErrorCode } from "@/data/services/api";
const applyLocalHistoryLoadedAction = baseChatMachineSetup.assign(
({ event }) => {
if (event.type !== "ChatLocalHistoryLoaded") return {};
return applyHistoryLoadedOutput(event.output);
},
);
const applyNetworkHistoryLoadedAction = baseChatMachineSetup.assign(
({ context, event }) => {
if (event.type !== "ChatNetworkHistoryLoaded") return {};
return applyNetworkHistoryLoadedOutput(context, event.output);
},
);
const applyNetworkHistoryLoadedAndClearPaymentAction =
baseChatMachineSetup.assign(({ context, event }) => {
if (event.type !== "ChatNetworkHistoryLoaded") return {};
return {
...applyNetworkHistoryLoadedOutput(context, event.output),
paymentUnlockPending: false,
};
});
const showUnlockHistoryPromptFromNetworkAction = baseChatMachineSetup.assign(
({ context, event }) => {
if (event.type !== "ChatNetworkHistoryLoaded") return {};
const nextHistory = applyNetworkHistoryLoadedOutput(context, event.output);
return {
...nextHistory,
paymentUnlockPending: false,
unlockHistoryPromptVisible: true,
lockedHistoryCount: countLockedHistoryMessages(nextHistory.messages),
unlockHistoryError: null,
};
},
);
const markHistoryLoadFailedAction = baseChatMachineSetup.assign(
({ context, event }) => {
if (event.type !== "ChatHistoryLoadFailed") return {};
const characterErrorCode = getCharacterErrorCode(event.error);
return {
historyLoaded: true,
characterErrorCode,
canSendMessage:
characterErrorCode === "CHARACTER_DISABLED" ||
characterErrorCode === "CHARACTER_NOT_FOUND"
? false
: context.canSendMessage,
};
},
);
const markLoadMoreHistoryStartedAction = baseChatMachineSetup.assign({
isLoadingMoreHistory: true,
});
const requestOlderHistoryPageAction = baseChatMachineSetup.sendTo(
"loadMoreHistory",
({ context }) => ({
type: "LoadMoreHistoryPageRequested",
offset: context.nextHistoryOffset,
limit: context.historyLimit,
}),
);
const applyOlderHistoryLoadedAction = baseChatMachineSetup.assign(
({ context, event }) => {
if (event.type !== "ChatOlderHistoryLoaded") return {};
return applyOlderHistoryLoadedOutput(context, event.output);
},
);
const markOlderHistoryLoadFailedAction = baseChatMachineSetup.assign({
isLoadingMoreHistory: false,
});
export const historyMachineSetup = baseChatMachineSetup.extend({
actions: {
applyLocalHistoryLoaded: applyLocalHistoryLoadedAction,
applyNetworkHistoryLoaded: applyNetworkHistoryLoadedAction,
applyNetworkHistoryLoadedAndClearPayment:
applyNetworkHistoryLoadedAndClearPaymentAction,
showUnlockHistoryPromptFromNetwork:
showUnlockHistoryPromptFromNetworkAction,
markHistoryLoadFailed: markHistoryLoadFailedAction,
markLoadMoreHistoryStarted: markLoadMoreHistoryStartedAction,
requestOlderHistoryPage: requestOlderHistoryPageAction,
applyOlderHistoryLoaded: applyOlderHistoryLoadedAction,
markOlderHistoryLoadFailed: markOlderHistoryLoadFailedAction,
},
});
export const historyPaginationTransitions = {
ChatLoadMoreHistoryRequested: {
guard: ({ context }: { context: ChatState }) =>
canLoadMoreHistory(context),
actions: ["markLoadMoreHistoryStarted", "requestOlderHistoryPage"],
},
ChatOlderHistoryLoaded: {
actions: "applyOlderHistoryLoaded",
},
ChatOlderHistoryLoadFailed: {
actions: "markOlderHistoryLoadFailed",
},
} as const;
export const guestInitializingState = historyMachineSetup.createStateConfig({
on: {
ChatLocalHistoryLoaded: {
target: "ready",
actions: "applyLocalHistoryLoaded",
},
ChatNetworkHistoryLoaded: {
target: "ready",
actions: "applyNetworkHistoryLoaded",
},
ChatHistoryLoadFailed: {
target: "ready",
actions: "markHistoryLoadFailed",
},
},
});
export const userInitializingState = historyMachineSetup.createStateConfig({
on: {
ChatLocalHistoryLoaded: {
target: "ready",
actions: "applyLocalHistoryLoaded",
},
ChatNetworkHistoryLoaded: [
{
guard: ({ context, event }) =>
event.type === "ChatNetworkHistoryLoaded" &&
context.paymentUnlockPending &&
shouldPromptUnlockHistory(event.output.messages),
target: "ready",
actions: "showUnlockHistoryPromptFromNetwork",
},
{
target: "ready",
actions: "applyNetworkHistoryLoadedAndClearPayment",
},
],
ChatHistoryLoadFailed: {
target: "ready",
actions: "markHistoryLoadFailed",
},
},
});