This commit is contained in:
2026-05-14 01:11:58 +08:00
parent b13870f71b
commit 5a55180b78
61 changed files with 5050 additions and 1057 deletions

View File

@@ -162,7 +162,10 @@ import {
listMatch3DGallery,
listMatch3DWorks,
} from '../../services/match3d-works';
import { preloadMatch3DGeneratedModelAssets } from '../../services/match3dGeneratedModelCache';
import {
hasMatch3DGeneratedImageAsset,
preloadMatch3DGeneratedRuntimeAssets,
} from '../../services/match3dGeneratedModelCache';
import {
buildBabyObjectMatchGenerationAnchorEntries,
buildBigFishGenerationAnchorEntries,
@@ -359,6 +362,18 @@ type PendingDraftShelfMap = Partial<
Record<string, PendingDraftShelfState>
>
>;
type Match3DBackgroundCompileTask = {
session: Match3DAgentSessionSnapshot;
payload: CreateMatch3DSessionRequest;
generationState: MiniGameDraftGenerationState;
error: string | null;
};
type PuzzleBackgroundCompileTask = {
session: PuzzleAgentSessionSnapshot;
payload: CreatePuzzleAgentSessionRequest;
generationState: MiniGameDraftGenerationState;
error: string | null;
};
type PuzzleDetailReturnTarget = {
tab: PlatformHomeTab;
@@ -667,14 +682,10 @@ function buildMatch3DProfileFromSession(
};
}
function hasMatch3DGeneratedModelAsset(
function hasMatch3DRuntimeAsset(
assets: readonly Match3DGeneratedItemAsset[] | null | undefined,
) {
return Boolean(
assets?.some(
(asset) => asset.modelSrc?.trim() || asset.modelObjectKey?.trim(),
),
);
return hasMatch3DGeneratedImageAsset(assets);
}
function resolveMatch3DRuntimeGeneratedItemAssets(
@@ -690,7 +701,7 @@ function resolveMatch3DRuntimeGeneratedItemAssets(
: [];
if (runProfileId && profile?.profileId === runProfileId) {
if (hasMatch3DGeneratedModelAsset(profileAssets)) {
if (hasMatch3DRuntimeAsset(profileAssets)) {
return profileAssets;
}
@@ -699,10 +710,12 @@ function resolveMatch3DRuntimeGeneratedItemAssets(
isMatch3DGalleryEntry(publicWorkDetail) &&
publicWorkDetail.profileId === runProfileId
) {
return hasMatch3DGeneratedModelAsset(publicDetailAssets)
return hasMatch3DRuntimeAsset(publicDetailAssets)
? publicDetailAssets
: profileAssets;
}
return profileAssets;
}
if (
@@ -714,9 +727,10 @@ function resolveMatch3DRuntimeGeneratedItemAssets(
return publicDetailAssets;
}
return hasMatch3DGeneratedModelAsset(profileAssets)
? profileAssets
: publicDetailAssets;
if (hasMatch3DRuntimeAsset(profileAssets)) {
return profileAssets;
}
return publicDetailAssets.length > 0 ? publicDetailAssets : profileAssets;
}
function resolveActiveMatch3DRuntimeProfile(
@@ -777,23 +791,23 @@ function resolveMatch3DGenerationStateFromAssets(
const assetList = assets ?? [];
const imageReadyCount = assetList.filter(
(asset) => asset.imageObjectKey?.trim() || asset.imageSrc?.trim(),
).length;
const modelReadyCount = assetList.filter(
(asset) =>
asset.status === 'model_ready' &&
(asset.modelObjectKey?.trim() || asset.modelSrc?.trim()),
asset.imageViews?.some(
(view) => view.imageObjectKey?.trim() || view.imageSrc?.trim(),
) ||
asset.imageObjectKey?.trim() ||
asset.imageSrc?.trim(),
).length;
const totalAssetCount = Math.max(3, assetList.length);
const totalAssetCount = Math.max(5, assetList.length);
const failedAsset = assetList.find((asset) => asset.error?.trim());
return {
...current,
phase:
imageReadyCount > 0 || modelReadyCount > 0
imageReadyCount > 0
? 'match3d-generate-views'
: current.phase,
completedAssetCount: modelReadyCount,
completedAssetCount: imageReadyCount,
totalAssetCount,
error: failedAsset?.error?.trim() || current.error,
};
@@ -2071,6 +2085,8 @@ export function PlatformEntryFlowShellImpl({
useState<CreateMatch3DSessionRequest | null>(null);
const [match3dGenerationState, setMatch3DGenerationState] =
useState<MiniGameDraftGenerationState | null>(null);
const [match3dBackgroundCompileTasks, setMatch3DBackgroundCompileTasks] =
useState<Record<string, Match3DBackgroundCompileTask>>({});
const [isMatch3DLoadingLibrary, setIsMatch3DLoadingLibrary] = useState(false);
const [squareHoleWorks, setSquareHoleWorks] = useState<
SquareHoleWorkSummary[]
@@ -2155,6 +2171,8 @@ export function PlatformEntryFlowShellImpl({
);
const [puzzleGenerationState, setPuzzleGenerationState] =
useState<MiniGameDraftGenerationState | null>(null);
const [puzzleBackgroundCompileTasks, setPuzzleBackgroundCompileTasks] =
useState<Record<string, PuzzleBackgroundCompileTask>>({});
const [miniGameGenerationProgressNowMs, setMiniGameGenerationProgressNowMs] =
useState(() => Date.now());
const [puzzleFormDraftPayload, setPuzzleFormDraftPayload] =
@@ -2287,6 +2305,8 @@ export function PlatformEntryFlowShellImpl({
);
const handledInitialPublicWorkCodeRef = useRef<string | null>(null);
const selectionStageRef = useRef(selectionStage);
const activeMatch3DGenerationSessionIdRef = useRef<string | null>(null);
const activePuzzleGenerationSessionIdRef = useRef<string | null>(null);
const [draftGenerationNotices, setDraftGenerationNotices] =
useState<DraftGenerationNoticeMap>({});
const [pendingDraftShelfItems, setPendingDraftShelfItems] =
@@ -2437,6 +2457,24 @@ export function PlatformEntryFlowShellImpl({
},
[updatePendingDraftShelfItem],
);
const getMatch3DBackgroundCompileTask = useCallback(
(sessionId: string | null | undefined) => {
const normalizedSessionId = normalizeDraftNoticeId(sessionId);
return normalizedSessionId
? (match3dBackgroundCompileTasks[normalizedSessionId] ?? null)
: null;
},
[match3dBackgroundCompileTasks],
);
const getPuzzleBackgroundCompileTask = useCallback(
(sessionId: string | null | undefined) => {
const normalizedSessionId = normalizeDraftNoticeId(sessionId);
return normalizedSessionId
? (puzzleBackgroundCompileTasks[normalizedSessionId] ?? null)
: null;
},
[puzzleBackgroundCompileTasks],
);
useEffect(() => {
let cancelled = false;
@@ -2501,6 +2539,18 @@ export function PlatformEntryFlowShellImpl({
selectionStageRef.current = 'platform';
setSelectionStage('platform');
}, [enterCreateTab, setSelectionStage]);
const isViewingMatch3DGeneration = useCallback((sessionId: string) => {
return (
selectionStageRef.current === 'match3d-generating' &&
activeMatch3DGenerationSessionIdRef.current === sessionId
);
}, []);
const isViewingPuzzleGeneration = useCallback((sessionId: string) => {
return (
selectionStageRef.current === 'puzzle-generating' &&
activePuzzleGenerationSessionIdRef.current === sessionId
);
}, []);
const resolveBigFishErrorMessage = useCallback(
(error: unknown, fallback: string) =>
@@ -3515,9 +3565,9 @@ export function PlatformEntryFlowShellImpl({
...current,
phase: 'ready',
completedAssetCount:
response.session.draft?.generatedItemAssets?.length ?? 3,
response.session.draft?.generatedItemAssets?.length ?? 5,
totalAssetCount:
response.session.draft?.generatedItemAssets?.length ?? 3,
response.session.draft?.generatedItemAssets?.length ?? 5,
}
: current,
);
@@ -3552,7 +3602,7 @@ export function PlatformEntryFlowShellImpl({
);
if (openResult && runtimeProfile) {
try {
await preloadMatch3DGeneratedModelAssets(
await preloadMatch3DGeneratedRuntimeAssets(
runtimeProfile.generatedItemAssets,
{ expireSeconds: 300 },
);
@@ -4151,6 +4201,39 @@ export function PlatformEntryFlowShellImpl({
const resetAutoSaveTrackingToIdle =
autosaveCoordinator.resetAutoSaveTrackingToIdle;
const activeMatch3DBackgroundCompileTask =
getMatch3DBackgroundCompileTask(match3dSession?.sessionId);
const match3dGenerationViewState =
activeMatch3DBackgroundCompileTask?.generationState ??
match3dGenerationState;
const match3dGenerationViewSession =
activeMatch3DBackgroundCompileTask?.session ?? match3dSession;
const match3dGenerationViewPayload =
activeMatch3DBackgroundCompileTask?.payload ?? match3dFormDraftPayload;
const match3dGenerationViewError =
activeMatch3DBackgroundCompileTask?.error ?? match3dError;
const isMatch3DGenerationViewBusy =
isMatch3DBusy ||
isMiniGameDraftGenerating(
activeMatch3DBackgroundCompileTask?.generationState ?? null,
);
const activePuzzleBackgroundCompileTask = getPuzzleBackgroundCompileTask(
puzzleSession?.sessionId,
);
const puzzleGenerationViewState =
activePuzzleBackgroundCompileTask?.generationState ?? puzzleGenerationState;
const puzzleGenerationViewSession =
activePuzzleBackgroundCompileTask?.session ?? puzzleSession;
const puzzleGenerationViewPayload =
activePuzzleBackgroundCompileTask?.payload ?? puzzleFormDraftPayload;
const puzzleGenerationViewError =
activePuzzleBackgroundCompileTask?.error ?? puzzleError;
const isPuzzleGenerationViewBusy =
isPuzzleBusy ||
isMiniGameDraftGenerating(
activePuzzleBackgroundCompileTask?.generationState ?? null,
);
const match3DGeneratingSessionId =
selectionStage === 'match3d-generating' ? match3dSession?.sessionId : null;
@@ -4302,60 +4385,366 @@ export function PlatformEntryFlowShellImpl({
const createPuzzleDraftFromForm = useCallback(
async (payload: CreatePuzzleAgentSessionRequest) => {
setPuzzleFormDraftPayload(payload);
setPuzzleGenerationState(null);
const nextSession =
puzzleFlow.session && !isEmptyPuzzleFormOnlyDraft(puzzleFlow.session)
? puzzleFlow.session
: await puzzleFlow.openWorkspace(payload);
if (!nextSession) {
setPuzzleCreationError(null);
setPuzzleError(null);
let nextSession: PuzzleAgentSessionSnapshot;
try {
const response = await createPuzzleAgentSession(payload);
nextSession = response.session;
} catch (error) {
const errorMessage = resolvePuzzleErrorMessage(
error,
'开启拼图创作工作台失败。',
);
setPuzzleCreationError(errorMessage);
setPuzzleError(errorMessage);
return;
}
markPendingDraftGenerating('puzzle', nextSession.sessionId);
await puzzleFlow.executeAction(
buildPuzzleCompileActionFromFormPayload(payload),
nextSession,
);
const generationState = createMiniGameDraftGenerationState('puzzle');
setPuzzleBackgroundCompileTasks((current) => ({
...current,
[nextSession.sessionId]: {
session: nextSession,
payload,
generationState,
error: null,
},
}));
puzzleFlow.setSession(nextSession);
setPuzzleGenerationState(generationState);
markDraftGenerating('puzzle', [
nextSession.sessionId,
buildPuzzleResultWorkId(nextSession.sessionId),
nextSession.publishedProfileId,
buildPuzzleResultProfileId(nextSession.sessionId),
]);
markPendingDraftGenerating('puzzle', nextSession.sessionId);
selectionStageRef.current = 'puzzle-generating';
activePuzzleGenerationSessionIdRef.current = nextSession.sessionId;
setSelectionStage('puzzle-generating');
try {
const actionPayload = buildPuzzleCompileActionFromFormPayload(payload);
const response = await executePuzzleAgentAction(
nextSession.sessionId,
actionPayload,
);
setPuzzleOperation(response.operation);
const openResult = isViewingPuzzleGeneration(nextSession.sessionId);
const readyGenerationState = {
...generationState,
phase: 'ready' as const,
completedAssetCount: 1,
totalAssetCount: 1,
};
setPuzzleBackgroundCompileTasks((current) => ({
...current,
[nextSession.sessionId]: {
session: response.session,
payload,
generationState: readyGenerationState,
error: null,
},
}));
if (isViewingPuzzleGeneration(nextSession.sessionId)) {
puzzleFlow.setSession(response.session);
setPuzzleGenerationState(readyGenerationState);
}
const profileId =
response.session.publishedProfileId ??
buildPuzzleResultProfileId(response.session.sessionId);
markPendingDraftReady('puzzle', response.session.sessionId, openResult);
markDraftReady(
'puzzle',
[
response.session.sessionId,
buildPuzzleResultWorkId(response.session.sessionId),
profileId,
],
openResult,
);
void refreshPuzzleShelf();
if (openResult && response.session.draft) {
const draft = response.session.draft;
const draftProfileId =
response.session.publishedProfileId ??
buildPuzzleResultProfileId(response.session.sessionId);
if (!draft.coverImageSrc || !draftProfileId) {
setPuzzleError(
!draft.coverImageSrc
? '请先选择一张正式拼图图片。'
: '这份拼图草稿缺少会话信息,请重新开始创作。',
);
setSelectionStage('puzzle-result');
return;
}
try {
const { item } = await updatePuzzleWork(draftProfileId, {
workTitle: draft.workTitle,
workDescription: draft.workDescription,
levelName: draft.levelName,
summary: draft.summary,
themeTags: draft.themeTags,
coverImageSrc: draft.coverImageSrc,
coverAssetId: draft.coverAssetId,
levels: draft.levels ?? [],
});
const run = startLocalPuzzleRun(item);
setSelectedPuzzleDetail(item);
setPuzzleRun(run);
setPuzzleRuntimeAuthMode('default');
setPuzzleRuntimeReturnStage('puzzle-result');
setSelectionStage('puzzle-runtime');
} catch (error) {
setPuzzleError(
resolvePuzzleErrorMessage(error, '启动拼图试玩失败。'),
);
setSelectionStage('puzzle-result');
}
}
} catch (error) {
const errorMessage = resolvePuzzleErrorMessage(
error,
'执行拼图操作失败。',
);
const failedGenerationState = {
...generationState,
phase: 'failed' as const,
error: errorMessage,
};
setPuzzleBackgroundCompileTasks((current) => ({
...current,
[nextSession.sessionId]: {
session: nextSession,
payload,
generationState: failedGenerationState,
error: errorMessage,
},
}));
if (isViewingPuzzleGeneration(nextSession.sessionId)) {
setPuzzleError(errorMessage);
setPuzzleGenerationState(failedGenerationState);
}
}
},
[markPendingDraftGenerating, puzzleFlow],
[
markDraftGenerating,
markDraftReady,
markPendingDraftGenerating,
markPendingDraftReady,
isViewingPuzzleGeneration,
puzzleFlow,
refreshPuzzleShelf,
resolvePuzzleErrorMessage,
setPuzzleError,
setSelectionStage,
],
);
const createMatch3DDraftFromForm = useCallback(
async (payload: CreateMatch3DSessionRequest) => {
setMatch3DFormDraftPayload(payload);
setMatch3DGenerationState(null);
setMatch3DSession(null);
setMatch3DProfile(null);
setMatch3DRuntimeProfile(null);
setMatch3DRun(null);
setMatch3DError(null);
setStreamingMatch3DReplyText('');
setIsStreamingMatch3DReply(false);
const nextSession = await match3dFlow.openWorkspace(payload);
if (!nextSession) {
let nextSession: Match3DAgentSessionSnapshot;
try {
const response = await match3dCreationClient.createSession(payload);
nextSession = response.session;
} catch (error) {
setMatch3DError(
resolveMatch3DErrorMessage(error, '开启抓大鹅共创工作台失败。'),
);
return;
}
markDraftGenerating('match3d', [nextSession.sessionId]);
markPendingDraftGenerating('match3d', nextSession.sessionId);
await match3dFlow.executeAction(
{
action: 'match3d_compile_draft',
generateClickSound: payload.generateClickSound,
const generationState = createMiniGameDraftGenerationState('match3d');
setMatch3DBackgroundCompileTasks((current) => ({
...current,
[nextSession.sessionId]: {
session: nextSession,
payload,
generationState,
error: null,
},
nextSession,
);
}));
setMatch3DSession(nextSession);
setMatch3DProfile(null);
setMatch3DRuntimeProfile(null);
setMatch3DRun(null);
setMatch3DGenerationState(generationState);
markDraftGenerating('match3d', [
nextSession.draft?.profileId,
nextSession.publishedProfileId,
nextSession.sessionId,
]);
markPendingDraftGenerating('match3d', nextSession.sessionId);
selectionStageRef.current = 'match3d-generating';
activeMatch3DGenerationSessionIdRef.current = nextSession.sessionId;
setSelectionStage('match3d-generating');
try {
const response = await match3dCreationClient.executeAction(
nextSession.sessionId,
{
action: 'match3d_compile_draft',
generateClickSound: payload.generateClickSound,
},
);
const openResult = isViewingMatch3DGeneration(nextSession.sessionId);
const readyGenerationState = {
...generationState,
phase: 'ready' as const,
completedAssetCount:
response.session.draft?.generatedItemAssets?.length ?? 5,
totalAssetCount:
response.session.draft?.generatedItemAssets?.length ?? 5,
};
setMatch3DBackgroundCompileTasks((current) => ({
...current,
[nextSession.sessionId]: {
session: response.session,
payload,
generationState: readyGenerationState,
error: null,
},
}));
if (isViewingMatch3DGeneration(nextSession.sessionId)) {
setMatch3DSession(response.session);
setMatch3DGenerationState(readyGenerationState);
}
const profileId = response.session.draft?.profileId;
if (!profileId) {
if (isViewingMatch3DGeneration(nextSession.sessionId)) {
setMatch3DProfile(null);
setMatch3DRuntimeProfile(null);
}
return;
}
let runtimeProfile: Match3DWorkProfile | null = null;
try {
const { item } = await getMatch3DWorkDetail(profileId);
runtimeProfile = {
...item,
generatedItemAssets:
response.session.draft?.generatedItemAssets ??
item.generatedItemAssets,
};
if (isViewingMatch3DGeneration(nextSession.sessionId)) {
setMatch3DProfile(runtimeProfile);
}
await refreshMatch3DShelf().catch(() => undefined);
} catch {
runtimeProfile = buildMatch3DProfileFromSession(response.session);
if (isViewingMatch3DGeneration(nextSession.sessionId)) {
setMatch3DProfile(runtimeProfile);
}
}
markPendingDraftReady(
'match3d',
response.session.sessionId,
openResult,
);
markDraftReady(
'match3d',
[profileId, response.session.sessionId],
openResult,
);
if (openResult && runtimeProfile) {
try {
await preloadMatch3DGeneratedRuntimeAssets(
runtimeProfile.generatedItemAssets,
{ expireSeconds: 300 },
);
const { run } = await match3dRuntimeAdapter.startRun(
runtimeProfile.profileId,
);
setMatch3DRuntimeProfile(runtimeProfile);
setMatch3DRun(run);
setMatch3DProfile(runtimeProfile);
setMatch3DRuntimeReturnStage('match3d-result');
setSelectionStage('match3d-runtime');
} catch (error) {
setMatch3DError(
resolveMatch3DErrorMessage(error, '启动抓大鹅玩法失败。'),
);
setSelectionStage('match3d-result');
}
}
} catch (error) {
const errorMessage = resolveMatch3DErrorMessage(
error,
'执行抓大鹅操作失败。',
);
const failedGenerationState = {
...generationState,
phase: 'failed' as const,
error: errorMessage,
};
setMatch3DBackgroundCompileTasks((current) => ({
...current,
[nextSession.sessionId]: {
session: nextSession,
payload,
generationState: failedGenerationState,
error: errorMessage,
},
}));
if (isViewingMatch3DGeneration(nextSession.sessionId)) {
setMatch3DError(errorMessage);
setMatch3DGenerationState(failedGenerationState);
}
try {
const { session: latestSession } =
await match3dCreationClient.getSession(nextSession.sessionId);
setMatch3DBackgroundCompileTasks((current) => ({
...current,
[nextSession.sessionId]: {
session: latestSession,
payload,
generationState: failedGenerationState,
error: errorMessage,
},
}));
if (isViewingMatch3DGeneration(nextSession.sessionId)) {
setMatch3DSession(latestSession);
const profileId =
latestSession.draft?.profileId ?? latestSession.publishedProfileId;
if (profileId) {
const { item } = await getMatch3DWorkDetail(profileId);
setMatch3DProfile(item);
}
}
await refreshMatch3DShelf().catch(() => undefined);
} catch {
await refreshMatch3DShelf().catch(() => undefined);
}
}
},
[
match3dFlow,
match3dRuntimeAdapter,
isViewingMatch3DGeneration,
markDraftGenerating,
markDraftReady,
markPendingDraftGenerating,
markPendingDraftReady,
refreshMatch3DShelf,
resolveMatch3DErrorMessage,
setIsStreamingMatch3DReply,
setMatch3DError,
setMatch3DProfile,
setMatch3DRun,
setMatch3DSession,
setSelectionStage,
setStreamingMatch3DReplyText,
],
);
@@ -4552,6 +4941,8 @@ export function PlatformEntryFlowShellImpl({
setMatch3DProfile(null);
setMatch3DRuntimeProfile(null);
setMatch3DFormDraftPayload(null);
setMatch3DBackgroundCompileTasks({});
activeMatch3DGenerationSessionIdRef.current = null;
setActiveCreationFormType('puzzle');
setMatch3DWorks([]);
setMatch3DGalleryEntries([]);
@@ -4585,6 +4976,8 @@ export function PlatformEntryFlowShellImpl({
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
setPuzzleGenerationState(null);
setPuzzleBackgroundCompileTasks({});
activePuzzleGenerationSessionIdRef.current = null;
setIsPuzzleNextLevelGenerating(false);
setPuzzleShelfError(null);
setPuzzleCreationError(null);
@@ -5361,7 +5754,7 @@ export function PlatformEntryFlowShellImpl({
const executePuzzleBackgroundAction = useCallback(
async (payload: PuzzleAgentActionRequest) => {
const targetSession = puzzleFlow.session;
const targetSession = puzzleSession;
if (!targetSession) {
return;
}
@@ -5383,7 +5776,7 @@ export function PlatformEntryFlowShellImpl({
setPuzzleError(resolvePuzzleErrorMessage(error, '执行拼图操作失败。'));
}
},
[puzzleFlow, resolvePuzzleErrorMessage, setPuzzleError],
[puzzleFlow, puzzleSession, resolvePuzzleErrorMessage, setPuzzleError],
);
const retryPuzzleDraftGeneration = useCallback(() => {
@@ -5427,7 +5820,7 @@ export function PlatformEntryFlowShellImpl({
(payload: PuzzleAgentActionRequest) => {
if (
payload.action === 'compile_puzzle_draft' &&
isEmptyPuzzleFormOnlyDraft(puzzleFlow.session)
isEmptyPuzzleFormOnlyDraft(puzzleSession)
) {
const formPayload = buildPuzzleFormPayloadFromAction(payload);
if (formPayload) {
@@ -5447,7 +5840,7 @@ export function PlatformEntryFlowShellImpl({
createPuzzleDraftFromForm,
executePuzzleAction,
executePuzzleBackgroundAction,
puzzleFlow.session,
puzzleSession,
],
);
@@ -5815,7 +6208,7 @@ export function PlatformEntryFlowShellImpl({
try {
let runtimeProfile = profile;
if (!hasMatch3DGeneratedModelAsset(profile.generatedItemAssets)) {
if (!hasMatch3DRuntimeAsset(profile.generatedItemAssets)) {
try {
const { item } = await getMatch3DWorkDetail(profile.profileId);
runtimeProfile = item;
@@ -5823,7 +6216,7 @@ export function PlatformEntryFlowShellImpl({
// 中文注释:详情补读只为拿完整生成素材;失败时继续按摘要开局,避免推荐流卡死。
}
}
await preloadMatch3DGeneratedModelAssets(
await preloadMatch3DGeneratedRuntimeAssets(
runtimeProfile.generatedItemAssets,
{ expireSeconds: 300 },
);
@@ -7628,10 +8021,31 @@ export function PlatformEntryFlowShellImpl({
if (
item.sourceSessionId === puzzleSession?.sessionId &&
isMiniGameDraftGenerating(puzzleGenerationState)
isMiniGameDraftGenerating(puzzleGenerationViewState)
) {
enterCreateTab();
selectionStageRef.current = 'puzzle-generating';
activePuzzleGenerationSessionIdRef.current = item.sourceSessionId;
setSelectionStage('puzzle-generating');
return;
}
const backgroundTask = getPuzzleBackgroundCompileTask(
item.sourceSessionId,
);
if (
backgroundTask &&
isMiniGameDraftGenerating(backgroundTask.generationState)
) {
puzzleFlow.setSession(backgroundTask.session);
setPuzzleFormDraftPayload(backgroundTask.payload);
setPuzzleGenerationState(backgroundTask.generationState);
if (backgroundTask.error) {
setPuzzleError(backgroundTask.error);
}
enterCreateTab();
selectionStageRef.current = 'puzzle-generating';
activePuzzleGenerationSessionIdRef.current = item.sourceSessionId;
setSelectionStage('puzzle-generating');
return;
}
@@ -7655,10 +8069,11 @@ export function PlatformEntryFlowShellImpl({
},
[
enterCreateTab,
getPuzzleBackgroundCompileTask,
markDraftNoticeSeen,
openPuzzleDetail,
puzzleFlow,
puzzleGenerationState,
puzzleGenerationViewState,
puzzleSession?.sessionId,
refreshPuzzleShelf,
setPuzzleError,
@@ -7695,10 +8110,31 @@ export function PlatformEntryFlowShellImpl({
if (
item.sourceSessionId === match3dSession?.sessionId &&
isMiniGameDraftGenerating(match3dGenerationState)
isMiniGameDraftGenerating(match3dGenerationViewState)
) {
enterCreateTab();
selectionStageRef.current = 'match3d-generating';
activeMatch3DGenerationSessionIdRef.current = item.sourceSessionId;
setSelectionStage('match3d-generating');
return;
}
const backgroundTask = getMatch3DBackgroundCompileTask(
item.sourceSessionId,
);
if (
backgroundTask &&
isMiniGameDraftGenerating(backgroundTask.generationState)
) {
setMatch3DSession(backgroundTask.session);
setMatch3DFormDraftPayload(backgroundTask.payload);
setMatch3DGenerationState(backgroundTask.generationState);
if (backgroundTask.error) {
setMatch3DError(backgroundTask.error);
}
enterCreateTab();
selectionStageRef.current = 'match3d-generating';
activeMatch3DGenerationSessionIdRef.current = item.sourceSessionId;
setSelectionStage('match3d-generating');
return;
}
@@ -7726,9 +8162,10 @@ export function PlatformEntryFlowShellImpl({
},
[
enterCreateTab,
getMatch3DBackgroundCompileTask,
markDraftNoticeSeen,
match3dFlow,
match3dGenerationState,
match3dGenerationViewState,
match3dSession?.sessionId,
openPublicWorkDetail,
refreshMatch3DShelf,
@@ -9630,18 +10067,7 @@ export function PlatformEntryFlowShellImpl({
>
{getVisiblePlatformCreationTypes(creationEntryTypes).map((item) => {
const selected = item.id === activeCreationFormType;
const disabled =
item.locked ||
sessionController.isCreatingAgentSession ||
isCreativeAgentBusy ||
isCreativeAgentStreaming ||
isBigFishBusy ||
isMatch3DBusy ||
isSquareHoleBusy ||
isPuzzleBusy ||
isVisualNovelBusy ||
isVisualNovelStreamingReply ||
isBabyObjectMatchBusy;
const disabled = item.locked;
return (
<button
@@ -9708,7 +10134,7 @@ export function PlatformEntryFlowShellImpl({
>
<Match3DAgentWorkspace
session={match3dSession}
isBusy={isMatch3DBusy || isStreamingMatch3DReply}
isBusy={isStreamingMatch3DReply}
error={match3dError}
onBack={leaveMatch3DFlow}
onExecuteAction={(payload) => {
@@ -9765,7 +10191,7 @@ export function PlatformEntryFlowShellImpl({
>
<PuzzleAgentWorkspace
session={puzzleSession}
isBusy={isPuzzleBusy || isStreamingPuzzleReply}
isBusy={isStreamingPuzzleReply}
error={puzzleError}
onBack={leavePuzzleFlow}
onSubmitMessage={(payload) => {
@@ -10287,7 +10713,7 @@ export function PlatformEntryFlowShellImpl({
>
<Match3DAgentWorkspace
session={match3dSession}
isBusy={isMatch3DBusy || isStreamingMatch3DReply}
isBusy={isStreamingMatch3DReply}
error={match3dError}
onBack={leaveMatch3DFlow}
onExecuteAction={(payload) => {
@@ -10311,19 +10737,19 @@ export function PlatformEntryFlowShellImpl({
>
<CustomWorldGenerationView
settingText={
match3dSession?.lastAssistantReply ??
match3dGenerationViewSession?.lastAssistantReply ??
'正在生成本局抓大鹅物品素材。'
}
anchorEntries={buildMatch3DGenerationAnchorEntries(
match3dSession,
match3dFormDraftPayload,
match3dGenerationViewSession,
match3dGenerationViewPayload,
)}
progress={buildMiniGameDraftGenerationProgress(
match3dGenerationState,
match3dGenerationViewState,
miniGameGenerationProgressNowMs,
)}
isGenerating={isMatch3DBusy}
error={match3dError}
isGenerating={isMatch3DGenerationViewBusy}
error={match3dGenerationViewError}
onBack={returnToCreationCenterFromGeneration}
onEditSetting={() => {
setSelectionStage('match3d-agent-workspace');
@@ -10364,7 +10790,7 @@ export function PlatformEntryFlowShellImpl({
isBusy={isMatch3DBusy}
error={match3dError}
onBack={() => {
setSelectionStage('match3d-agent-workspace');
returnToCreationCenterFromGeneration();
}}
onSaved={(profile) => {
setMatch3DProfile(profile);
@@ -10388,7 +10814,6 @@ export function PlatformEntryFlowShellImpl({
}}
onStartTestRun={(profile, options) => {
setMatch3DProfile(profile);
setMatch3DRuntimeProfile(profile);
void startMatch3DRunFromProfile(
profile,
'match3d-result',
@@ -10895,7 +11320,7 @@ export function PlatformEntryFlowShellImpl({
>
<PuzzleAgentWorkspace
session={puzzleSession}
isBusy={isPuzzleBusy || isStreamingPuzzleReply}
isBusy={isStreamingPuzzleReply}
error={puzzleError}
onBack={leavePuzzleFlow}
onSubmitMessage={(payload) => {
@@ -10950,18 +11375,19 @@ export function PlatformEntryFlowShellImpl({
>
<CustomWorldGenerationView
settingText={
puzzleSession?.lastAssistantReply ?? '正在整理当前拼图草稿。'
puzzleGenerationViewSession?.lastAssistantReply ??
'正在整理当前拼图草稿。'
}
anchorEntries={buildPuzzleGenerationAnchorEntries(
puzzleSession,
puzzleFormDraftPayload,
puzzleGenerationViewSession,
puzzleGenerationViewPayload,
)}
progress={buildMiniGameDraftGenerationProgress(
puzzleGenerationState,
puzzleGenerationViewState,
miniGameGenerationProgressNowMs,
)}
isGenerating={isPuzzleBusy}
error={puzzleError}
isGenerating={isPuzzleGenerationViewBusy}
error={puzzleGenerationViewError}
onBack={returnToCreationCenterFromGeneration}
onEditSetting={() => {
setSelectionStage('puzzle-agent-workspace');
@@ -11537,18 +11963,7 @@ export function PlatformEntryFlowShellImpl({
{creationEntryConfig ? (
<PlatformEntryCreationTypeModal
isOpen={showCreationTypeModal}
isBusy={
sessionController.isCreatingAgentSession ||
isCreativeAgentBusy ||
isCreativeAgentStreaming ||
isBigFishBusy ||
isMatch3DBusy ||
isSquareHoleBusy ||
isPuzzleBusy ||
isVisualNovelBusy ||
isVisualNovelStreamingReply ||
isBabyObjectMatchBusy
}
isBusy={sessionController.isCreatingAgentSession}
error={
creationEntryConfigError ??
bigFishError ??
@@ -11564,18 +11979,7 @@ export function PlatformEntryFlowShellImpl({
entryConfig={creationEntryConfig}
creationTypes={creationEntryTypes}
onClose={() => {
if (
sessionController.isCreatingAgentSession ||
isCreativeAgentBusy ||
isCreativeAgentStreaming ||
isBigFishBusy ||
isMatch3DBusy ||
isSquareHoleBusy ||
isPuzzleBusy ||
isVisualNovelBusy ||
isVisualNovelStreamingReply ||
isBabyObjectMatchBusy
) {
if (sessionController.isCreatingAgentSession) {
return;
}
setShowCreationTypeModal(false);