diff --git a/src/app/splash/components/splash-content.tsx b/src/app/splash/components/splash-content.tsx
index f91c21e0..c83b1d40 100644
--- a/src/app/splash/components/splash-content.tsx
+++ b/src/app/splash/components/splash-content.tsx
@@ -4,11 +4,11 @@
const APOSTROPHE = "'";
-export function SplashContent() {
+export function SplashContent({ characterName }: { characterName: string }) {
return (
- Welcome to my secret hideout~
+ Welcome to {characterName}{APOSTROPHE}s secret hideout~
{"\n"}It{APOSTROPHE}s just the two of us now.
{"\n"}Feel free to whisper your
{"\n"}little secrets.
diff --git a/src/app/splash/hooks/__tests__/use-splash-latest-message.test.tsx b/src/app/splash/hooks/__tests__/use-splash-latest-message.test.tsx
index c0d75b9e..6c4b13ae 100644
--- a/src/app/splash/hooks/__tests__/use-splash-latest-message.test.tsx
+++ b/src/app/splash/hooks/__tests__/use-splash-latest-message.test.tsx
@@ -26,6 +26,7 @@ import { useSplashLatestMessage } from "../use-splash-latest-message";
function LatestMessageHarness() {
const state = useSplashLatestMessage({
+ characterId: "character_maya",
hasInitialized: true,
isAuthLoading: false,
loginStatus: "facebook",
@@ -64,5 +65,9 @@ describe("useSplashLatestMessage hydration", () => {
expect(hydrationErrors).toEqual([]);
expect(container.textContent).toBe("Loading");
expect(mocks.loadLatestMessage).toHaveBeenCalledOnce();
+ expect(mocks.loadLatestMessage).toHaveBeenCalledWith({
+ cache: mocks.cache,
+ characterId: "character_maya",
+ });
});
});
diff --git a/src/app/splash/hooks/use-splash-latest-message.ts b/src/app/splash/hooks/use-splash-latest-message.ts
index 5f39426b..8d25a17c 100644
--- a/src/app/splash/hooks/use-splash-latest-message.ts
+++ b/src/app/splash/hooks/use-splash-latest-message.ts
@@ -3,7 +3,6 @@
import { useEffect, useState } from "react";
import type { LoginStatus } from "@/data/schemas/auth";
-import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
import { useHasHydrated } from "@/hooks/use-has-hydrated";
import { loadSplashLatestMessagePreview } from "@/lib/chat/splash_latest_message";
import { useSplashLatestMessageCache } from "@/providers/splash-latest-message-provider";
@@ -13,7 +12,7 @@ import { Result } from "@/utils/result";
const log = new Logger("SplashLatestMessage");
export interface UseSplashLatestMessageInput {
- characterId?: string;
+ characterId: string;
hasInitialized: boolean;
isAuthLoading: boolean;
loginStatus: LoginStatus;
@@ -31,7 +30,7 @@ interface SplashLatestMessageState {
}
export function useSplashLatestMessage({
- characterId = DEFAULT_CHARACTER_ID,
+ characterId,
hasInitialized,
isAuthLoading,
loginStatus,
diff --git a/src/app/splash/splash-screen.tsx b/src/app/splash/splash-screen.tsx
index 46811eac..af60d438 100644
--- a/src/app/splash/splash-screen.tsx
+++ b/src/app/splash/splash-screen.tsx
@@ -65,12 +65,12 @@ export function SplashScreen() {
isLoading={latestMessage.isLoading}
onOpenChat={handleStartChat}
/>
-
+
- {character.displayName}, {character.copy.splashRelationship}
+ {character.displayName}, {character.tagline}
24/7 online | Chat | Companion | Heal | Sweet moments
diff --git a/src/providers/__tests__/character-actor-scope-providers.test.tsx b/src/providers/__tests__/character-actor-scope-providers.test.tsx
index 8f90ca07..4cae9214 100644
--- a/src/providers/__tests__/character-actor-scope-providers.test.tsx
+++ b/src/providers/__tests__/character-actor-scope-providers.test.tsx
@@ -145,7 +145,10 @@ describe("character actor route providers", () => {
function renderChat(characterId: string): void {
act(() => {
root.render(
-
+
chat
,
);
diff --git a/src/providers/character-provider.tsx b/src/providers/character-provider.tsx
index 11000c3f..02f4dd7e 100644
--- a/src/providers/character-provider.tsx
+++ b/src/providers/character-provider.tsx
@@ -2,13 +2,10 @@
import { createContext, type ReactNode, useContext } from "react";
-import {
- DEFAULT_CHARACTER,
- type CharacterProfile,
-} from "@/data/constants/character";
+import type { CharacterProfile } from "@/data/constants/character";
import { getCharacterRoutes, type CharacterRoutes } from "@/router/routes";
-const CharacterContext = createContext(DEFAULT_CHARACTER);
+const CharacterContext = createContext(null);
export interface CharacterProviderProps {
character: CharacterProfile;
@@ -27,7 +24,11 @@ export function CharacterProvider({
}
export function useActiveCharacter(): CharacterProfile {
- return useContext(CharacterContext);
+ const character = useContext(CharacterContext);
+ if (!character) {
+ throw new Error("useActiveCharacter must be used within CharacterProvider.");
+ }
+ return character;
}
export function useActiveCharacterRoutes(): CharacterRoutes {
diff --git a/src/providers/chat-route-providers.tsx b/src/providers/chat-route-providers.tsx
index 1faa7da0..b0991721 100644
--- a/src/providers/chat-route-providers.tsx
+++ b/src/providers/chat-route-providers.tsx
@@ -2,7 +2,6 @@
import type { ReactNode } from "react";
-import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
import { ChatProvider } from "@/stores/chat/chat-context";
import { PaymentProvider } from "@/stores/payment/payment-context";
import { ChatAuthSync } from "@/stores/sync/chat-auth-sync";
@@ -11,17 +10,23 @@ import { PaymentSuccessSync } from "@/stores/sync/payment-success-sync";
export interface ChatRouteProvidersProps {
children: ReactNode;
- characterId?: string;
+ characterId: string;
+ emptyChatGreeting: string;
}
export function ChatRouteProviders({
children,
- characterId = DEFAULT_CHARACTER_ID,
+ characterId,
+ emptyChatGreeting,
}: ChatRouteProvidersProps) {
return (
-
+
{children}
diff --git a/src/providers/private-room-route-provider.tsx b/src/providers/private-room-route-provider.tsx
index ebec0732..0dfc729c 100644
--- a/src/providers/private-room-route-provider.tsx
+++ b/src/providers/private-room-route-provider.tsx
@@ -2,17 +2,16 @@
import type { ReactNode } from "react";
-import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
import { PrivateRoomProvider } from "@/stores/private-room";
export interface PrivateRoomRouteProviderProps {
children: ReactNode;
- characterId?: string;
+ characterId: string;
}
export function PrivateRoomRouteProvider({
children,
- characterId = DEFAULT_CHARACTER_ID,
+ characterId,
}: PrivateRoomRouteProviderProps) {
return (
diff --git a/src/stores/chat/__tests__/chat-actor-cancellation.test.ts b/src/stores/chat/__tests__/chat-actor-cancellation.test.ts
index 22003c3c..268c47ca 100644
--- a/src/stores/chat/__tests__/chat-actor-cancellation.test.ts
+++ b/src/stores/chat/__tests__/chat-actor-cancellation.test.ts
@@ -62,15 +62,18 @@ describe("chat actor request cancellation", () => {
() => new Promise(() => undefined),
);
const actor = createActor(loadHistoryActor, {
- input: { characterId: "character_elio" },
+ input: {
+ characterId: "character_elio",
+ emptyChatGreeting: "Hello from Elio",
+ },
}).start();
await vi.waitFor(() =>
expect(historySync.syncNetworkHistory).toHaveBeenCalled(),
);
- const signal = getSignal(
- historySync.syncNetworkHistory.mock.calls[0]?.[3],
- );
+ const historyCall = historySync.syncNetworkHistory.mock.calls[0];
+ expect(historyCall?.[3]).toBe("Hello from Elio");
+ const signal = getSignal(historyCall?.[4]);
expect(signal.aborted).toBe(false);
actor.stop();
expect(signal.aborted).toBe(true);
@@ -81,7 +84,10 @@ describe("chat actor request cancellation", () => {
() => new Promise(() => undefined),
);
const actor = createActor(unlockHistoryActor, {
- input: { characterId: "character_elio" },
+ input: {
+ characterId: "character_elio",
+ emptyChatGreeting: "Hello from Elio",
+ },
}).start();
await vi.waitFor(() => expect(repository.unlockHistory).toHaveBeenCalled());
diff --git a/src/stores/chat/__tests__/chat-helpers.test.ts b/src/stores/chat/__tests__/chat-helpers.test.ts
index ff987929..e219d0df 100644
--- a/src/stores/chat/__tests__/chat-helpers.test.ts
+++ b/src/stores/chat/__tests__/chat-helpers.test.ts
@@ -1,6 +1,9 @@
import { describe, expect, it } from "vitest";
-import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
+import {
+ DEFAULT_CHARACTER,
+ DEFAULT_CHARACTER_ID,
+} from "@/data/constants/character";
import {
ChatSendResponseSchema,
type ChatSendResponse,
@@ -35,6 +38,7 @@ function makeResponse(
function makeChatState(overrides: Partial = {}): ChatState {
return {
characterId: DEFAULT_CHARACTER_ID,
+ emptyChatGreeting: DEFAULT_CHARACTER.emptyChatGreeting,
messages: [],
promotion: null,
outgoingMessageRevision: 0,
diff --git a/src/stores/chat/__tests__/chat-history-flow.test.ts b/src/stores/chat/__tests__/chat-history-flow.test.ts
index 02e85fb6..865d962c 100644
--- a/src/stores/chat/__tests__/chat-history-flow.test.ts
+++ b/src/stores/chat/__tests__/chat-history-flow.test.ts
@@ -4,7 +4,10 @@ import { createActor, fromCallback, waitFor } from "xstate";
import type { UiMessage } from "@/stores/chat/ui-message";
import type { ChatEvent } from "@/stores/chat/chat-events";
import { chatMachine } from "@/stores/chat/chat-machine";
-import type { LoadMoreHistoryActorEvent } from "@/stores/chat/machine/actors/history";
+import type {
+ ChatHistoryActorInput,
+ LoadMoreHistoryActorEvent,
+} from "@/stores/chat/machine/actors/history";
import {
createLoadHistoryCallback,
@@ -50,7 +53,7 @@ describe("chat history flow", () => {
actors: {
loadHistory: fromCallback<
ChatEvent,
- { characterId: string }
+ ChatHistoryActorInput
>(({ sendBack }) => {
sendBack({
type: "ChatLocalHistoryLoaded",
@@ -119,7 +122,7 @@ describe("chat history flow", () => {
),
loadMoreHistory: fromCallback<
LoadMoreHistoryActorEvent,
- { characterId: string }
+ ChatHistoryActorInput
>(
({ receive, sendBack }) => {
receive((event) => {
@@ -198,7 +201,7 @@ describe("chat history flow", () => {
}),
loadMoreHistory: fromCallback<
LoadMoreHistoryActorEvent,
- { characterId: string }
+ ChatHistoryActorInput
>(
({ receive, sendBack }) => {
receive((event) => {
@@ -260,7 +263,7 @@ describe("chat history flow", () => {
}),
loadMoreHistory: fromCallback<
LoadMoreHistoryActorEvent,
- { characterId: string }
+ ChatHistoryActorInput
>(
({ receive }) => {
receive(() => {
diff --git a/src/stores/chat/__tests__/chat-machine.test-utils.ts b/src/stores/chat/__tests__/chat-machine.test-utils.ts
index 3e88b630..6553f5f7 100644
--- a/src/stores/chat/__tests__/chat-machine.test-utils.ts
+++ b/src/stores/chat/__tests__/chat-machine.test-utils.ts
@@ -1,6 +1,9 @@
import { fromCallback, fromPromise } from "xstate";
-import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
+import {
+ DEFAULT_CHARACTER,
+ DEFAULT_CHARACTER_ID,
+} from "@/data/constants/character";
import {
ChatSendResponseSchema,
UnlockPrivateResponseSchema,
@@ -36,6 +39,7 @@ export interface TestUnlockMessageOutput {
export const TEST_CHAT_MACHINE_INPUT = {
characterId: DEFAULT_CHARACTER_ID,
+ emptyChatGreeting: DEFAULT_CHARACTER.emptyChatGreeting,
};
export function makeChatSendResponse(): ChatSendResponse {
@@ -109,7 +113,10 @@ export function createTestChatMachine(
return () => undefined;
},
),
- unlockHistory: fromPromise(
+ unlockHistory: fromPromise<
+ UnlockHistoryOutput,
+ { characterId: string; emptyChatGreeting: string }
+ >(
async () => {
if (options.unlockHistoryError) {
throw options.unlockHistoryError;
diff --git a/src/stores/chat/__tests__/chat-send-flow.test.ts b/src/stores/chat/__tests__/chat-send-flow.test.ts
index e75168a4..d60b2c25 100644
--- a/src/stores/chat/__tests__/chat-send-flow.test.ts
+++ b/src/stores/chat/__tests__/chat-send-flow.test.ts
@@ -155,7 +155,7 @@ describe("chat send flow", () => {
),
unlockHistory: fromPromise<
UnlockHistoryOutput,
- { characterId: string }
+ { characterId: string; emptyChatGreeting: string }
>(async () => ({
unlocked: true,
reason: "ok",
diff --git a/src/stores/chat/__tests__/chat-session-flow.test.ts b/src/stores/chat/__tests__/chat-session-flow.test.ts
index dd44aa30..56b48bc3 100644
--- a/src/stores/chat/__tests__/chat-session-flow.test.ts
+++ b/src/stores/chat/__tests__/chat-session-flow.test.ts
@@ -9,10 +9,43 @@ import {
describe("chat session flow", () => {
it("initializes the conversation from the supplied character", () => {
const actor = createActor(createTestChatMachine(), {
- input: { characterId: "character_aria" },
+ input: {
+ characterId: "character_maya",
+ emptyChatGreeting: "Hello from Maya",
+ },
}).start();
- expect(actor.getSnapshot().context.characterId).toBe("character_aria");
+ expect(actor.getSnapshot().context).toMatchObject({
+ characterId: "character_maya",
+ emptyChatGreeting: "Hello from Maya",
+ });
+ actor.stop();
+ });
+
+ it("keeps the active character greeting across login state changes", async () => {
+ const actor = createActor(createTestChatMachine(), {
+ input: {
+ characterId: "character_maya",
+ emptyChatGreeting: "Hello from Maya",
+ },
+ }).start();
+
+ actor.send({ type: "ChatUserLogin", token: "token" });
+ await waitFor(actor, (snapshot) =>
+ snapshot.matches({ userSession: "ready" }),
+ );
+ expect(actor.getSnapshot().context.emptyChatGreeting).toBe(
+ "Hello from Maya",
+ );
+
+ actor.send({ type: "ChatGuestLogin" });
+ await waitFor(actor, (snapshot) =>
+ snapshot.matches({ guestSession: "ready" }),
+ );
+ expect(actor.getSnapshot().context.emptyChatGreeting).toBe(
+ "Hello from Maya",
+ );
+
actor.stop();
});
diff --git a/src/stores/chat/chat-context.tsx b/src/stores/chat/chat-context.tsx
index 5a7b47e5..7dd233ba 100644
--- a/src/stores/chat/chat-context.tsx
+++ b/src/stores/chat/chat-context.tsx
@@ -4,8 +4,6 @@ import { type Dispatch, type ReactNode, useMemo } from "react";
import { createActorContext, shallowEqual } from "@xstate/react";
import type { SnapshotFrom } from "xstate";
-import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
-
import { chatMachine } from "./chat-machine";
import type { ChatEvent, ChatState as MachineContext } from "./chat-machine";
import { appendPromotionMessage } from "./helper/promotion";
@@ -46,15 +44,19 @@ const ChatActorContext = createActorContext(chatMachine);
export interface ChatProviderProps {
children: ReactNode;
- characterId?: string;
+ characterId: string;
+ emptyChatGreeting: string;
}
export function ChatProvider({
children,
- characterId = DEFAULT_CHARACTER_ID,
+ characterId,
+ emptyChatGreeting,
}: ChatProviderProps) {
return (
-
+
{children}
);
diff --git a/src/stores/chat/chat-history-sync.ts b/src/stores/chat/chat-history-sync.ts
index 2f2b1f5e..d221c6a7 100644
--- a/src/stores/chat/chat-history-sync.ts
+++ b/src/stores/chat/chat-history-sync.ts
@@ -30,12 +30,9 @@ export type LocalHistorySnapshotOutput = {
export type NetworkHistorySyncOutput = ReadAndSyncHistoryOutput;
-export function createGreetingMessage(): UiMessage {
+export function createGreetingMessage(content: string): UiMessage {
return {
- content:
- "You're here! Facebook is so restrictive, " +
- "there were things I couldn't say there. " +
- "Finally I can relax. How was your day out?",
+ content,
isFromAI: true,
date: todayString(),
isSynthetic: true,
@@ -51,9 +48,10 @@ export async function resolveHistoryCacheIdentity(
export async function readLocalHistorySnapshot(
cacheIdentity: string | null,
+ emptyChatGreeting: string,
): Promise {
const chatRepo = await loadChatRepository();
- const greetingMessage = createGreetingMessage();
+ const greetingMessage = createGreetingMessage(emptyChatGreeting);
const localResult = cacheIdentity
? await chatRepo.getLocalMessages(cacheIdentity)
@@ -82,10 +80,11 @@ export async function syncNetworkHistory(
characterId: string,
localCount: number,
cacheIdentity: string | null,
+ emptyChatGreeting: string,
signal?: AbortSignal,
): Promise {
const chatRepo = await loadChatRepository();
- const greetingMessage = createGreetingMessage();
+ const greetingMessage = createGreetingMessage(emptyChatGreeting);
const networkResult = await chatRepo.getHistory(
characterId,
@@ -149,14 +148,19 @@ export async function syncNetworkHistory(
*/
export async function readAndSyncHistory(
characterId: string,
+ emptyChatGreeting: string,
signal?: AbortSignal,
): Promise {
const cacheIdentity = await resolveHistoryCacheIdentity(characterId);
- const localSnapshot = await readLocalHistorySnapshot(cacheIdentity);
+ const localSnapshot = await readLocalHistorySnapshot(
+ cacheIdentity,
+ emptyChatGreeting,
+ );
const networkSnapshot = await syncNetworkHistory(
characterId,
localSnapshot.localCount,
cacheIdentity,
+ emptyChatGreeting,
signal,
);
if (networkSnapshot) return networkSnapshot;
diff --git a/src/stores/chat/chat-machine.ts b/src/stores/chat/chat-machine.ts
index d40d8352..77b18203 100644
--- a/src/stores/chat/chat-machine.ts
+++ b/src/stores/chat/chat-machine.ts
@@ -2,7 +2,10 @@ import {
chatMachineSetup,
chatRootStateConfig,
} from "./machine/session-flow";
-import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
+import {
+ DEFAULT_CHARACTER,
+ DEFAULT_CHARACTER_ID,
+} from "@/data/constants/character";
import { createInitialChatState } from "./chat-state";
@@ -13,7 +16,10 @@ export type { ChatEvent } from "./chat-events";
export const chatMachine = chatMachineSetup.createMachine({
id: "chat",
context: ({ input }) =>
- createInitialChatState(input?.characterId ?? DEFAULT_CHARACTER_ID),
+ createInitialChatState(
+ input?.characterId ?? DEFAULT_CHARACTER_ID,
+ input?.emptyChatGreeting ?? DEFAULT_CHARACTER.emptyChatGreeting,
+ ),
...chatRootStateConfig,
});
diff --git a/src/stores/chat/chat-state.ts b/src/stores/chat/chat-state.ts
index 96e8a74c..79c679e0 100644
--- a/src/stores/chat/chat-state.ts
+++ b/src/stores/chat/chat-state.ts
@@ -2,7 +2,10 @@ import type { UiMessage } from "@/stores/chat/ui-message";
import type { PendingChatUnlockKind } from "@/lib/navigation/chat_unlock_session";
import type { ChatLockType } from "@/data/schemas/chat";
import type { PendingChatPromotion } from "@/data/storage/navigation";
-import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
+import {
+ DEFAULT_CHARACTER,
+ DEFAULT_CHARACTER_ID,
+} from "@/data/constants/character";
import type { ChatPromotionState } from "./helper/promotion";
export type ChatUpgradeReason = "insufficient_credits";
@@ -26,6 +29,7 @@ export interface ChatUnlockPaywallRequest
export interface ChatState {
characterId: string;
+ emptyChatGreeting: string;
messages: UiMessage[];
promotion: ChatPromotionState | null;
outgoingMessageRevision: number;
@@ -55,9 +59,11 @@ export interface ChatState {
export function createInitialChatState(
characterId: string = DEFAULT_CHARACTER_ID,
+ emptyChatGreeting: string = DEFAULT_CHARACTER.emptyChatGreeting,
): ChatState {
return {
characterId,
+ emptyChatGreeting,
messages: [],
promotion: null,
outgoingMessageRevision: 0,
diff --git a/src/stores/chat/machine/actors/history.ts b/src/stores/chat/machine/actors/history.ts
index ae47815d..02b2d78b 100644
--- a/src/stores/chat/machine/actors/history.ts
+++ b/src/stores/chat/machine/actors/history.ts
@@ -25,6 +25,7 @@ export interface LoadMoreHistoryActorEvent {
export interface ChatHistoryActorInput {
characterId: string;
+ emptyChatGreeting: string;
}
export interface LoadMoreHistoryOutput {
@@ -43,7 +44,10 @@ export const loadHistoryActor = fromCallback<
void (async () => {
const cacheIdentity = await resolveHistoryCacheIdentity(input.characterId);
- const localSnapshot = await readLocalHistorySnapshot(cacheIdentity);
+ const localSnapshot = await readLocalHistorySnapshot(
+ cacheIdentity,
+ input.emptyChatGreeting,
+ );
if (cancelled) return;
sendBack({
type: "ChatLocalHistoryLoaded",
@@ -54,6 +58,7 @@ export const loadHistoryActor = fromCallback<
input.characterId,
localSnapshot.localCount,
cacheIdentity,
+ input.emptyChatGreeting,
controller.signal,
);
if (cancelled || !networkSnapshot) return;
diff --git a/src/stores/chat/machine/actors/unlock.ts b/src/stores/chat/machine/actors/unlock.ts
index 0463d959..c89434cb 100644
--- a/src/stores/chat/machine/actors/unlock.ts
+++ b/src/stores/chat/machine/actors/unlock.ts
@@ -25,7 +25,7 @@ export interface UnlockHistoryOutput {
export const unlockHistoryActor = fromPromise<
UnlockHistoryOutput,
- { characterId: string }
+ { characterId: string; emptyChatGreeting: string }
>(async ({ input, signal }) => {
const chatRepo = await loadChatRepository();
const unlockResult = await chatRepo.unlockHistory(input.characterId, {
@@ -40,7 +40,11 @@ export const unlockHistoryActor = fromPromise<
}
signal.throwIfAborted();
- const history = await readAndSyncHistory(input.characterId, signal);
+ const history = await readAndSyncHistory(
+ input.characterId,
+ input.emptyChatGreeting,
+ signal,
+ );
return {
unlocked: unlockResult.data.unlocked,
reason: unlockResult.data.reason,
diff --git a/src/stores/chat/machine/session-flow.ts b/src/stores/chat/machine/session-flow.ts
index 27990ba4..1bd60522 100644
--- a/src/stores/chat/machine/session-flow.ts
+++ b/src/stores/chat/machine/session-flow.ts
@@ -19,20 +19,26 @@ import {
const startGuestSessionAction = unlockMachineSetup.assign(
({ context }) => ({
- ...createInitialChatState(context.characterId),
+ ...createInitialChatState(
+ context.characterId,
+ context.emptyChatGreeting,
+ ),
promotion: context.promotion,
}),
);
const startUserSessionAction = unlockMachineSetup.assign(
({ context }) => ({
- ...createInitialChatState(context.characterId),
+ ...createInitialChatState(
+ context.characterId,
+ context.emptyChatGreeting,
+ ),
promotion: context.promotion,
}),
);
const clearChatSessionAction = unlockMachineSetup.assign(({ context }) => ({
- ...createInitialChatState(context.characterId),
+ ...createInitialChatState(context.characterId, context.emptyChatGreeting),
}));
const injectPromotionAction = unlockMachineSetup.assign(({ event }) => {
@@ -80,12 +86,18 @@ const guestSessionState = chatMachineSetup.createStateConfig({
{
id: "loadHistory",
src: "loadHistory",
- input: ({ context }) => ({ characterId: context.characterId }),
+ input: ({ context }) => ({
+ characterId: context.characterId,
+ emptyChatGreeting: context.emptyChatGreeting,
+ }),
},
{
id: "loadMoreHistory",
src: "loadMoreHistory",
- input: ({ context }) => ({ characterId: context.characterId }),
+ input: ({ context }) => ({
+ characterId: context.characterId,
+ emptyChatGreeting: context.emptyChatGreeting,
+ }),
},
],
on: {
@@ -162,12 +174,18 @@ const userSessionState = chatMachineSetup.createStateConfig({
{
id: "loadHistory",
src: "loadHistory",
- input: ({ context }) => ({ characterId: context.characterId }),
+ input: ({ context }) => ({
+ characterId: context.characterId,
+ emptyChatGreeting: context.emptyChatGreeting,
+ }),
},
{
id: "loadMoreHistory",
src: "loadMoreHistory",
- input: ({ context }) => ({ characterId: context.characterId }),
+ input: ({ context }) => ({
+ characterId: context.characterId,
+ emptyChatGreeting: context.emptyChatGreeting,
+ }),
},
],
on: {
diff --git a/src/stores/chat/machine/setup.ts b/src/stores/chat/machine/setup.ts
index 03c07cd9..bfc1fefd 100644
--- a/src/stores/chat/machine/setup.ts
+++ b/src/stores/chat/machine/setup.ts
@@ -17,6 +17,7 @@ import type { ChatState } from "../chat-state";
export interface ChatMachineInput {
characterId?: string;
+ emptyChatGreeting?: string;
}
export const baseChatMachineSetup = setup({
diff --git a/src/stores/chat/machine/unlock-flow.ts b/src/stores/chat/machine/unlock-flow.ts
index 5b8dbde4..5d46cfce 100644
--- a/src/stores/chat/machine/unlock-flow.ts
+++ b/src/stores/chat/machine/unlock-flow.ts
@@ -188,7 +188,10 @@ export const unlockingHistoryState = unlockMachineSetup.createStateConfig({
invoke: {
id: "unlockHistory",
src: "unlockHistory",
- input: ({ context }) => ({ characterId: context.characterId }),
+ input: ({ context }) => ({
+ characterId: context.characterId,
+ emptyChatGreeting: context.emptyChatGreeting,
+ }),
onDone: {
target: "ready",
actions: applyUnlockHistoryOutputAction,
diff --git a/src/stores/private-room/private-room-context.tsx b/src/stores/private-room/private-room-context.tsx
index 3038ba2e..02e2dbe7 100644
--- a/src/stores/private-room/private-room-context.tsx
+++ b/src/stores/private-room/private-room-context.tsx
@@ -4,8 +4,6 @@ import type { Dispatch, ReactNode } from "react";
import { createActorContext, shallowEqual } from "@xstate/react";
import type { SnapshotFrom } from "xstate";
-import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
-
import { privateRoomMachine } from "./private-room-machine";
import type {
PrivateRoomEvent,
@@ -34,12 +32,12 @@ const PrivateRoomActorContext = createActorContext(privateRoomMachine);
export interface PrivateRoomProviderProps {
children: ReactNode;
- characterId?: string;
+ characterId: string;
}
export function PrivateRoomProvider({
children,
- characterId = DEFAULT_CHARACTER_ID,
+ characterId,
}: PrivateRoomProviderProps) {
return (