93 lines
2.9 KiB
TypeScript
93 lines
2.9 KiB
TypeScript
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>;
|
||
syncAgentDraftResultProfile: (
|
||
profile: CustomWorldProfile,
|
||
) => Promise<{
|
||
profile: CustomWorldProfile | null;
|
||
session: CustomWorldAgentSessionSnapshot | null;
|
||
}>;
|
||
setGeneratedCustomWorldProfile: (profile: CustomWorldProfile | null) => void;
|
||
};
|
||
|
||
/**
|
||
* 统一“进入世界”前的最终同步策略。
|
||
* 非 Agent 草稿结果直接进入;Agent 草稿结果必须先把当前结果页并回 session。
|
||
*/
|
||
export function useRpgCreationEnterWorld(
|
||
params: UseRpgCreationEnterWorldParams,
|
||
) {
|
||
const {
|
||
isAgentDraftResultView,
|
||
activeAgentSessionId,
|
||
generatedCustomWorldProfile,
|
||
agentSessionProfile,
|
||
agentSession,
|
||
handleCustomWorldSelect,
|
||
executePublishWorld,
|
||
syncAgentDraftResultProfile,
|
||
setGeneratedCustomWorldProfile,
|
||
} = params;
|
||
|
||
const enterWorldFromCurrentResult = useCallback(async () => {
|
||
if (!generatedCustomWorldProfile) {
|
||
return;
|
||
}
|
||
|
||
if (!isAgentDraftResultView || !activeAgentSessionId) {
|
||
handleCustomWorldSelect(generatedCustomWorldProfile);
|
||
return;
|
||
}
|
||
|
||
const latestResult = await syncAgentDraftResultProfile(
|
||
generatedCustomWorldProfile,
|
||
);
|
||
const latestProfile =
|
||
latestResult.profile ?? agentSessionProfile ?? generatedCustomWorldProfile;
|
||
setGeneratedCustomWorldProfile(latestProfile);
|
||
|
||
const latestSession = latestResult.session ?? agentSession;
|
||
const canEnterPublishedWorld =
|
||
latestSession?.stage === 'published' &&
|
||
latestSession.resultPreview?.canEnterWorld;
|
||
|
||
if (canEnterPublishedWorld) {
|
||
handleCustomWorldSelect(latestProfile);
|
||
return;
|
||
}
|
||
|
||
const publishedSession = await executePublishWorld();
|
||
const publishedProfile =
|
||
rpgCreationPreviewAdapter.buildPreviewFromSession(publishedSession) ??
|
||
latestProfile;
|
||
|
||
setGeneratedCustomWorldProfile(publishedProfile);
|
||
handleCustomWorldSelect(publishedProfile);
|
||
}, [
|
||
activeAgentSessionId,
|
||
agentSession,
|
||
agentSessionProfile,
|
||
executePublishWorld,
|
||
generatedCustomWorldProfile,
|
||
handleCustomWorldSelect,
|
||
isAgentDraftResultView,
|
||
setGeneratedCustomWorldProfile,
|
||
syncAgentDraftResultProfile,
|
||
]);
|
||
|
||
return {
|
||
enterWorldFromCurrentResult,
|
||
};
|
||
}
|