refactor(stores): tighten chat and payment boundaries

This commit is contained in:
2026-07-01 10:12:19 +08:00
parent b7bccaa4cf
commit 5d9ed7e027
9 changed files with 435 additions and 431 deletions
+56
View File
@@ -0,0 +1,56 @@
import type { UiMessage, UnlockPrivateResponse } from "@/data/dto/chat";
export interface UnlockMessageOutput {
messageId: string;
response: UnlockPrivateResponse;
}
export function countLockedHistoryMessages(messages: readonly UiMessage[]): number {
return messages.filter(isUnlockableLockedMessage).length;
}
export function applySingleUnlockOutput(
messages: readonly UiMessage[],
output: UnlockMessageOutput,
): UiMessage[] {
if (!output.response.unlocked) return [...messages];
return messages.map((message) => {
if (message.id !== output.messageId) return message;
const nextContent =
output.response.content.length > 0
? output.response.content
: message.content;
return {
...message,
content: nextContent,
locked: output.response.lockDetail.locked,
lockReason: output.response.lockDetail.reason,
imagePaywalled: message.imageUrl
? output.response.lockDetail.locked &&
output.response.lockDetail.showUpgrade
: undefined,
lockedPrivate: false,
privateMessageHint: null,
};
});
}
export function shouldAutoUnlockHistory(messages: readonly UiMessage[]): boolean {
return countLockedHistoryMessages(messages) === 1;
}
export function shouldPromptUnlockHistory(messages: readonly UiMessage[]): boolean {
return countLockedHistoryMessages(messages) > 1;
}
function isUnlockableLockedMessage(message: UiMessage): boolean {
if (!message.isFromAI || message.locked !== true) return false;
if (message.imagePaywalled === true) return true;
return (
message.lockReason === "private_message" ||
message.lockReason === "voice_message"
);
}