refactor(private-zoom): rename full feature surface

This commit is contained in:
Codex
2026-07-22 18:21:47 +08:00
parent e813333607
commit ed3b34ce1c
102 changed files with 695 additions and 519 deletions
-7
View File
@@ -1,7 +0,0 @@
/** @file Private Room store barrel. */
export * from "./private-room-context";
export * from "./private-room-events";
export * from "./helper";
export * from "./private-room-machine";
export * from "./private-room-state";
@@ -1,8 +0,0 @@
/** Public events for one character-scoped Private Room actor. */
export type PrivateRoomEvent =
| { type: "PrivateRoomInit" }
| { type: "PrivateRoomRefresh" }
| { type: "PrivateRoomUnlockRequested"; albumId: string }
| { type: "PrivateRoomUnlockConfirmed" }
| { type: "PrivateRoomUnlockCancelled" }
| { type: "PrivateRoomUnlockPaywallConsumed" };
@@ -1,18 +0,0 @@
import {
privateRoomMachineSetup,
privateRoomRootStateConfig,
} from "./machine/unlock-flow";
import { createInitialPrivateRoomState } from "./private-room-state";
export type { PrivateRoomEvent } from "./private-room-events";
export type { PrivateRoomState } from "./private-room-state";
export { initialState } from "./private-room-state";
export const privateRoomMachine = privateRoomMachineSetup.createMachine({
id: "privateRoom",
context: ({ input }) =>
createInitialPrivateRoomState(input.characterId),
...privateRoomRootStateConfig,
});
export type PrivateRoomMachine = typeof privateRoomMachine;
@@ -2,18 +2,18 @@ import { describe, expect, it } from "vitest";
import { createActor, waitFor } from "xstate";
import {
createTestPrivateRoomMachine,
loadPrivateRoom,
createTestPrivateZoomMachine,
loadPrivateZoom,
makeAlbum,
makeAlbumsResponse,
TEST_PRIVATE_ROOM_INPUT,
} from "./private-room-machine.test-utils";
TEST_PRIVATE_ZOOM_INPUT,
} from "./private-zoom-machine.test-utils";
describe("private room album flow", () => {
describe("private zoom album flow", () => {
it("loads albums for the supplied character", async () => {
let loadedCharacterId: string | null = null;
const actor = createActor(
createTestPrivateRoomMachine({
createTestPrivateZoomMachine({
onLoad: ({ characterId }) => {
loadedCharacterId = characterId;
},
@@ -21,7 +21,7 @@ describe("private room album flow", () => {
{ input: { characterId: "character_aria" } },
).start();
actor.send({ type: "PrivateRoomInit" });
actor.send({ type: "PrivateZoomInit" });
await waitFor(actor, (snapshot) => snapshot.matches("ready"));
expect(actor.getSnapshot().context.characterId).toBe("character_aria");
@@ -30,7 +30,7 @@ describe("private room album flow", () => {
});
it("loads only the first non-paginated album page", async () => {
const actor = await loadPrivateRoom({
const actor = await loadPrivateZoom({
loadResponse: makeAlbumsResponse({
items: Array.from({ length: 20 }, (_, index) => makeAlbum(index)),
}),
@@ -43,12 +43,12 @@ describe("private room album flow", () => {
it("moves to failed when the album actor rejects", async () => {
const actor = createActor(
createTestPrivateRoomMachine({
createTestPrivateZoomMachine({
loadError: new Error("albums unavailable"),
}),
{ input: TEST_PRIVATE_ROOM_INPUT },
{ input: TEST_PRIVATE_ZOOM_INPUT },
).start();
actor.send({ type: "PrivateRoomInit" });
actor.send({ type: "PrivateZoomInit" });
await waitFor(actor, (snapshot) => snapshot.matches("failed"));
expect(actor.getSnapshot().context.errorMessage).toBe(
"albums unavailable",
@@ -8,13 +8,13 @@ import {
type PrivateAlbumUnlockResponseInput,
type PrivateAlbumsResponse,
type PrivateAlbumsResponseInput,
} from "@/data/schemas/private-room";
import { privateRoomMachine } from "@/stores/private-room/private-room-machine";
} from "@/data/schemas/private-zoom";
import { privateZoomMachine } from "@/stores/private-zoom/private-zoom-machine";
export const ALBUM_ID = "a1b2c3d4-0000-0000-0000-000000000000";
export const COVER_URL =
"https://dbapi.banlv-ai.com/storage/v1/object/public/elio-schedules/01.jpg";
export const TEST_PRIVATE_ROOM_INPUT = {
export const TEST_PRIVATE_ZOOM_INPUT = {
characterId: DEFAULT_CHARACTER_ID,
};
@@ -65,7 +65,7 @@ export function makeUnlockResponse(
});
}
export function createTestPrivateRoomMachine(
export function createTestPrivateZoomMachine(
options: {
loadResponse?: PrivateAlbumsResponse;
unlockResponse?: PrivateAlbumUnlockResponse;
@@ -74,7 +74,7 @@ export function createTestPrivateRoomMachine(
onLoad?: (input: { characterId: string }) => void;
} = {},
) {
return privateRoomMachine.provide({
return privateZoomMachine.provide({
actors: {
loadAlbums: fromPromise<PrivateAlbumsResponse, { characterId: string }>(
async ({ input }) => {
@@ -91,24 +91,24 @@ export function createTestPrivateRoomMachine(
});
}
export async function loadPrivateRoom(
options: Parameters<typeof createTestPrivateRoomMachine>[0] = {},
export async function loadPrivateZoom(
options: Parameters<typeof createTestPrivateZoomMachine>[0] = {},
) {
const actor = createActor(createTestPrivateRoomMachine(options), {
input: TEST_PRIVATE_ROOM_INPUT,
const actor = createActor(createTestPrivateZoomMachine(options), {
input: TEST_PRIVATE_ZOOM_INPUT,
}).start();
actor.send({ type: "PrivateRoomInit" });
actor.send({ type: "PrivateZoomInit" });
await waitFor(actor, (snapshot) => snapshot.matches("ready"));
return actor;
}
export async function unlockFirstAlbum(
actor: Awaited<ReturnType<typeof loadPrivateRoom>>,
actor: Awaited<ReturnType<typeof loadPrivateZoom>>,
) {
actor.send({
type: "PrivateRoomUnlockRequested",
type: "PrivateZoomUnlockRequested",
albumId: ALBUM_ID,
});
actor.send({ type: "PrivateRoomUnlockConfirmed" });
actor.send({ type: "PrivateZoomUnlockConfirmed" });
await waitFor(actor, (snapshot) => snapshot.matches("ready"));
}
@@ -3,14 +3,14 @@ import { describe, expect, it } from "vitest";
import {
ALBUM_ID,
COVER_URL,
loadPrivateRoom,
loadPrivateZoom,
makeUnlockResponse,
unlockFirstAlbum,
} from "./private-room-machine.test-utils";
} from "./private-zoom-machine.test-utils";
describe("private room unlock flow", () => {
describe("private zoom unlock flow", () => {
it("patches album images after a successful unlock", async () => {
const actor = await loadPrivateRoom();
const actor = await loadPrivateZoom();
await unlockFirstAlbum(actor);
expect(actor.getSnapshot().context.items[0]).toMatchObject({
albumId: ALBUM_ID,
@@ -24,7 +24,7 @@ describe("private room unlock flow", () => {
});
it("exposes a paywall request when credits are low", async () => {
const actor = await loadPrivateRoom({
const actor = await loadPrivateZoom({
unlockResponse: makeUnlockResponse({
locked: true,
unlocked: false,
@@ -47,7 +47,7 @@ describe("private room unlock flow", () => {
it("reloads when expected cost changes", async () => {
let loadCount = 0;
const actor = await loadPrivateRoom({
const actor = await loadPrivateZoom({
onLoad: () => {
loadCount += 1;
},
@@ -66,7 +66,7 @@ describe("private room unlock flow", () => {
});
it("removes an album that no longer exists", async () => {
const actor = await loadPrivateRoom({
const actor = await loadPrivateZoom({
unlockResponse: makeUnlockResponse({
locked: true,
unlocked: false,
@@ -80,7 +80,7 @@ describe("private room unlock flow", () => {
});
it("keeps refunded persistence failures locked", async () => {
const actor = await loadPrivateRoom({
const actor = await loadPrivateZoom({
unlockResponse: makeUnlockResponse({
locked: true,
unlocked: false,
@@ -99,7 +99,7 @@ describe("private room unlock flow", () => {
});
it("returns to ready when the unlock actor rejects", async () => {
const actor = await loadPrivateRoom({
const actor = await loadPrivateZoom({
unlockError: new Error("unlock unavailable"),
});
await unlockFirstAlbum(actor);
@@ -3,15 +3,15 @@ import {
PrivateAlbumSchema,
type PrivateAlbumsResponse,
type PrivateAlbumUnlockResponse,
} from "@/data/schemas/private-room";
} from "@/data/schemas/private-zoom";
import type { PrivateRoomState } from "../private-room-state";
import type { PrivateZoomState } from "../private-zoom-state";
export const PRIVATE_ROOM_PAGE_SIZE = 20;
export const PRIVATE_ZOOM_PAGE_SIZE = 20;
export function applyAlbumsResponse(
response: PrivateAlbumsResponse,
): Partial<PrivateRoomState> {
): Partial<PrivateZoomState> {
return {
items: response.items,
creditBalance: response.creditBalance,
@@ -20,7 +20,7 @@ export function applyAlbumsResponse(
}
export function getPendingAlbum(
context: PrivateRoomState,
context: PrivateZoomState,
): PrivateAlbum | null {
if (!context.pendingConfirmAlbumId) return null;
return (
@@ -1,10 +1,10 @@
import type { PrivateAlbumUnlockResponse } from "@/data/schemas/private-room";
import type { PrivateAlbumUnlockResponse } from "@/data/schemas/private-zoom";
import type { PrivateRoomUnlockPaywallRequest } from "../private-room-state";
import type { PrivateZoomUnlockPaywallRequest } from "../private-zoom-state";
export function toPrivateRoomErrorMessage(error: unknown): string {
export function toPrivateZoomErrorMessage(error: unknown): string {
if (error instanceof Error && error.message) return error.message;
return "Private room is temporarily unavailable. Please try again.";
return "Private Zoom is temporarily unavailable. Please try again.";
}
export function toUnlockErrorMessage(
@@ -30,7 +30,7 @@ export function toUnlockErrorMessage(
export function toPaywallRequest(
response: PrivateAlbumUnlockResponse,
): PrivateRoomUnlockPaywallRequest {
): PrivateZoomUnlockPaywallRequest {
return {
albumId: response.albumId,
reason: response.reason,
+7
View File
@@ -0,0 +1,7 @@
/** @file Private Zoom store barrel. */
export * from "./private-zoom-context";
export * from "./private-zoom-events";
export * from "./helper";
export * from "./private-zoom-machine";
export * from "./private-zoom-state";
@@ -3,19 +3,19 @@ import { fromPromise } from "xstate";
import type {
PrivateAlbumsResponse,
PrivateAlbumUnlockResponse,
} from "@/data/schemas/private-room";
import { getPrivateRoomRepository } from "@/data/repositories/private_room_repository";
} from "@/data/schemas/private-zoom";
import { getPrivateZoomRepository } from "@/data/repositories/private_zoom_repository";
import { Result } from "@/utils/result";
import { PRIVATE_ROOM_PAGE_SIZE } from "../../helper/albums";
import { PRIVATE_ZOOM_PAGE_SIZE } from "../../helper/albums";
export const loadPrivateAlbumsActor =
fromPromise<PrivateAlbumsResponse, { characterId: string }>(async ({
input,
}) => {
const result = await getPrivateRoomRepository().getAlbums({
const result = await getPrivateZoomRepository().getAlbums({
characterId: input.characterId,
limit: PRIVATE_ROOM_PAGE_SIZE,
limit: PRIVATE_ZOOM_PAGE_SIZE,
});
if (Result.isErr(result)) throw result.error;
return result.data;
@@ -25,7 +25,7 @@ export const unlockPrivateAlbumActor = fromPromise<
PrivateAlbumUnlockResponse,
{ albumId: string; expectedCost: number }
>(async ({ input }) => {
const result = await getPrivateRoomRepository().unlockAlbum(
const result = await getPrivateZoomRepository().unlockAlbum(
input.albumId,
input.expectedCost,
);
@@ -1,43 +1,43 @@
import type { DoneActorEvent, ErrorActorEvent } from "xstate";
import type { PrivateAlbumsResponse } from "@/data/schemas/private-room";
import type { PrivateAlbumsResponse } from "@/data/schemas/private-zoom";
import { applyAlbumsResponse } from "../helper/albums";
import { toPrivateRoomErrorMessage } from "../helper/unlock";
import { toPrivateZoomErrorMessage } from "../helper/unlock";
import {
basePrivateRoomMachineSetup,
createPrivateRoomActorActionSetup,
basePrivateZoomMachineSetup,
createPrivateZoomActorActionSetup,
} from "./setup";
const clearAlbumLoadStateAction = basePrivateRoomMachineSetup.assign({
const clearAlbumLoadStateAction = basePrivateZoomMachineSetup.assign({
errorMessage: null,
unlockPaywallRequest: null,
});
export const albumMachineSetup = basePrivateRoomMachineSetup.extend({
export const albumMachineSetup = basePrivateZoomMachineSetup.extend({
actions: {
clearAlbumLoadState: clearAlbumLoadStateAction,
},
});
const albumsDoneSetup =
createPrivateRoomActorActionSetup<
createPrivateZoomActorActionSetup<
DoneActorEvent<PrivateAlbumsResponse>
>();
const albumErrorSetup =
createPrivateRoomActorActionSetup<ErrorActorEvent>();
createPrivateZoomActorActionSetup<ErrorActorEvent>();
const applyAlbumsResponseAction = albumsDoneSetup.assign(({ event }) =>
applyAlbumsResponse(event.output),
);
const applyAlbumLoadErrorAction = albumErrorSetup.assign(({ event }) => ({
errorMessage: toPrivateRoomErrorMessage(event.error),
errorMessage: toPrivateZoomErrorMessage(event.error),
}));
export const idleState = albumMachineSetup.createStateConfig({
on: {
PrivateRoomInit: "loading",
PrivateZoomInit: "loading",
},
});
@@ -59,7 +59,7 @@ export const loadingState = albumMachineSetup.createStateConfig({
export const failedState = albumMachineSetup.createStateConfig({
on: {
PrivateRoomInit: "loading",
PrivateRoomRefresh: "loading",
PrivateZoomInit: "loading",
PrivateZoomRefresh: "loading",
},
});
@@ -1,22 +1,22 @@
import { setup, type ActionFunction, type EventObject } from "xstate";
import { getPendingAlbum } from "../helper/albums";
import type { PrivateRoomEvent } from "../private-room-events";
import type { PrivateRoomState } from "../private-room-state";
import type { PrivateZoomEvent } from "../private-zoom-events";
import type { PrivateZoomState } from "../private-zoom-state";
import {
loadPrivateAlbumsActor,
unlockPrivateAlbumActor,
} from "./actors/albums";
export interface PrivateRoomMachineInput {
export interface PrivateZoomMachineInput {
characterId: string;
}
export const basePrivateRoomMachineSetup = setup({
export const basePrivateZoomMachineSetup = setup({
types: {
context: {} as PrivateRoomState,
events: {} as PrivateRoomEvent,
input: {} as PrivateRoomMachineInput,
context: {} as PrivateZoomState,
events: {} as PrivateZoomEvent,
input: {} as PrivateZoomMachineInput,
},
actors: {
loadAlbums: loadPrivateAlbumsActor,
@@ -27,10 +27,10 @@ export const basePrivateRoomMachineSetup = setup({
},
});
type PrivateRoomActorAction<TEvent extends EventObject> = ActionFunction<
PrivateRoomState,
type PrivateZoomActorAction<TEvent extends EventObject> = ActionFunction<
PrivateZoomState,
TEvent,
PrivateRoomEvent,
PrivateZoomEvent,
undefined,
never,
never,
@@ -39,22 +39,22 @@ type PrivateRoomActorAction<TEvent extends EventObject> = ActionFunction<
never
>;
export function createPrivateRoomActorActionSetup<
export function createPrivateZoomActorActionSetup<
TEvent extends EventObject,
>() {
const actorActionSetup = setup({
types: {
context: {} as PrivateRoomState,
context: {} as PrivateZoomState,
events: {} as TEvent,
},
});
return {
assign(
assignment: Parameters<typeof actorActionSetup.assign>[0],
): PrivateRoomActorAction<TEvent> {
): PrivateZoomActorAction<TEvent> {
return actorActionSetup.assign(
assignment,
) as unknown as PrivateRoomActorAction<TEvent>;
) as unknown as PrivateZoomActorAction<TEvent>;
},
};
}
@@ -1,6 +1,6 @@
import type { DoneActorEvent, ErrorActorEvent } from "xstate";
import type { PrivateAlbumUnlockResponse } from "@/data/schemas/private-room";
import type { PrivateAlbumUnlockResponse } from "@/data/schemas/private-zoom";
import {
getPendingAlbum,
@@ -9,7 +9,7 @@ import {
} from "../helper/albums";
import {
toPaywallRequest,
toPrivateRoomErrorMessage,
toPrivateZoomErrorMessage,
toUnlockErrorMessage,
} from "../helper/unlock";
import {
@@ -18,10 +18,10 @@ import {
idleState,
loadingState,
} from "./album-flow";
import { createPrivateRoomActorActionSetup } from "./setup";
import { createPrivateZoomActorActionSetup } from "./setup";
const requestUnlockAction = albumMachineSetup.assign(({ event }) =>
event.type === "PrivateRoomUnlockRequested"
event.type === "PrivateZoomUnlockRequested"
? {
pendingConfirmAlbumId: event.albumId,
unlockErrorMessage: null,
@@ -44,7 +44,7 @@ const beginUnlockAction = albumMachineSetup.assign(({ context }) => ({
unlockPaywallRequest: null,
}));
export const privateRoomMachineSetup = albumMachineSetup.extend({
export const privateZoomMachineSetup = albumMachineSetup.extend({
actions: {
requestUnlock: requestUnlockAction,
cancelUnlock: cancelUnlockAction,
@@ -54,11 +54,11 @@ export const privateRoomMachineSetup = albumMachineSetup.extend({
});
const unlockDoneSetup =
createPrivateRoomActorActionSetup<
createPrivateZoomActorActionSetup<
DoneActorEvent<PrivateAlbumUnlockResponse>
>();
const unlockErrorSetup =
createPrivateRoomActorActionSetup<ErrorActorEvent>();
createPrivateZoomActorActionSetup<ErrorActorEvent>();
const applyUnlockSuccessAction = unlockDoneSetup.assign(
({ context, event }) => ({
@@ -111,26 +111,26 @@ const applyUnlockFailureAction = unlockDoneSetup.assign(
const applyUnlockActorErrorAction = unlockErrorSetup.assign(({ event }) => ({
pendingConfirmAlbumId: null,
unlockingAlbumId: null,
unlockErrorMessage: toPrivateRoomErrorMessage(event.error),
unlockErrorMessage: toPrivateZoomErrorMessage(event.error),
}));
const readyState = privateRoomMachineSetup.createStateConfig({
const readyState = privateZoomMachineSetup.createStateConfig({
on: {
PrivateRoomInit: "loading",
PrivateRoomRefresh: "loading",
PrivateRoomUnlockRequested: { actions: "requestUnlock" },
PrivateRoomUnlockCancelled: { actions: "cancelUnlock" },
PrivateRoomUnlockConfirmed: [
PrivateZoomInit: "loading",
PrivateZoomRefresh: "loading",
PrivateZoomUnlockRequested: { actions: "requestUnlock" },
PrivateZoomUnlockCancelled: { actions: "cancelUnlock" },
PrivateZoomUnlockConfirmed: [
{
guard: "hasPendingAlbum",
target: "unlocking",
},
],
PrivateRoomUnlockPaywallConsumed: { actions: "clearUnlockPaywall" },
PrivateZoomUnlockPaywallConsumed: { actions: "clearUnlockPaywall" },
},
});
const unlockingState = privateRoomMachineSetup.createStateConfig({
const unlockingState = privateZoomMachineSetup.createStateConfig({
entry: "beginUnlock",
invoke: {
src: "unlockAlbum",
@@ -175,8 +175,8 @@ const unlockingState = privateRoomMachineSetup.createStateConfig({
},
});
export const privateRoomRootStateConfig =
privateRoomMachineSetup.createStateConfig({
export const privateZoomRootStateConfig =
privateZoomMachineSetup.createStateConfig({
initial: "idle",
states: {
idle: idleState,
@@ -4,14 +4,14 @@ import type { Dispatch, ReactNode } from "react";
import { createActorContext, shallowEqual } from "@xstate/react";
import type { SnapshotFrom } from "xstate";
import { privateRoomMachine } from "./private-room-machine";
import { privateZoomMachine } from "./private-zoom-machine";
import type {
PrivateRoomEvent,
PrivateRoomState as MachineContext,
} from "./private-room-machine";
PrivateZoomEvent,
PrivateZoomState as MachineContext,
} from "./private-zoom-machine";
/** Route UI reads this projection instead of the Private Room snapshot. */
export interface PrivateRoomContextState {
/** Route UI reads this projection instead of the Private Zoom snapshot. */
export interface PrivateZoomContextState {
characterId: string;
status: string;
items: MachineContext["items"];
@@ -26,45 +26,45 @@ export interface PrivateRoomContextState {
isUnlocking: boolean;
}
type PrivateRoomSnapshot = SnapshotFrom<typeof privateRoomMachine>;
type PrivateRoomSelector<T> = (snapshot: PrivateRoomSnapshot) => T;
type PrivateZoomSnapshot = SnapshotFrom<typeof privateZoomMachine>;
type PrivateZoomSelector<T> = (snapshot: PrivateZoomSnapshot) => T;
const PrivateRoomActorContext = createActorContext(privateRoomMachine);
const PrivateZoomActorContext = createActorContext(privateZoomMachine);
export interface PrivateRoomProviderProps {
export interface PrivateZoomProviderProps {
children: ReactNode;
characterId: string;
}
export function PrivateRoomProvider({
export function PrivateZoomProvider({
children,
characterId,
}: PrivateRoomProviderProps) {
}: PrivateZoomProviderProps) {
return (
<PrivateRoomActorContext.Provider options={{ input: { characterId } }}>
<PrivateZoomActorContext.Provider options={{ input: { characterId } }}>
{children}
</PrivateRoomActorContext.Provider>
</PrivateZoomActorContext.Provider>
);
}
export function usePrivateRoomState(): PrivateRoomContextState {
return usePrivateRoomSelector(selectPrivateRoomState, shallowEqual);
export function usePrivateZoomState(): PrivateZoomContextState {
return usePrivateZoomSelector(selectPrivateZoomState, shallowEqual);
}
export function usePrivateRoomDispatch(): Dispatch<PrivateRoomEvent> {
return PrivateRoomActorContext.useActorRef().send;
export function usePrivateZoomDispatch(): Dispatch<PrivateZoomEvent> {
return PrivateZoomActorContext.useActorRef().send;
}
export function usePrivateRoomSelector<T>(
selector: PrivateRoomSelector<T>,
export function usePrivateZoomSelector<T>(
selector: PrivateZoomSelector<T>,
compare?: (previous: T, next: T) => boolean,
): T {
return PrivateRoomActorContext.useSelector(selector, compare);
return PrivateZoomActorContext.useSelector(selector, compare);
}
function selectPrivateRoomState(
state: PrivateRoomSnapshot,
): PrivateRoomContextState {
function selectPrivateZoomState(
state: PrivateZoomSnapshot,
): PrivateZoomContextState {
return {
characterId: state.context.characterId,
status: String(state.value),
@@ -0,0 +1,8 @@
/** Public events for one character-scoped Private Zoom actor. */
export type PrivateZoomEvent =
| { type: "PrivateZoomInit" }
| { type: "PrivateZoomRefresh" }
| { type: "PrivateZoomUnlockRequested"; albumId: string }
| { type: "PrivateZoomUnlockConfirmed" }
| { type: "PrivateZoomUnlockCancelled" }
| { type: "PrivateZoomUnlockPaywallConsumed" };
@@ -0,0 +1,18 @@
import {
privateZoomMachineSetup,
privateZoomRootStateConfig,
} from "./machine/unlock-flow";
import { createInitialPrivateZoomState } from "./private-zoom-state";
export type { PrivateZoomEvent } from "./private-zoom-events";
export type { PrivateZoomState } from "./private-zoom-state";
export { initialState } from "./private-zoom-state";
export const privateZoomMachine = privateZoomMachineSetup.createMachine({
id: "privateZoom",
context: ({ input }) =>
createInitialPrivateZoomState(input.characterId),
...privateZoomRootStateConfig,
});
export type PrivateZoomMachine = typeof privateZoomMachine;
@@ -1,7 +1,7 @@
import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
import type { PrivateAlbum } from "@/data/schemas/private-room";
import type { PrivateAlbum } from "@/data/schemas/private-zoom";
export interface PrivateRoomUnlockPaywallRequest {
export interface PrivateZoomUnlockPaywallRequest {
albumId: string;
reason: string;
requiredCredits: number;
@@ -9,7 +9,7 @@ export interface PrivateRoomUnlockPaywallRequest {
shortfallCredits: number;
}
export interface PrivateRoomState {
export interface PrivateZoomState {
characterId: string;
items: readonly PrivateAlbum[];
creditBalance: number;
@@ -17,13 +17,13 @@ export interface PrivateRoomState {
unlockingAlbumId: string | null;
unlockErrorMessage: string | null;
pendingConfirmAlbumId: string | null;
unlockPaywallRequest: PrivateRoomUnlockPaywallRequest | null;
unlockPaywallRequest: PrivateZoomUnlockPaywallRequest | null;
unlockSuccessNonce: number;
}
export function createInitialPrivateRoomState(
export function createInitialPrivateZoomState(
characterId: string,
): PrivateRoomState {
): PrivateZoomState {
return {
characterId,
items: [],
@@ -37,4 +37,4 @@ export function createInitialPrivateRoomState(
};
}
export const initialState = createInitialPrivateRoomState(DEFAULT_CHARACTER_ID);
export const initialState = createInitialPrivateZoomState(DEFAULT_CHARACTER_ID);