Merge branch 'master' into codex/puzzle-clear-template-runtime-fixes
This commit is contained in:
@@ -38,7 +38,10 @@ import type {
|
||||
BabyObjectMatchDraft,
|
||||
CreateBabyObjectMatchDraftRequest,
|
||||
} from '../../../packages/shared/src/contracts/edutainmentBabyObject';
|
||||
import type { JumpHopWorkSummaryResponse } from '../../../packages/shared/src/contracts/jumpHop';
|
||||
import type {
|
||||
JumpHopJumpRequest,
|
||||
JumpHopWorkSummaryResponse,
|
||||
} from '../../../packages/shared/src/contracts/jumpHop';
|
||||
import type {
|
||||
CreateMatch3DSessionRequest,
|
||||
ExecuteMatch3DActionRequest,
|
||||
@@ -67,6 +70,7 @@ import type {
|
||||
PuzzleAgentSessionSnapshot,
|
||||
SendPuzzleAgentMessageRequest,
|
||||
} from '../../../packages/shared/src/contracts/puzzleAgentSession';
|
||||
import { isPuzzleCompileActionReady } from './puzzleDraftGenerationState';
|
||||
import type { PuzzleCreativeTemplateSelection } from '../../../packages/shared/src/contracts/puzzleCreativeTemplate';
|
||||
import type {
|
||||
PuzzleRunSnapshot,
|
||||
@@ -127,6 +131,7 @@ import {
|
||||
} from '../../services/authService';
|
||||
import {
|
||||
createBarkBattleDraft,
|
||||
deleteBarkBattleWork,
|
||||
listBarkBattleGallery,
|
||||
listBarkBattleWorks,
|
||||
publishBarkBattleWork,
|
||||
@@ -188,6 +193,7 @@ import {
|
||||
jumpHopClient,
|
||||
type JumpHopGalleryCardResponse,
|
||||
type JumpHopRunResponse,
|
||||
type JumpHopRuntimeRequestOptions,
|
||||
type JumpHopSessionResponse,
|
||||
type JumpHopSessionSnapshotResponse,
|
||||
JumpHopWorkProfileResponse,
|
||||
@@ -386,6 +392,7 @@ import {
|
||||
resolvePuzzleWorkCoverImageSrc,
|
||||
} from '../custom-world-home/creationWorkShelf';
|
||||
import {
|
||||
buildPlatformPublicGalleryCardKey,
|
||||
isBarkBattleGalleryEntry,
|
||||
isBigFishGalleryEntry,
|
||||
isEdutainmentGalleryEntry,
|
||||
@@ -462,7 +469,6 @@ import {
|
||||
type PlatformErrorDialogPayload,
|
||||
} from './PlatformErrorDialog';
|
||||
import { PlatformFeedbackView } from './PlatformFeedbackView';
|
||||
import { shouldTickPlatformGenerationProgressClock } from './platformGenerationProgressClock';
|
||||
import {
|
||||
PlatformTaskCompletionDialog,
|
||||
type PlatformTaskCompletionDialogPayload,
|
||||
@@ -513,6 +519,31 @@ type PuzzleBackgroundCompileTask = {
|
||||
error: string | null;
|
||||
};
|
||||
|
||||
type MiniGameGenerationProgressTickStateMap = Partial<
|
||||
Record<MiniGameDraftGenerationKind, MiniGameDraftGenerationState | null>
|
||||
>;
|
||||
|
||||
export function resolveMiniGameGenerationProgressTickState(
|
||||
selectionStage: SelectionStage,
|
||||
states: MiniGameGenerationProgressTickStateMap,
|
||||
) {
|
||||
const stageKindMap: Partial<
|
||||
Record<SelectionStage, MiniGameDraftGenerationKind>
|
||||
> = {
|
||||
'puzzle-generating': 'puzzle',
|
||||
'big-fish-generating': 'big-fish',
|
||||
'square-hole-generating': 'square-hole',
|
||||
'match3d-generating': 'match3d',
|
||||
'baby-object-match-generating': 'baby-object-match',
|
||||
'jump-hop-generating': 'jump-hop',
|
||||
'puzzle-clear-generating': 'puzzle-clear',
|
||||
'wooden-fish-generating': 'wooden-fish',
|
||||
};
|
||||
const kind = stageKindMap[selectionStage];
|
||||
|
||||
return kind ? (states[kind] ?? null) : null;
|
||||
}
|
||||
|
||||
type PuzzleDetailReturnTarget = {
|
||||
tab: PlatformHomeTab;
|
||||
};
|
||||
@@ -574,6 +605,7 @@ type BabyObjectMatchGenerationPhase = 'generating' | 'ready' | 'failed';
|
||||
|
||||
type RecommendRuntimeState = {
|
||||
activeKind: RecommendRuntimeKind | null;
|
||||
barkBattlePublishedConfig: BarkBattlePublishedConfig | null;
|
||||
babyObjectMatchDraft: BabyObjectMatchDraft | null;
|
||||
bigFishRun: BigFishRuntimeSnapshotResponse | null;
|
||||
jumpHopRun: JumpHopRunResponse['run'] | null;
|
||||
@@ -621,11 +653,11 @@ const AGENT_RESULT_STRUCTURAL_BLOCKER_CODES = new Set([
|
||||
'publish_missing_main_chapter',
|
||||
'publish_missing_first_act',
|
||||
]);
|
||||
const RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS =
|
||||
const RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS: JumpHopRuntimeRequestOptions =
|
||||
BACKGROUND_AUTH_REQUEST_OPTIONS;
|
||||
const RECOMMEND_PUZZLE_BACKGROUND_AUTH_OPTIONS =
|
||||
const RECOMMEND_PUZZLE_BACKGROUND_AUTH_OPTIONS: JumpHopRuntimeRequestOptions =
|
||||
RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS;
|
||||
async function buildRecommendRuntimeGuestOptions() {
|
||||
async function buildRecommendRuntimeGuestOptions(): Promise<JumpHopRuntimeRequestOptions> {
|
||||
const { token } = await ensureRuntimeGuestToken();
|
||||
return {
|
||||
...RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS,
|
||||
@@ -640,9 +672,9 @@ function shouldUseRecommendRuntimeGuestAuth(
|
||||
async function buildRecommendRuntimeAuthOptions(
|
||||
authUi: { user?: { id?: string } | null } | null | undefined,
|
||||
embedded?: boolean,
|
||||
) {
|
||||
): Promise<JumpHopRuntimeRequestOptions> {
|
||||
if (!embedded) {
|
||||
return {};
|
||||
return RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS;
|
||||
}
|
||||
|
||||
if (shouldUseRecommendRuntimeGuestAuth(authUi)) {
|
||||
@@ -662,28 +694,7 @@ function getPlatformPublicGalleryEntryTime(entry: PlatformPublicGalleryCard) {
|
||||
}
|
||||
|
||||
function getPlatformPublicGalleryEntryKey(entry: PlatformPublicGalleryCard) {
|
||||
const kind = isBigFishGalleryEntry(entry)
|
||||
? 'big-fish'
|
||||
: isPuzzleGalleryEntry(entry)
|
||||
? 'puzzle'
|
||||
: isPuzzleClearGalleryEntry(entry)
|
||||
? 'puzzle-clear'
|
||||
: isJumpHopGalleryEntry(entry)
|
||||
? 'jump-hop'
|
||||
: isWoodenFishGalleryEntry(entry)
|
||||
? 'wooden-fish'
|
||||
: isMatch3DGalleryEntry(entry)
|
||||
? 'match3d'
|
||||
: isSquareHoleGalleryEntry(entry)
|
||||
? 'square-hole'
|
||||
: isVisualNovelGalleryEntry(entry)
|
||||
? 'visual-novel'
|
||||
: isBarkBattleGalleryEntry(entry)
|
||||
? 'bark-battle'
|
||||
: isEdutainmentGalleryEntry(entry)
|
||||
? `edutainment:${entry.templateId}`
|
||||
: 'rpg';
|
||||
return `${kind}:${entry.ownerUserId}:${entry.profileId}`;
|
||||
return buildPlatformPublicGalleryCardKey(entry);
|
||||
}
|
||||
|
||||
function getPlatformRecommendRuntimeKind(
|
||||
@@ -769,7 +780,7 @@ function isRecommendRuntimeReadyForEntry(
|
||||
return Boolean(state.visualNovelRun);
|
||||
}
|
||||
if (expectedKind === 'bark-battle') {
|
||||
return true;
|
||||
return Boolean(state.barkBattlePublishedConfig);
|
||||
}
|
||||
if (expectedKind === 'edutainment') {
|
||||
return Boolean(state.babyObjectMatchDraft);
|
||||
@@ -2084,6 +2095,7 @@ function buildJumpHopPendingSession(
|
||||
templateId: 'jump-hop',
|
||||
templateName: '跳一跳',
|
||||
profileId: item.profileId,
|
||||
themeText: item.themeText || item.workTitle,
|
||||
workTitle: item.workTitle,
|
||||
workDescription: item.workDescription,
|
||||
themeTags: item.themeTags,
|
||||
@@ -2899,6 +2911,7 @@ function buildPendingJumpHopWorks(
|
||||
profileId: `jump-hop-profile-${sessionId}`,
|
||||
ownerUserId: '',
|
||||
sourceSessionId: sessionId,
|
||||
themeText: '跳一跳',
|
||||
workTitle: '跳一跳草稿',
|
||||
workDescription:
|
||||
state.status === 'failed'
|
||||
@@ -3785,6 +3798,8 @@ export function PlatformEntryFlowShellImpl({
|
||||
const [jumpHopRun, setJumpHopRun] = useState<
|
||||
JumpHopRunResponse['run'] | null
|
||||
>(null);
|
||||
const [jumpHopRuntimeRequestOptions, setJumpHopRuntimeRequestOptions] =
|
||||
useState<JumpHopRuntimeRequestOptions | null>(null);
|
||||
const [jumpHopWork, setJumpHopWork] =
|
||||
useState<JumpHopWorkProfileResponse | null>(null);
|
||||
const [jumpHopGalleryEntries, setJumpHopGalleryEntries] = useState<
|
||||
@@ -5644,30 +5659,27 @@ export function PlatformEntryFlowShellImpl({
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const activeGenerationState =
|
||||
selectionStage === 'puzzle-generating'
|
||||
? puzzleGenerationState
|
||||
: selectionStage === 'match3d-generating'
|
||||
? match3dGenerationState
|
||||
: selectionStage === 'big-fish-generating'
|
||||
? bigFishGenerationState
|
||||
: selectionStage === 'square-hole-generating'
|
||||
? squareHoleGenerationState
|
||||
: selectionStage === 'jump-hop-generating'
|
||||
? jumpHopGenerationState
|
||||
: selectionStage === 'puzzle-clear-generating'
|
||||
? puzzleClearGenerationState
|
||||
: selectionStage === 'wooden-fish-generating'
|
||||
? woodenFishGenerationState
|
||||
: selectionStage === 'baby-object-match-generating'
|
||||
? babyObjectMatchGenerationState
|
||||
: null;
|
||||
const shouldTickProgress = shouldTickPlatformGenerationProgressClock({
|
||||
const activeGenerationState = resolveMiniGameGenerationProgressTickState(
|
||||
selectionStage,
|
||||
generationState: activeGenerationState,
|
||||
visualNovelGenerationStartedAtMs,
|
||||
visualNovelGenerationPhase,
|
||||
});
|
||||
{
|
||||
puzzle: puzzleGenerationState,
|
||||
'big-fish': bigFishGenerationState,
|
||||
'square-hole': squareHoleGenerationState,
|
||||
match3d: match3dGenerationState,
|
||||
'baby-object-match': babyObjectMatchGenerationState,
|
||||
'jump-hop': jumpHopGenerationState,
|
||||
'puzzle-clear': puzzleClearGenerationState,
|
||||
'wooden-fish': woodenFishGenerationState,
|
||||
},
|
||||
);
|
||||
const shouldTickProgress =
|
||||
selectionStage === 'visual-novel-generating'
|
||||
? visualNovelGenerationStartedAtMs != null &&
|
||||
visualNovelGenerationPhase !== 'ready' &&
|
||||
visualNovelGenerationPhase !== 'failed'
|
||||
: activeGenerationState != null &&
|
||||
activeGenerationState.phase !== 'ready' &&
|
||||
activeGenerationState.phase !== 'failed';
|
||||
|
||||
if (!shouldTickProgress) {
|
||||
return undefined;
|
||||
@@ -6505,7 +6517,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
sessionController.setCreationTypeError(errorMessage);
|
||||
setPuzzleCreationError(errorMessage);
|
||||
},
|
||||
onActionComplete: async ({ payload, response, setSession }) => {
|
||||
onActionComplete: async ({ payload, response, session, setSession }) => {
|
||||
setPuzzleOperation(response.operation);
|
||||
setSession(response.session);
|
||||
const formPayload = buildPuzzleFormPayloadFromAction(payload);
|
||||
@@ -6529,6 +6541,47 @@ export function PlatformEntryFlowShellImpl({
|
||||
|
||||
if (payload.action === 'compile_puzzle_draft') {
|
||||
const openResult = selectionStageRef.current === 'puzzle-generating';
|
||||
if (!isPuzzleCompileActionReady(response.session)) {
|
||||
const nextPayload =
|
||||
formPayload ?? buildPuzzleFormPayloadFromSession(response.session);
|
||||
const fallbackGenerationState = createPuzzleDraftGenerationStateFromPayload(
|
||||
nextPayload,
|
||||
response.session,
|
||||
);
|
||||
const nextGenerationState = mergePuzzleSessionProgressIntoGenerationState(
|
||||
puzzleGenerationState ?? fallbackGenerationState,
|
||||
response.session,
|
||||
);
|
||||
activePuzzleGenerationSessionIdRef.current = response.session.sessionId;
|
||||
setSelectionStage('puzzle-generating');
|
||||
markDraftGenerating('puzzle', [
|
||||
response.session.sessionId,
|
||||
buildPuzzleResultWorkId(response.session.sessionId),
|
||||
response.session.publishedProfileId,
|
||||
buildPuzzleResultProfileId(response.session.sessionId),
|
||||
]);
|
||||
markPendingDraftGenerating(
|
||||
'puzzle',
|
||||
response.session.sessionId,
|
||||
buildPendingPuzzleDraftMetadata(nextPayload),
|
||||
);
|
||||
setPuzzleGenerationState(nextGenerationState);
|
||||
setPuzzleBackgroundCompileTasks((current) => {
|
||||
const next = { ...current };
|
||||
if (session.sessionId !== response.session.sessionId) {
|
||||
delete next[session.sessionId];
|
||||
}
|
||||
next[response.session.sessionId] = {
|
||||
session: response.session,
|
||||
payload: nextPayload,
|
||||
generationState: nextGenerationState,
|
||||
error: null,
|
||||
};
|
||||
return next;
|
||||
});
|
||||
void refreshPuzzleShelf();
|
||||
return { openResult: false };
|
||||
}
|
||||
setPuzzleGenerationState((current) =>
|
||||
current
|
||||
? resolveFinishedMiniGameDraftGenerationState(current, 'ready', {
|
||||
@@ -7445,6 +7498,22 @@ export function PlatformEntryFlowShellImpl({
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasRecoverableGeneratedPuzzleDraft(latestSession)) {
|
||||
const payload =
|
||||
puzzleGenerationViewPayload ??
|
||||
buildPuzzleFormPayloadFromSession(latestSession);
|
||||
const generationState =
|
||||
puzzleGenerationViewState ??
|
||||
createPuzzleDraftGenerationStateFromPayload(payload, latestSession);
|
||||
await recoverCompletedPuzzleDraftGeneration({
|
||||
sessionId: latestSession.sessionId,
|
||||
payload,
|
||||
generationState,
|
||||
setSession: setPuzzleSession,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setPuzzleSession(latestSession);
|
||||
setPuzzleBackgroundCompileTasks((current) => {
|
||||
const task = current[activePuzzleGenerationSessionId];
|
||||
@@ -7488,6 +7557,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
};
|
||||
}, [
|
||||
activePuzzleGenerationSessionId,
|
||||
puzzleGenerationViewPayload,
|
||||
puzzleGenerationViewState,
|
||||
recoverCompletedPuzzleDraftGeneration,
|
||||
shouldPollPuzzleGenerationSession,
|
||||
setPuzzleSession,
|
||||
]);
|
||||
@@ -7616,6 +7688,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
setJumpHopSession(null);
|
||||
setJumpHopWork(null);
|
||||
setJumpHopRun(null);
|
||||
setJumpHopRuntimeRequestOptions(null);
|
||||
setJumpHopGenerationState(null);
|
||||
enterCreateTab();
|
||||
setShowCreationTypeModal(false);
|
||||
@@ -8778,6 +8851,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
setJumpHopRuntimeReturnStage('jump-hop-result');
|
||||
setJumpHopGenerationState(null);
|
||||
setJumpHopSession(null);
|
||||
setJumpHopRuntimeRequestOptions(null);
|
||||
setJumpHopError(null);
|
||||
returnToCreationFlowSource();
|
||||
}, [returnToCreationFlowSource]);
|
||||
@@ -9774,20 +9848,26 @@ export function PlatformEntryFlowShellImpl({
|
||||
const executeSquareHoleAction = squareHoleFlow.executeAction;
|
||||
|
||||
const retryMatch3DDraftGeneration = useCallback(() => {
|
||||
if (match3dFormDraftPayload && !match3dSession?.draft?.profileId) {
|
||||
void createMatch3DDraftFromForm(match3dFormDraftPayload);
|
||||
if (match3dSession?.sessionId) {
|
||||
const retryPayload =
|
||||
match3dFormDraftPayload ??
|
||||
buildMatch3DFormPayloadFromSession(match3dSession);
|
||||
void executeMatch3DAction({
|
||||
action: 'match3d_compile_draft',
|
||||
generateClickSound: retryPayload.generateClickSound,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
void executeMatch3DAction({
|
||||
action: 'match3d_compile_draft',
|
||||
generateClickSound: match3dFormDraftPayload?.generateClickSound,
|
||||
});
|
||||
if (match3dFormDraftPayload) {
|
||||
void createMatch3DDraftFromForm(match3dFormDraftPayload);
|
||||
return;
|
||||
}
|
||||
}, [
|
||||
createMatch3DDraftFromForm,
|
||||
executeMatch3DAction,
|
||||
match3dFormDraftPayload,
|
||||
match3dSession?.draft?.profileId,
|
||||
match3dSession,
|
||||
]);
|
||||
|
||||
const retrySquareHoleAssetGeneration = useCallback(() => {
|
||||
@@ -9820,6 +9900,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
);
|
||||
setJumpHopWork(null);
|
||||
setJumpHopRun(null);
|
||||
setJumpHopRuntimeRequestOptions(null);
|
||||
setJumpHopGenerationState(generationState);
|
||||
setIsJumpHopBusy(true);
|
||||
setSelectionStage('jump-hop-generating');
|
||||
@@ -9834,6 +9915,8 @@ export function PlatformEntryFlowShellImpl({
|
||||
created.session.sessionId,
|
||||
{
|
||||
actionType: 'compile-draft',
|
||||
themeText:
|
||||
payload?.themeText ?? created.session.draft?.themeText,
|
||||
workTitle: payload?.workTitle ?? created.session.draft?.workTitle,
|
||||
workDescription:
|
||||
payload?.workDescription ??
|
||||
@@ -9948,7 +10031,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
}, [compileJumpHopSession, jumpHopSession, setSelectionStage]);
|
||||
|
||||
const regenerateJumpHopAsset = useCallback(
|
||||
async (actionType: 'regenerate-character' | 'regenerate-tiles') => {
|
||||
async (actionType: 'regenerate-tiles') => {
|
||||
if (!jumpHopSession?.sessionId) {
|
||||
setSelectionStage('jump-hop-workspace');
|
||||
return;
|
||||
@@ -9964,6 +10047,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
jumpHopSession.sessionId,
|
||||
{
|
||||
actionType,
|
||||
profileId:
|
||||
jumpHopWork?.summary.profileId ?? jumpHopSession.draft?.profileId,
|
||||
themeText: jumpHopSession.draft?.themeText,
|
||||
workTitle: jumpHopSession.draft?.workTitle,
|
||||
workDescription: jumpHopSession.draft?.workDescription,
|
||||
themeTags: jumpHopSession.draft?.themeTags,
|
||||
@@ -9989,9 +10075,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
} catch (error) {
|
||||
const errorMessage = resolveRpgCreationErrorMessage(
|
||||
error,
|
||||
actionType === 'regenerate-character'
|
||||
? '重新生成跳一跳角色失败。'
|
||||
: '重新生成跳一跳地块失败。',
|
||||
'重新生成跳一跳地块失败。',
|
||||
);
|
||||
setJumpHopError(errorMessage);
|
||||
setJumpHopGenerationState(
|
||||
@@ -10067,7 +10151,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
setJumpHopError(null);
|
||||
setJumpHopRuntimeReturnStage('jump-hop-result');
|
||||
try {
|
||||
const response = await jumpHopClient.startRun(profileId);
|
||||
const response = await jumpHopClient.startRun(profileId, {
|
||||
runtimeMode: 'draft',
|
||||
});
|
||||
setJumpHopRun(response.run);
|
||||
setSelectionStage('jump-hop-runtime');
|
||||
} catch (error) {
|
||||
@@ -10098,13 +10184,30 @@ export function PlatformEntryFlowShellImpl({
|
||||
setJumpHopError(null);
|
||||
setJumpHopRuntimeReturnStage(options.returnStage ?? 'work-detail');
|
||||
try {
|
||||
const runtimeGuestOptions = await buildRecommendRuntimeAuthOptions(
|
||||
authUi,
|
||||
options.embedded,
|
||||
const runtimeGuestOptions =
|
||||
options.embedded || shouldUseRecommendRuntimeGuestAuth(authUi)
|
||||
? await buildRecommendRuntimeAuthOptions(authUi, true)
|
||||
: RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS;
|
||||
setJumpHopRuntimeRequestOptions(
|
||||
runtimeGuestOptions.runtimeGuestToken?.trim()
|
||||
? {
|
||||
runtimeGuestToken: runtimeGuestOptions.runtimeGuestToken,
|
||||
authImpact: runtimeGuestOptions.authImpact,
|
||||
skipAuth: runtimeGuestOptions.skipAuth,
|
||||
skipRefresh: runtimeGuestOptions.skipRefresh,
|
||||
notifyAuthStateChange:
|
||||
runtimeGuestOptions.notifyAuthStateChange,
|
||||
clearAuthOnUnauthorized:
|
||||
runtimeGuestOptions.clearAuthOnUnauthorized,
|
||||
}
|
||||
: null,
|
||||
);
|
||||
const [detail, runResponse] = await Promise.all([
|
||||
jumpHopClient.getWorkDetail(normalizedProfileId).catch(() => null),
|
||||
jumpHopClient.startRun(normalizedProfileId, runtimeGuestOptions),
|
||||
jumpHopClient.startRun(normalizedProfileId, {
|
||||
...runtimeGuestOptions,
|
||||
runtimeMode: 'published',
|
||||
}),
|
||||
]);
|
||||
if (detail?.item) {
|
||||
setJumpHopWork(detail.item);
|
||||
@@ -10142,7 +10245,10 @@ export function PlatformEntryFlowShellImpl({
|
||||
setIsJumpHopBusy(true);
|
||||
setJumpHopError(null);
|
||||
try {
|
||||
const response = await jumpHopClient.restartRun(runId);
|
||||
const response = await jumpHopClient.restartRun(
|
||||
runId,
|
||||
jumpHopRuntimeRequestOptions ?? undefined,
|
||||
);
|
||||
setJumpHopRun(response.run);
|
||||
} catch (error) {
|
||||
setJumpHopError(
|
||||
@@ -10151,16 +10257,29 @@ export function PlatformEntryFlowShellImpl({
|
||||
} finally {
|
||||
setIsJumpHopBusy(false);
|
||||
}
|
||||
}, [jumpHopRun?.runId, startJumpHopTestRunFromProfile]);
|
||||
}, [
|
||||
jumpHopRun?.runId,
|
||||
jumpHopRuntimeRequestOptions,
|
||||
startJumpHopTestRunFromProfile,
|
||||
]);
|
||||
|
||||
const submitJumpHopJumpAction = useCallback(
|
||||
async (payload: { chargeMs: number }) => {
|
||||
async (
|
||||
payload: Pick<
|
||||
JumpHopJumpRequest,
|
||||
'dragDistance' | 'dragVectorX' | 'dragVectorY'
|
||||
>,
|
||||
) => {
|
||||
const runId = jumpHopRun?.runId;
|
||||
if (!runId) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const response = await jumpHopClient.submitJump(runId, payload);
|
||||
const response = await jumpHopClient.submitJump(
|
||||
runId,
|
||||
payload,
|
||||
jumpHopRuntimeRequestOptions ?? undefined,
|
||||
);
|
||||
setJumpHopRun(response.run);
|
||||
} catch (error) {
|
||||
setJumpHopError(
|
||||
@@ -10168,7 +10287,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
);
|
||||
}
|
||||
},
|
||||
[jumpHopRun?.runId],
|
||||
[jumpHopRun?.runId, jumpHopRuntimeRequestOptions],
|
||||
);
|
||||
|
||||
const compilePuzzleClearSession = useCallback(
|
||||
@@ -11123,15 +11242,25 @@ export function PlatformEntryFlowShellImpl({
|
||||
);
|
||||
|
||||
const retryPuzzleDraftGeneration = useCallback(() => {
|
||||
if (puzzleFormDraftPayload) {
|
||||
void createPuzzleDraftFromForm(puzzleFormDraftPayload);
|
||||
if (puzzleSession?.sessionId) {
|
||||
const retryPayload =
|
||||
puzzleFormDraftPayload ??
|
||||
buildPuzzleFormPayloadFromSession(puzzleSession);
|
||||
void executePuzzleAction(
|
||||
buildPuzzleCompileActionFromFormPayload(retryPayload),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
void executePuzzleAction(
|
||||
buildPuzzleCompileActionFromFormPayload(puzzleFormDraftPayload),
|
||||
);
|
||||
}, [createPuzzleDraftFromForm, executePuzzleAction, puzzleFormDraftPayload]);
|
||||
if (puzzleFormDraftPayload) {
|
||||
void createPuzzleDraftFromForm(puzzleFormDraftPayload);
|
||||
}
|
||||
}, [
|
||||
createPuzzleDraftFromForm,
|
||||
executePuzzleAction,
|
||||
puzzleFormDraftPayload,
|
||||
puzzleSession,
|
||||
]);
|
||||
|
||||
const retryVisualNovelDraftGeneration = useCallback(() => {
|
||||
if (!visualNovelFormDraftPayload) {
|
||||
@@ -12929,6 +13058,154 @@ export function PlatformEntryFlowShellImpl({
|
||||
],
|
||||
);
|
||||
|
||||
const handleDeleteJumpHopWork = useCallback(
|
||||
(work: JumpHopWorkSummaryResponse) => {
|
||||
if (deletingCreationWorkId) {
|
||||
return;
|
||||
}
|
||||
const noticeKeys = collectDraftNoticeKeys('jump-hop', [
|
||||
work.workId,
|
||||
work.profileId,
|
||||
work.sourceSessionId,
|
||||
]);
|
||||
|
||||
requestDeleteCreationWork({
|
||||
id: work.workId,
|
||||
title: work.workTitle || '未命名跳一跳',
|
||||
detail:
|
||||
work.publicationStatus === 'published'
|
||||
? '删除后会从你的作品列表和公开广场中移除。'
|
||||
: '删除后会从你的作品列表中移除。',
|
||||
run: () => {
|
||||
setDeletingCreationWorkId(work.workId);
|
||||
setJumpHopError(null);
|
||||
|
||||
void jumpHopClient
|
||||
.deleteWork(work.profileId)
|
||||
.then((response) => {
|
||||
markDraftNoticeSeen(noticeKeys);
|
||||
setJumpHopWorks(response.items);
|
||||
void refreshJumpHopGallery();
|
||||
})
|
||||
.catch((error) => {
|
||||
setJumpHopError(
|
||||
resolvePuzzleErrorMessage(error, '删除跳一跳作品失败。'),
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
setDeletingCreationWorkId(null);
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
[
|
||||
deletingCreationWorkId,
|
||||
markDraftNoticeSeen,
|
||||
refreshJumpHopGallery,
|
||||
requestDeleteCreationWork,
|
||||
resolvePuzzleErrorMessage,
|
||||
setJumpHopError,
|
||||
],
|
||||
);
|
||||
|
||||
const handleDeleteWoodenFishWork = useCallback(
|
||||
(work: WoodenFishWorkSummaryResponse) => {
|
||||
if (deletingCreationWorkId) {
|
||||
return;
|
||||
}
|
||||
const noticeKeys = collectDraftNoticeKeys('wooden-fish', [
|
||||
work.workId,
|
||||
work.profileId,
|
||||
work.sourceSessionId,
|
||||
]);
|
||||
|
||||
requestDeleteCreationWork({
|
||||
id: work.workId,
|
||||
title: work.workTitle || '未命名敲木鱼',
|
||||
detail:
|
||||
work.publicationStatus === 'published'
|
||||
? '删除后会从你的作品列表和公开广场中移除。'
|
||||
: '删除后会从你的作品列表中移除。',
|
||||
run: () => {
|
||||
setDeletingCreationWorkId(work.workId);
|
||||
setWoodenFishError(null);
|
||||
|
||||
void woodenFishClient
|
||||
.deleteWork(work.profileId)
|
||||
.then((response) => {
|
||||
markDraftNoticeSeen(noticeKeys);
|
||||
setWoodenFishWorks(response.items);
|
||||
void refreshWoodenFishGallery();
|
||||
})
|
||||
.catch((error) => {
|
||||
setWoodenFishError(
|
||||
resolvePuzzleErrorMessage(error, '删除敲木鱼作品失败。'),
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
setDeletingCreationWorkId(null);
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
[
|
||||
deletingCreationWorkId,
|
||||
markDraftNoticeSeen,
|
||||
refreshWoodenFishGallery,
|
||||
requestDeleteCreationWork,
|
||||
resolvePuzzleErrorMessage,
|
||||
setWoodenFishError,
|
||||
],
|
||||
);
|
||||
|
||||
const handleDeleteBarkBattleWork = useCallback(
|
||||
(work: BarkBattleWorkSummary) => {
|
||||
if (deletingCreationWorkId) {
|
||||
return;
|
||||
}
|
||||
const noticeKeys = collectDraftNoticeKeys('bark-battle', [
|
||||
work.workId,
|
||||
work.draftId,
|
||||
]);
|
||||
|
||||
requestDeleteCreationWork({
|
||||
id: work.workId,
|
||||
title: work.title || '未命名汪汪声浪',
|
||||
detail:
|
||||
work.status === 'published'
|
||||
? '删除后会从你的作品列表和公开广场中移除。'
|
||||
: '删除后会从你的作品列表中移除。',
|
||||
run: () => {
|
||||
setDeletingCreationWorkId(work.workId);
|
||||
setBarkBattleError(null);
|
||||
|
||||
void deleteBarkBattleWork(work.workId)
|
||||
.then((response) => {
|
||||
markDraftNoticeSeen(noticeKeys);
|
||||
setBarkBattleWorks(mergeBarkBattleWorksByWorkId(response.items));
|
||||
void refreshBarkBattleGallery();
|
||||
})
|
||||
.catch((error) => {
|
||||
setBarkBattleError(
|
||||
resolveBarkBattleErrorMessage(error, '删除汪汪声浪作品失败。'),
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
setDeletingCreationWorkId(null);
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
[
|
||||
deletingCreationWorkId,
|
||||
markDraftNoticeSeen,
|
||||
refreshBarkBattleGallery,
|
||||
requestDeleteCreationWork,
|
||||
resolveBarkBattleErrorMessage,
|
||||
setBarkBattleError,
|
||||
],
|
||||
);
|
||||
|
||||
const handleDeleteVisualNovelWork = useCallback(
|
||||
(work: VisualNovelWorkSummary) => {
|
||||
if (deletingCreationWorkId) {
|
||||
@@ -15139,6 +15416,14 @@ export function PlatformEntryFlowShellImpl({
|
||||
return;
|
||||
}
|
||||
|
||||
if (isJumpHopGalleryEntry(selectedPublicWorkDetail)) {
|
||||
setPublicWorkDetailError(null);
|
||||
void startJumpHopRunFromProfile(selectedPublicWorkDetail.profileId, {
|
||||
returnStage: 'work-detail',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
runProtectedAction(() => {
|
||||
if (isBigFishGalleryEntry(selectedPublicWorkDetail)) {
|
||||
const work = mapPublicWorkDetailToBigFishWork(selectedPublicWorkDetail);
|
||||
@@ -15699,37 +15984,15 @@ export function PlatformEntryFlowShellImpl({
|
||||
run={jumpHopRun}
|
||||
isBusy={isJumpHopBusy}
|
||||
error={jumpHopError}
|
||||
runtimeRequestOptions={jumpHopRuntimeRequestOptions ?? undefined}
|
||||
onBack={() => {
|
||||
setActiveRecommendRuntimeKind(null);
|
||||
}}
|
||||
onRestart={() => {
|
||||
if (!jumpHopRun?.runId || isJumpHopBusy) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsJumpHopBusy(true);
|
||||
setJumpHopError(null);
|
||||
void jumpHopClient
|
||||
.restartRun(jumpHopRun.runId)
|
||||
.then((response) => {
|
||||
setJumpHopRun(response.run);
|
||||
})
|
||||
.catch((error) => {
|
||||
setJumpHopError(
|
||||
resolveRpgCreationErrorMessage(error, '重新开始跳一跳失败。'),
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
setIsJumpHopBusy(false);
|
||||
});
|
||||
void restartJumpHopRuntimeRun();
|
||||
}}
|
||||
onJump={async (payload) => {
|
||||
const runId = jumpHopRun?.runId;
|
||||
if (!runId) {
|
||||
throw new Error('跳一跳运行态缺少 runId。');
|
||||
}
|
||||
const response = await jumpHopClient.submitJump(runId, payload);
|
||||
setJumpHopRun(response.run);
|
||||
await submitJumpHopJumpAction(payload);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -15975,6 +16238,30 @@ export function PlatformEntryFlowShellImpl({
|
||||
swapPuzzleClearCardsInRun,
|
||||
]);
|
||||
|
||||
const activeRecommendEntry =
|
||||
activeRecommendEntryKey && !isDesktopLayout
|
||||
? (recommendRuntimeEntries.find(
|
||||
(entry) =>
|
||||
getPlatformPublicGalleryEntryKey(entry) ===
|
||||
activeRecommendEntryKey,
|
||||
) ?? null)
|
||||
: null;
|
||||
const isActiveRecommendRuntimeReady =
|
||||
activeRecommendEntry !== null &&
|
||||
isRecommendRuntimeReadyForEntry(activeRecommendEntry, {
|
||||
activeKind: activeRecommendRuntimeKind,
|
||||
barkBattlePublishedConfig,
|
||||
babyObjectMatchDraft,
|
||||
bigFishRun,
|
||||
jumpHopRun,
|
||||
match3dRun,
|
||||
puzzleRun,
|
||||
puzzleClearRun,
|
||||
squareHoleRun,
|
||||
visualNovelRun,
|
||||
woodenFishRun,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
isDesktopLayout ||
|
||||
@@ -15992,26 +16279,6 @@ export function PlatformEntryFlowShellImpl({
|
||||
return;
|
||||
}
|
||||
|
||||
const activeRecommendEntry = activeRecommendEntryKey
|
||||
? (recommendRuntimeEntries.find(
|
||||
(entry) =>
|
||||
getPlatformPublicGalleryEntryKey(entry) === activeRecommendEntryKey,
|
||||
) ?? null)
|
||||
: null;
|
||||
const isActiveRecommendRuntimeReady =
|
||||
activeRecommendEntry !== null &&
|
||||
isRecommendRuntimeReadyForEntry(activeRecommendEntry, {
|
||||
activeKind: activeRecommendRuntimeKind,
|
||||
babyObjectMatchDraft,
|
||||
bigFishRun,
|
||||
jumpHopRun,
|
||||
match3dRun,
|
||||
puzzleRun,
|
||||
puzzleClearRun,
|
||||
squareHoleRun,
|
||||
visualNovelRun,
|
||||
woodenFishRun,
|
||||
});
|
||||
if (
|
||||
(activeRecommendEntry !== null && isActiveRecommendRuntimeReady) ||
|
||||
isStartingRecommendEntry
|
||||
@@ -16027,9 +16294,12 @@ export function PlatformEntryFlowShellImpl({
|
||||
}, [
|
||||
activeRecommendEntryKey,
|
||||
activeRecommendRuntimeKind,
|
||||
activeRecommendEntry,
|
||||
barkBattlePublishedConfig,
|
||||
babyObjectMatchDraft,
|
||||
bigFishRun,
|
||||
jumpHopRun,
|
||||
isActiveRecommendRuntimeReady,
|
||||
isStartingRecommendEntry,
|
||||
match3dRun,
|
||||
platformBootstrap.isLoadingPlatform,
|
||||
@@ -17316,7 +17586,13 @@ export function PlatformEntryFlowShellImpl({
|
||||
}
|
||||
: null
|
||||
}
|
||||
onDeleteJumpHop={null}
|
||||
onDeleteJumpHop={
|
||||
isJumpHopCreationVisible
|
||||
? (item) => {
|
||||
handleDeleteJumpHopWork(item);
|
||||
}
|
||||
: null
|
||||
}
|
||||
onOpenPuzzleClearDetail={
|
||||
isPuzzleClearCreationVisible
|
||||
? (item) => {
|
||||
@@ -17334,7 +17610,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
void openWoodenFishDraft(item);
|
||||
});
|
||||
}}
|
||||
onDeleteWoodenFish={null}
|
||||
onDeleteWoodenFish={(item) => {
|
||||
handleDeleteWoodenFishWork(item);
|
||||
}}
|
||||
match3dItems={match3dShelfItems}
|
||||
onOpenMatch3DDetail={(item) => {
|
||||
runProtectedAction(() => {
|
||||
@@ -17398,6 +17676,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
openBarkBattleDraft(item);
|
||||
});
|
||||
}}
|
||||
onDeleteBarkBattle={(item) => {
|
||||
handleDeleteBarkBattleWork(item);
|
||||
}}
|
||||
visualNovelItems={visualNovelShelfItems}
|
||||
onOpenVisualNovelDetail={(item) => {
|
||||
runProtectedAction(() => {
|
||||
@@ -17482,6 +17763,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
onOpenRecommendGalleryDetail={openRecommendGalleryDetail}
|
||||
recommendRuntimeContent={recommendRuntimeContent}
|
||||
activeRecommendEntryKey={activeRecommendEntryKey}
|
||||
isRecommendRuntimeReady={isActiveRecommendRuntimeReady}
|
||||
isStartingRecommendEntry={
|
||||
isStartingRecommendEntry ||
|
||||
isBigFishBusy ||
|
||||
@@ -17847,7 +18129,6 @@ export function PlatformEntryFlowShellImpl({
|
||||
backLabel="返回创作中心"
|
||||
settingActionLabel={null}
|
||||
retryLabel="重新生成草稿"
|
||||
settingTitle="当前玩法信息"
|
||||
settingDescription={null}
|
||||
progressTitle="大鱼吃小鱼草稿生成进度"
|
||||
activeBadgeLabel="草稿生成中"
|
||||
@@ -18253,7 +18534,6 @@ export function PlatformEntryFlowShellImpl({
|
||||
backLabel="返回创作中心"
|
||||
settingActionLabel={null}
|
||||
retryLabel="重新生成草稿"
|
||||
settingTitle="当前宝贝识物信息"
|
||||
settingDescription={null}
|
||||
progressTitle="宝贝识物草稿生成进度"
|
||||
activeBadgeLabel="草稿生成中"
|
||||
@@ -18454,7 +18734,6 @@ export function PlatformEntryFlowShellImpl({
|
||||
backLabel="返回创作中心"
|
||||
settingActionLabel={null}
|
||||
retryLabel="重新生成图片"
|
||||
settingTitle="当前方洞挑战"
|
||||
settingDescription={null}
|
||||
progressTitle="方洞挑战图片生成进度"
|
||||
activeBadgeLabel="图片生成中"
|
||||
@@ -18697,9 +18976,6 @@ export function PlatformEntryFlowShellImpl({
|
||||
}}
|
||||
onStartTestRun={startJumpHopTestRunFromProfile}
|
||||
onPublish={publishJumpHopDraft}
|
||||
onRegenerateCharacter={() => {
|
||||
void regenerateJumpHopAsset('regenerate-character');
|
||||
}}
|
||||
onRegenerateTiles={() => {
|
||||
void regenerateJumpHopAsset('regenerate-tiles');
|
||||
}}
|
||||
@@ -18735,6 +19011,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
profile={jumpHopWork}
|
||||
isBusy={isJumpHopBusy}
|
||||
error={jumpHopError}
|
||||
runtimeRequestOptions={jumpHopRuntimeRequestOptions ?? undefined}
|
||||
onBack={() => {
|
||||
setSelectionStage(jumpHopRuntimeReturnStage);
|
||||
}}
|
||||
@@ -19250,7 +19527,6 @@ export function PlatformEntryFlowShellImpl({
|
||||
backLabel="返回创作中心"
|
||||
settingActionLabel={null}
|
||||
retryLabel="重新生成草稿"
|
||||
settingTitle="当前视觉小说信息"
|
||||
settingDescription={null}
|
||||
progressTitle="视觉小说草稿生成进度"
|
||||
activeBadgeLabel="草稿生成中"
|
||||
@@ -19501,7 +19777,6 @@ export function PlatformEntryFlowShellImpl({
|
||||
backLabel="返回创作中心"
|
||||
settingActionLabel={null}
|
||||
retryLabel="继续生成草稿"
|
||||
settingTitle="当前世界信息"
|
||||
settingDescription={null}
|
||||
progressTitle="世界草稿生成进度"
|
||||
activeBadgeLabel="草稿编译中"
|
||||
|
||||
Reference in New Issue
Block a user