refactor: 收口 RPG 结果预览门禁
This commit is contained in:
@@ -556,6 +556,10 @@ import {
|
||||
buildPuzzleResultProfileId,
|
||||
buildPuzzleResultWorkId,
|
||||
} from './platformPuzzleIdentityModel';
|
||||
import {
|
||||
buildPlatformRpgAgentResultPublishGateView,
|
||||
resolvePlatformRpgAgentResultPreviewSourceLabel,
|
||||
} from './platformRpgAgentResultPreviewModel';
|
||||
import {
|
||||
resolveSelectionStageAfterMissingCreationState,
|
||||
resolveSelectionStageAfterProtectedDataLoss,
|
||||
@@ -567,10 +571,6 @@ import { usePlatformEntryBootstrap } from './usePlatformEntryBootstrap';
|
||||
import { usePlatformEntryLibraryDetail } from './usePlatformEntryLibraryDetail';
|
||||
import { usePlatformEntryNavigation } from './usePlatformEntryNavigation';
|
||||
|
||||
type AgentResultPublishGateView = {
|
||||
blockers: string[];
|
||||
publishReady: boolean;
|
||||
};
|
||||
type CreationWorkShelfKind = CreationWorkShelfItem['kind'];
|
||||
type CreationFlowReturnTarget = 'create' | 'draft-shelf';
|
||||
type Match3DBackgroundCompileTask = {
|
||||
@@ -653,18 +653,6 @@ async function resumePuzzleProfileSaveArchiveRaw(worldKey: string) {
|
||||
);
|
||||
}
|
||||
|
||||
type AgentResultBlockerView = {
|
||||
code?: string;
|
||||
message: string;
|
||||
};
|
||||
|
||||
const AGENT_RESULT_STRUCTURAL_BLOCKER_CODES = new Set([
|
||||
'publish_missing_world_hook',
|
||||
'publish_missing_player_premise',
|
||||
'publish_missing_core_conflict',
|
||||
'publish_missing_main_chapter',
|
||||
'publish_missing_first_act',
|
||||
]);
|
||||
const RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS =
|
||||
BACKGROUND_AUTH_REQUEST_OPTIONS;
|
||||
const RECOMMEND_PUZZLE_BACKGROUND_AUTH_OPTIONS =
|
||||
@@ -1029,130 +1017,6 @@ async function resolvePublicWorkAuthorSummary(
|
||||
return null;
|
||||
}
|
||||
|
||||
function readProfileTextField(
|
||||
profile: CustomWorldProfile | null,
|
||||
paths: string[],
|
||||
) {
|
||||
for (const path of paths) {
|
||||
let current: unknown = profile;
|
||||
for (const segment of path.split('.')) {
|
||||
if (!current || typeof current !== 'object') {
|
||||
current = null;
|
||||
break;
|
||||
}
|
||||
current = (current as Record<string, unknown>)[segment];
|
||||
}
|
||||
if (typeof current === 'string' && current.trim()) {
|
||||
return current.trim();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function hasProfileTextArray(profile: CustomWorldProfile | null, key: string) {
|
||||
const value = profile
|
||||
? (profile as unknown as Record<string, unknown>)[key]
|
||||
: null;
|
||||
return Array.isArray(value)
|
||||
? value.some((entry) => typeof entry === 'string' && entry.trim())
|
||||
: false;
|
||||
}
|
||||
|
||||
function hasProfileArray(profile: CustomWorldProfile | null, key: string) {
|
||||
const value = profile
|
||||
? (profile as unknown as Record<string, unknown>)[key]
|
||||
: null;
|
||||
return Array.isArray(value) && value.length > 0;
|
||||
}
|
||||
|
||||
function hasSceneAct(profile: CustomWorldProfile | null) {
|
||||
const rawProfile = profile as unknown as Record<string, unknown> | null;
|
||||
const chapters =
|
||||
rawProfile &&
|
||||
(Array.isArray(rawProfile.sceneChapterBlueprints)
|
||||
? rawProfile.sceneChapterBlueprints
|
||||
: Array.isArray(rawProfile.sceneChapters)
|
||||
? rawProfile.sceneChapters
|
||||
: []);
|
||||
return Array.isArray(chapters)
|
||||
? chapters.some((chapter) => {
|
||||
const acts =
|
||||
chapter && typeof chapter === 'object'
|
||||
? (chapter as Record<string, unknown>).acts
|
||||
: null;
|
||||
return Array.isArray(acts) && acts.length > 0;
|
||||
})
|
||||
: false;
|
||||
}
|
||||
|
||||
function isAgentResultStructuralBlockerResolved(
|
||||
profile: CustomWorldProfile,
|
||||
code: string | undefined,
|
||||
) {
|
||||
if (!code || !AGENT_RESULT_STRUCTURAL_BLOCKER_CODES.has(code)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (code === 'publish_missing_world_hook') {
|
||||
return Boolean(
|
||||
readProfileTextField(profile, [
|
||||
'worldHook',
|
||||
'creatorIntent.worldHook',
|
||||
'anchorContent.worldPromise',
|
||||
'anchorContent.worldPromise.hook',
|
||||
'settingText',
|
||||
]),
|
||||
);
|
||||
}
|
||||
if (code === 'publish_missing_player_premise') {
|
||||
return Boolean(
|
||||
readProfileTextField(profile, [
|
||||
'playerPremise',
|
||||
'creatorIntent.playerPremise',
|
||||
'anchorContent.playerEntryPoint',
|
||||
'anchorContent.playerEntryPoint.openingIdentity',
|
||||
'anchorContent.playerEntryPoint.openingProblem',
|
||||
'anchorContent.playerEntryPoint.entryMotivation',
|
||||
]),
|
||||
);
|
||||
}
|
||||
if (code === 'publish_missing_core_conflict') {
|
||||
return hasProfileTextArray(profile, 'coreConflicts');
|
||||
}
|
||||
if (code === 'publish_missing_main_chapter') {
|
||||
return (
|
||||
hasProfileArray(profile, 'chapters') ||
|
||||
hasProfileArray(profile, 'sceneChapterBlueprints') ||
|
||||
hasProfileArray(profile, 'sceneChapters')
|
||||
);
|
||||
}
|
||||
return hasSceneAct(profile);
|
||||
}
|
||||
|
||||
function buildAgentResultPublishGateView(
|
||||
profile: CustomWorldProfile | null,
|
||||
fallbackBlockers: AgentResultBlockerView[],
|
||||
fallbackPublishReady: boolean,
|
||||
): AgentResultPublishGateView {
|
||||
if (!profile) {
|
||||
return {
|
||||
blockers: fallbackBlockers.map((entry) => entry.message),
|
||||
publishReady: fallbackPublishReady,
|
||||
};
|
||||
}
|
||||
|
||||
const blockers = fallbackBlockers
|
||||
.filter(
|
||||
(entry) => !isAgentResultStructuralBlockerResolved(profile, entry.code),
|
||||
)
|
||||
.map((entry) => entry.message);
|
||||
|
||||
return {
|
||||
blockers,
|
||||
publishReady: blockers.length === 0,
|
||||
};
|
||||
}
|
||||
|
||||
function openPuzzleRuntimeStage(
|
||||
setSelectionStage: (stage: SelectionStage) => void,
|
||||
state: PuzzleRuntimeUrlState,
|
||||
@@ -3337,7 +3201,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
);
|
||||
const agentResultPublishGateView = useMemo(
|
||||
() =>
|
||||
buildAgentResultPublishGateView(
|
||||
buildPlatformRpgAgentResultPublishGateView(
|
||||
sessionController.generatedCustomWorldProfile,
|
||||
agentResultPreviewBlockers,
|
||||
Boolean(agentResultPreview?.publishReady),
|
||||
@@ -3397,16 +3261,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
[openPublishShareModal, platformBootstrap],
|
||||
);
|
||||
const agentResultPreviewSourceLabel = useMemo(() => {
|
||||
if (!agentResultPreview?.source) {
|
||||
return null;
|
||||
}
|
||||
if (agentResultPreview.source === 'published_profile') {
|
||||
return '已发布世界';
|
||||
}
|
||||
if (agentResultPreview.source === 'session_preview') {
|
||||
return '会话预览';
|
||||
}
|
||||
return '服务端预览';
|
||||
return resolvePlatformRpgAgentResultPreviewSourceLabel(
|
||||
agentResultPreview?.source,
|
||||
);
|
||||
}, [agentResultPreview]);
|
||||
const featuredGalleryEntries = useMemo(() => {
|
||||
const bigFishPublicEntries = isBigFishCreationVisible
|
||||
|
||||
Reference in New Issue
Block a user