import { useMemo, useState } from 'react'; import type { Character, CustomWorldProfile } from '../../types'; import { CustomWorldEntityCatalog, type ResultTab, } from '../CustomWorldEntityCatalog'; import RpgCreationEntityEditorModal from '../rpg-creation-editor/RpgCreationEntityEditorModal'; import RpgCreationAssetDebugPanel, { shouldEnableRpgCreationAssetDebugPanel, } from './RpgCreationAssetDebugPanel'; import RpgCreationResultActionBar from './RpgCreationResultActionBar'; import RpgCreationResultHeader from './RpgCreationResultHeader'; import { useRpgCreationResultActions } from './useRpgCreationResultActions'; import type { EntityGenerationKind } from './useRpgCreationResultActions'; export interface RpgCreationResultViewProps { profile: CustomWorldProfile; previewCharacters: Character[]; isGenerating: boolean; progress: number; progressLabel: string; error: string | null; onBack: () => void; onEditSetting?: () => void; onRegenerate?: () => void; onContinueExpand?: () => void; onEnterWorld?: () => void; onOpenCoverEditor?: () => void; onPublishWorld?: () => Promise | void; onTestWorld?: () => void; onDeleteEntities?: ( kind: 'story' | 'landmark', ids: string[], ) => Promise | void; onGenerateEntity?: | (( kind: EntityGenerationKind, ) => | Promise<{ profile?: CustomWorldProfile | null } | void> | { profile?: CustomWorldProfile | null } | void) | undefined; onProfileChange: (profile: CustomWorldProfile) => void; readOnly?: boolean; backLabel?: string; editActionLabel?: string; regenerateActionLabel?: string; enterWorldActionLabel?: string; autoSaveState?: 'idle' | 'saving' | 'saved' | 'error'; compactAgentResultMode?: boolean; publishReady?: boolean; publishBlockers?: string[]; qualityFindings?: Array<{ id: string; severity: 'info' | 'warning' | 'blocker'; code: string; targetId?: string | null; message: string; }>; previewSourceLabel?: string | null; } export function RpgCreationResultView({ profile, previewCharacters, isGenerating, progress, progressLabel, error, onBack, onEditSetting, onRegenerate: triggerRegenerate, onContinueExpand, onOpenCoverEditor, onPublishWorld, onTestWorld, onDeleteEntities, onEnterWorld, onGenerateEntity, onProfileChange, readOnly = false, backLabel = '返回', editActionLabel = '修改设定', regenerateActionLabel = '重新生成', enterWorldActionLabel = '进入世界', autoSaveState = 'idle', compactAgentResultMode = false, publishReady = true, publishBlockers = [], qualityFindings = [], }: RpgCreationResultViewProps) { const [activeTab, setActiveTab] = useState('world'); const assetDebugEnabled = useMemo( () => shouldEnableRpgCreationAssetDebugPanel(), [], ); const { closeEditorTarget, createLabel, createTarget, editorTarget, handleDeleteLandmarks, handleDeleteStoryNpcs, handleGenerateEntity, handleRegenerate, localGenerationError, pendingGeneratedEntity, recentGeneratedIds, setEditorTarget, } = useRpgCreationResultActions({ activeTab, agentEntityGenerator: onGenerateEntity ? async (kind) => { return onGenerateEntity(kind); } : undefined, isGenerating, onProfileChange, profile, readOnly, triggerRegenerate, }); const deleteStoryNpcs = onDeleteEntities ? (ids: string[]) => { void onDeleteEntities('story', ids); } : handleDeleteStoryNpcs; const deleteLandmarks = onDeleteEntities ? (ids: string[]) => { void onDeleteEntities('landmark', ids); } : handleDeleteLandmarks; return (
{ if (activeTab === 'playable') { void handleGenerateEntity('playable'); return; } if (activeTab === 'story') { void handleGenerateEntity('story'); return; } if (activeTab === 'landmarks') { void handleGenerateEntity('landmark'); return; } setEditorTarget(createTarget); } } createActionDisabled={Boolean(isGenerating || pendingGeneratedEntity)} pendingGeneratedEntity={pendingGeneratedEntity} recentGeneratedIds={recentGeneratedIds} readOnly={readOnly} />
{isGenerating && (
{progressLabel}
{Math.round(progress)}%
)} {error ? (
{error}
) : null} {!error && compactAgentResultMode && publishBlockers.length <= 0 && qualityFindings.some((entry) => entry.severity === 'warning') ? (
发布后仍有{' '} { qualityFindings.filter((entry) => entry.severity === 'warning') .length }{' '} 条 warning 可继续优化。
) : null} {!error && localGenerationError ? (
{localGenerationError}
) : null} {assetDebugEnabled ? ( ) : null} setEditorTarget({ kind: 'cover' })) } onPublishWorld={onPublishWorld} onTestWorld={onTestWorld} onRegenerate={triggerRegenerate ? handleRegenerate : undefined} profile={profile} regenerateActionLabel={regenerateActionLabel} publishReady={publishReady} publishBlockers={publishBlockers} />
); }