Merge remote-tracking branch 'origin/master' into codex/public-work-readmodel-smooth-transition

This commit is contained in:
kdletters
2026-05-26 16:38:38 +08:00
130 changed files with 2966 additions and 511 deletions

View File

@@ -107,6 +107,12 @@ import type {
VisualNovelWorkSummary,
} from '../../../packages/shared/src/contracts/visualNovel';
import { buildCustomWorldPlayableCharacters } from '../../data/characterPresets';
import {
MATCH3D_DEMO_GALLERY_CARD,
MATCH3D_DEMO_PROFILE_ID,
MATCH3D_DEMO_WORK_PROFILE,
isMatch3DDemoProfileId,
} from '../../data/match3dDemoGalleryCard';
import {
buildPublicWorkStagePath,
pushAppHistoryPath,
@@ -198,7 +204,10 @@ import {
} from '../../services/jump-hop/jumpHopClient';
import type { JumpHopWorkSummaryResponse } from '../../../packages/shared/src/contracts/jumpHop';
import { match3dCreationClient } from '../../services/match3d-creation';
import { createServerMatch3DRuntimeAdapter } from '../../services/match3d-runtime';
import {
createLocalMatch3DRuntimeAdapter,
createServerMatch3DRuntimeAdapter,
} from '../../services/match3d-runtime';
import {
deleteMatch3DWork,
getMatch3DWorkDetail,
@@ -3524,6 +3533,13 @@ export function PlatformEntryFlowShellImpl({
setSelectedDetailEntry,
});
const { setPlatformTab } = platformBootstrap;
const returnPlatformHomeAfterMissingWork = useCallback(() => {
setPlatformTab('home');
setSelectionStage('platform');
if (!maybeAlertWorkNotFoundAndReturnHome()) {
pushAppHistoryPath('/');
}
}, [setPlatformTab, setSelectionStage]);
useEffect(() => {
if (selectionStage === 'profile-feedback') {
@@ -4177,6 +4193,8 @@ export function PlatformEntryFlowShellImpl({
}
return '服务端预览';
}, [agentResultPreview]);
const match3dDemoProfile = MATCH3D_DEMO_WORK_PROFILE;
const match3dDemoGalleryCard = MATCH3D_DEMO_GALLERY_CARD;
const featuredGalleryEntries = useMemo(() => {
const bigFishPublicEntries = isBigFishCreationVisible
@@ -4216,6 +4234,7 @@ export function PlatformEntryFlowShellImpl({
[
...bigFishPublicEntries,
...match3dPublicEntries,
match3dDemoGalleryCard,
...puzzlePublicEntries,
...barkBattlePublicEntries,
...squareHolePublicEntries,
@@ -4240,6 +4259,7 @@ export function PlatformEntryFlowShellImpl({
squareHoleGalleryEntries,
visualNovelGalleryEntries,
woodenFishGalleryEntries,
match3dDemoGalleryCard,
]);
const latestGalleryEntries = useMemo(
() =>
@@ -4250,6 +4270,7 @@ export function PlatformEntryFlowShellImpl({
? bigFishGalleryEntries.map(mapBigFishWorkToPlatformGalleryCard)
: []),
...match3dGalleryEntries.map(mapMatch3DWorkToPublicWorkDetail),
match3dDemoGalleryCard,
...puzzleGalleryEntries.map(mapPuzzleWorkToPlatformGalleryCard),
...barkBattleGalleryEntries.map(mapBarkBattleWorkToPlatformGalleryCard),
...jumpHopGalleryEntries.map(mapJumpHopWorkToPlatformGalleryCard),
@@ -4291,6 +4312,7 @@ export function PlatformEntryFlowShellImpl({
barkBattleGalleryEntries,
barkBattleWorks,
woodenFishGalleryEntries,
match3dDemoGalleryCard,
],
);
const recommendRuntimeEntries = useMemo(() => {
@@ -4298,9 +4320,11 @@ export function PlatformEntryFlowShellImpl({
filterGeneralPublicWorks([
...featuredGalleryEntries,
...latestGalleryEntries,
]).forEach((entry) => {
entryMap.set(getPlatformPublicGalleryEntryKey(entry), entry);
});
])
.filter((entry) => !isMatch3DDemoProfileId(entry.profileId))
.forEach((entry) => {
entryMap.set(getPlatformPublicGalleryEntryKey(entry), entry);
});
return Array.from(entryMap.values());
}, [featuredGalleryEntries, latestGalleryEntries]);
@@ -4836,6 +4860,21 @@ export function PlatformEntryFlowShellImpl({
() => createServerMatch3DRuntimeAdapter(),
[],
);
const match3dDemoRuntimeAdapter = useMemo(
() =>
createLocalMatch3DRuntimeAdapter({
clearCount: 21,
profileId: MATCH3D_DEMO_PROFILE_ID,
}),
[],
);
const resolveMatch3DRuntimeAdapter = useCallback(
(profileId: string | null | undefined) =>
isMatch3DDemoProfileId(profileId)
? match3dDemoRuntimeAdapter
: match3dRuntimeAdapter,
[match3dDemoRuntimeAdapter, match3dRuntimeAdapter],
);
const match3dFlow = usePlatformCreationAgentFlowController<
Match3DAgentSessionSnapshot,
CreateMatch3DSessionRequest,
@@ -9076,13 +9115,12 @@ export function PlatformEntryFlowShellImpl({
setPuzzleDetailReturnTarget(null);
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
setPuzzleGalleryEntries((current) =>
current.filter((entry) => entry.profileId !== profileId),
);
setPuzzleError(null);
setPublicWorkDetailError(null);
setPlatformTab('home');
setSelectionStage('platform');
if (!maybeAlertWorkNotFoundAndReturnHome()) {
pushAppHistoryPath('/');
}
returnPlatformHomeAfterMissingWork();
return false;
}
@@ -9103,9 +9141,9 @@ export function PlatformEntryFlowShellImpl({
isPuzzleBusy,
authUi,
resolvePuzzleErrorMessage,
returnPlatformHomeAfterMissingWork,
setIsPuzzleBusy,
setPuzzleError,
setPlatformTab,
setSelectionStage,
],
);
@@ -9125,10 +9163,13 @@ export function PlatformEntryFlowShellImpl({
setMatch3DError(null);
try {
let runtimeProfile = profile;
const isDemoProfile = isMatch3DDemoProfileId(profile.profileId);
let runtimeProfile: Match3DWorkProfile | Match3DWorkSummary =
isDemoProfile ? match3dDemoProfile : profile;
if (
!hasMatch3DRuntimeAsset(profile.generatedItemAssets) ||
!hasMatch3DRuntimeBackgroundAsset(profile)
!isDemoProfile &&
(!hasMatch3DRuntimeAsset(profile.generatedItemAssets) ||
!hasMatch3DRuntimeBackgroundAsset(profile))
) {
try {
const { item } = await getMatch3DWorkDetail(profile.profileId);
@@ -9164,7 +9205,10 @@ export function PlatformEntryFlowShellImpl({
? { itemTypeCountOverride: options.itemTypeCountOverride }
: {}),
};
const { run } = await match3dRuntimeAdapter.startRun(
const activeRuntimeAdapter = resolveMatch3DRuntimeAdapter(
runtimeProfile.profileId,
);
const { run } = await activeRuntimeAdapter.startRun(
runtimeProfile.profileId,
runtimeOptions,
);
@@ -9204,10 +9248,11 @@ export function PlatformEntryFlowShellImpl({
},
[
isMatch3DBusy,
match3dDemoProfile,
authUi,
match3dFlow,
match3dRuntimeAdapter,
resolveMatch3DErrorMessage,
resolveMatch3DRuntimeAdapter,
setMatch3DError,
setSelectionStage,
],
@@ -10945,13 +10990,12 @@ export function PlatformEntryFlowShellImpl({
setPuzzleDetailReturnTarget(null);
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
setPuzzleGalleryEntries((current) =>
current.filter((entry) => entry.profileId !== profileId),
);
setPuzzleError(null);
setPublicWorkDetailError(null);
setPlatformTab('home');
setSelectionStage('platform');
if (!maybeAlertWorkNotFoundAndReturnHome()) {
pushAppHistoryPath('/');
}
returnPlatformHomeAfterMissingWork();
return;
}
@@ -10969,7 +11013,6 @@ export function PlatformEntryFlowShellImpl({
resolvePuzzleErrorMessage,
setIsPuzzleBusy,
setPuzzleError,
setPlatformTab,
setSelectionStage,
],
);
@@ -10984,8 +11027,11 @@ export function PlatformEntryFlowShellImpl({
try {
const entries =
match3dGalleryEntries.length > 0
? match3dGalleryEntries
: await refreshMatch3DGallery();
? [...match3dGalleryEntries, match3dDemoProfile]
: await refreshMatch3DGallery().then((items) => [
...items,
match3dDemoProfile,
]);
const matchedEntry = entries.find(
(entry) => entry.profileId === profileId,
);
@@ -11005,6 +11051,7 @@ export function PlatformEntryFlowShellImpl({
},
[
match3dGalleryEntries,
match3dDemoProfile,
openPublicWorkDetail,
refreshMatch3DGallery,
resolveMatch3DErrorMessage,
@@ -11291,8 +11338,7 @@ export function PlatformEntryFlowShellImpl({
resolvePuzzleErrorMessage,
setIsPuzzleBusy,
setPuzzleError,
setPlatformTab,
setSelectionStage,
returnPlatformHomeAfterMissingWork,
],
);
@@ -12716,7 +12762,9 @@ export function PlatformEntryFlowShellImpl({
match3dFlow.setIsBusy(true);
setMatch3DError(null);
void match3dRuntimeAdapter
void resolveMatch3DRuntimeAdapter(
activeMatch3DRuntimeProfile?.profileId,
)
.restartRun(match3dRun.runId)
.then(({ run }) => {
setMatch3DRun(run);
@@ -12736,14 +12784,18 @@ export function PlatformEntryFlowShellImpl({
if (!runId) {
return Promise.reject(new Error('抓大鹅运行态缺少 runId。'));
}
return match3dRuntimeAdapter.clickItem(runId, payload);
return resolveMatch3DRuntimeAdapter(
activeMatch3DRuntimeProfile?.profileId,
).clickItem(runId, payload);
}}
onTimeExpired={() => {
if (!match3dRun?.runId) {
return;
}
void match3dRuntimeAdapter
void resolveMatch3DRuntimeAdapter(
activeMatch3DRuntimeProfile?.profileId,
)
.finishTimeUp(match3dRun.runId)
.then(({ run }) => {
setMatch3DRun(run);
@@ -13557,8 +13609,11 @@ export function PlatformEntryFlowShellImpl({
const tryOpenMatch3DGalleryEntry = async () => {
const entries =
match3dGalleryEntries.length > 0
? match3dGalleryEntries
: await refreshMatch3DGallery();
? [...match3dGalleryEntries, match3dDemoProfile]
: await refreshMatch3DGallery().then((items) => [
...items,
match3dDemoProfile,
]);
const matchedEntry = entries.find((entry) => {
const detailEntry = mapMatch3DWorkToPublicWorkDetail(entry);
return (
@@ -13764,11 +13819,7 @@ export function PlatformEntryFlowShellImpl({
setPuzzleRuntimeAuthMode('default');
setPuzzleError(null);
setPublicWorkDetailError(null);
setPlatformTab('home');
setSelectionStage('platform');
if (!maybeAlertWorkNotFoundAndReturnHome()) {
pushAppHistoryPath('/');
}
returnPlatformHomeAfterMissingWork();
return;
}
@@ -13797,6 +13848,7 @@ export function PlatformEntryFlowShellImpl({
refreshSquareHoleGallery,
refreshVisualNovelGallery,
squareHoleGalleryEntries,
returnPlatformHomeAfterMissingWork,
selectionStage,
setPlatformTab,
setPuzzleError,
@@ -13978,6 +14030,7 @@ export function PlatformEntryFlowShellImpl({
refreshBigFishGallery,
resolveBigFishErrorMessage,
setBigFishError,
match3dDemoProfile,
],
);
@@ -14978,7 +15031,9 @@ export function PlatformEntryFlowShellImpl({
match3dRun?.runId &&
match3dRun.status === 'running'
) {
void match3dRuntimeAdapter
void resolveMatch3DRuntimeAdapter(
activeMatch3DRuntimeProfile?.profileId,
)
.stopRun(match3dRun.runId)
.catch(() => undefined);
}
@@ -14991,7 +15046,9 @@ export function PlatformEntryFlowShellImpl({
match3dFlow.setIsBusy(true);
setMatch3DError(null);
void match3dRuntimeAdapter
void resolveMatch3DRuntimeAdapter(
activeMatch3DRuntimeProfile?.profileId,
)
.restartRun(match3dRun.runId)
.then(({ run }) => {
setMatch3DRun(run);
@@ -15016,14 +15073,18 @@ export function PlatformEntryFlowShellImpl({
new Error('抓大鹅运行态缺少 runId。'),
);
}
return match3dRuntimeAdapter.clickItem(runId, payload);
return resolveMatch3DRuntimeAdapter(
activeMatch3DRuntimeProfile?.profileId,
).clickItem(runId, payload);
}}
onTimeExpired={() => {
if (!match3dRun?.runId) {
return;
}
void match3dRuntimeAdapter
void resolveMatch3DRuntimeAdapter(
activeMatch3DRuntimeProfile?.profileId,
)
.finishTimeUp(match3dRun.runId)
.then(({ run }) => {
setMatch3DRun(run);