feat(chat): add composer action menu
This commit is contained in:
@@ -5,7 +5,10 @@ import memoryDriver from "unstorage/drivers/memory";
|
||||
import { StorageKeys } from "@/data/storage/storage_keys";
|
||||
import { SessionAsyncUtil } from "@/utils/session-storage";
|
||||
|
||||
import { NavigationStorage } from "../navigation_storage";
|
||||
import {
|
||||
createPendingChatPromotion,
|
||||
NavigationStorage,
|
||||
} from "../navigation_storage";
|
||||
|
||||
const CHARACTER_ID = "elio";
|
||||
const OTHER_CHARACTER_ID = "maya-tan";
|
||||
@@ -105,6 +108,28 @@ describe("NavigationStorage", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("creates manual promotions without persisting them", async () => {
|
||||
const image = createPendingChatPromotion("image", CHARACTER_ID);
|
||||
const voice = createPendingChatPromotion("voice", CHARACTER_ID);
|
||||
|
||||
expect(image).toMatchObject({
|
||||
characterId: CHARACTER_ID,
|
||||
promotionType: "image",
|
||||
lockType: "image_paywall",
|
||||
});
|
||||
expect(voice).toMatchObject({
|
||||
characterId: CHARACTER_ID,
|
||||
promotionType: "voice",
|
||||
lockType: "voice_message",
|
||||
});
|
||||
expect(image.clientLockId).toMatch(/^promotion_/);
|
||||
expect(voice.clientLockId).toMatch(/^promotion_/);
|
||||
expect(voice.clientLockId).not.toBe(image.clientLockId);
|
||||
await expect(
|
||||
NavigationStorage.consumePendingChatPromotion(CHARACTER_ID),
|
||||
).resolves.toBeNull();
|
||||
});
|
||||
|
||||
it("saves and consumes pending chat image return sessions", async () => {
|
||||
await NavigationStorage.savePendingChatImageReturn({
|
||||
characterId: CHARACTER_ID,
|
||||
|
||||
@@ -69,6 +69,19 @@ export type PendingChatImageReturn = z.output<
|
||||
typeof PendingChatImageReturnSchema
|
||||
>;
|
||||
|
||||
export function createPendingChatPromotion(
|
||||
promotionType: PendingChatPromotionType,
|
||||
characterId: string,
|
||||
): PendingChatPromotion {
|
||||
return PendingChatPromotionSchema.parse({
|
||||
characterId,
|
||||
promotionType,
|
||||
lockType: toPromotionLockType(promotionType),
|
||||
clientLockId: `promotion_${createUuidV4()}`,
|
||||
createdAt: Date.now(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* NavigationStorage owns short-lived cross-route sessions.
|
||||
*
|
||||
@@ -180,13 +193,10 @@ export class NavigationStorage {
|
||||
promotionType: PendingChatPromotionType,
|
||||
characterId: string,
|
||||
): Promise<PendingChatPromotion> {
|
||||
const promotion: PendingChatPromotion = {
|
||||
characterId,
|
||||
const promotion = createPendingChatPromotion(
|
||||
promotionType,
|
||||
lockType: toPromotionLockType(promotionType),
|
||||
clientLockId: `promotion_${createUuidV4()}`,
|
||||
createdAt: Date.now(),
|
||||
};
|
||||
characterId,
|
||||
);
|
||||
await SessionAsyncUtil.setJson(
|
||||
StorageKeys.pendingChatPromotion,
|
||||
promotion,
|
||||
|
||||
Reference in New Issue
Block a user