Files
Genarrative/src/components/rpg-entry/useRpgCreationEnterWorld.ts
kdletters cbc27bad4a
Some checks failed
CI / verify (push) Has been cancelled
init with react+axum+spacetimedb
2026-04-26 18:06:23 +08:00

110 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useCallback } from 'react';
import type { CustomWorldAgentSessionSnapshot } from '../../../packages/shared/src/contracts/customWorldAgent';
import { rpgCreationPreviewAdapter } from '../../services/rpg-creation/rpgCreationPreviewAdapter';
import type { CustomWorldProfile } from '../../types';
type UseRpgCreationEnterWorldParams = {
isAgentDraftResultView: boolean;
activeAgentSessionId: string | null;
generatedCustomWorldProfile: CustomWorldProfile | null;
agentSessionProfile: CustomWorldProfile | null;
agentSession: CustomWorldAgentSessionSnapshot | null;
handleCustomWorldSelect: (customWorldProfile: CustomWorldProfile) => void;
executePublishWorld: () => Promise<CustomWorldAgentSessionSnapshot | null>;
setGeneratedCustomWorldProfile: (profile: CustomWorldProfile | null) => void;
};
/**
* 统一“进入世界”前的最终同步策略。
* Agent 草稿结果进入游戏时只读 session.draftProfile不再把结果页快照回写成新的运行时 profile。
*/
export function useRpgCreationEnterWorld(
params: UseRpgCreationEnterWorldParams,
) {
const {
isAgentDraftResultView,
activeAgentSessionId,
generatedCustomWorldProfile,
agentSessionProfile,
agentSession,
handleCustomWorldSelect,
executePublishWorld,
setGeneratedCustomWorldProfile,
} = params;
const enterWorldForTestFromCurrentResult = useCallback(async () => {
if (!generatedCustomWorldProfile) {
return;
}
if (!isAgentDraftResultView || !activeAgentSessionId) {
handleCustomWorldSelect(generatedCustomWorldProfile);
return;
}
const latestProfile = agentSessionProfile ?? generatedCustomWorldProfile;
setGeneratedCustomWorldProfile(latestProfile);
handleCustomWorldSelect(latestProfile);
}, [
activeAgentSessionId,
agentSessionProfile,
generatedCustomWorldProfile,
handleCustomWorldSelect,
isAgentDraftResultView,
setGeneratedCustomWorldProfile,
]);
const publishCurrentResult = useCallback(async () => {
if (!generatedCustomWorldProfile) {
return null;
}
if (!isAgentDraftResultView || !activeAgentSessionId) {
return generatedCustomWorldProfile;
}
const latestProfile = agentSessionProfile ?? generatedCustomWorldProfile;
setGeneratedCustomWorldProfile(latestProfile);
const latestSession = agentSession;
const canEnterPublishedWorld =
latestSession?.stage === 'published' &&
latestSession.resultPreview?.canEnterWorld;
if (canEnterPublishedWorld) {
return latestProfile;
}
const publishedSession = await executePublishWorld();
const publishedProfile =
rpgCreationPreviewAdapter.buildPreviewFromSession(publishedSession) ??
latestProfile;
setGeneratedCustomWorldProfile(publishedProfile);
return publishedProfile;
}, [
activeAgentSessionId,
agentSession,
agentSessionProfile,
executePublishWorld,
generatedCustomWorldProfile,
handleCustomWorldSelect,
isAgentDraftResultView,
setGeneratedCustomWorldProfile,
]);
const enterWorldFromCurrentResult = useCallback(async () => {
const publishedProfile = await publishCurrentResult();
if (publishedProfile) {
handleCustomWorldSelect(publishedProfile);
}
}, [handleCustomWorldSelect, publishCurrentResult]);
return {
enterWorldFromCurrentResult,
enterWorldForTestFromCurrentResult,
publishCurrentResult,
};
}