This commit is contained in:
2026-05-09 17:15:23 +08:00
parent 80a4183b45
commit a0ed128bde
43 changed files with 2573 additions and 381 deletions

View File

@@ -319,6 +319,7 @@ type PuzzleRuntimeReturnStage =
| 'puzzle-gallery-detail'
| 'work-detail'
| 'platform';
type PuzzleRuntimeAuthMode = 'default' | 'isolated';
type PuzzleOnboardingPhase = 'input' | 'generating' | 'generated';
@@ -387,6 +388,8 @@ const RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS = {
notifyAuthStateChange: false,
clearAuthOnUnauthorized: false,
};
const PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS =
RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS;
function getPlatformPublicGalleryEntryTime(entry: PlatformPublicGalleryCard) {
const rawTime = entry.publishedAt ?? entry.updatedAt;
@@ -1568,6 +1571,8 @@ export function PlatformEntryFlowShellImpl({
useState<PuzzleDetailReturnTarget | null>(null);
const [puzzleRuntimeReturnStage, setPuzzleRuntimeReturnStage] =
useState<PuzzleRuntimeReturnStage>('puzzle-gallery-detail');
const [puzzleRuntimeAuthMode, setPuzzleRuntimeAuthMode] =
useState<PuzzleRuntimeAuthMode>('default');
const [isPuzzleLeaderboardBusy, setIsPuzzleLeaderboardBusy] = useState(false);
const submittedPuzzleLeaderboardKeysRef = useRef(new Set<string>());
const [puzzleRun, setPuzzleRun] = useState<PuzzleRunSnapshot | null>(null);
@@ -2230,6 +2235,7 @@ export function PlatformEntryFlowShellImpl({
setPuzzleWorks((current) => [response.item, ...current]);
setSelectedPuzzleDetail(null);
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
setPuzzleOnboardingDraft(null);
setPuzzleOnboardingPrompt('');
setPuzzleOnboardingPhase('input');
@@ -2268,10 +2274,11 @@ export function PlatformEntryFlowShellImpl({
setPuzzleOnboardingPhase('input');
setPuzzleOnboardingError(null);
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
setSelectedPuzzleDetail(null);
platformBootstrap.setPlatformTab('home');
platformBootstrap.setPlatformTab(authUi?.user ? 'home' : 'category');
setSelectionStage('platform');
}, [platformBootstrap, setSelectionStage]);
}, [authUi?.user, platformBootstrap, setSelectionStage]);
useEffect(() => {
if (
@@ -2321,6 +2328,7 @@ export function PlatformEntryFlowShellImpl({
markPuzzleOnboardingSeen();
window.setTimeout(() => {
setPuzzleRun(startLocalPuzzleRun(item));
setPuzzleRuntimeAuthMode('default');
setPuzzleRuntimeReturnStage('platform');
setSelectionStage('puzzle-runtime');
}, PUZZLE_ONBOARDING_GENERATED_DELAY_MS);
@@ -2953,6 +2961,7 @@ export function PlatformEntryFlowShellImpl({
const openPuzzleAgentWorkspace = useCallback(async () => {
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
setPuzzleOperation(null);
setPuzzleGenerationState(null);
setPuzzleFormDraftPayload(null);
@@ -2997,6 +3006,7 @@ export function PlatformEntryFlowShellImpl({
}
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
setPuzzleOperation(null);
setPuzzleGenerationState(null);
setPuzzleFormDraftPayload(null);
@@ -3137,6 +3147,7 @@ export function PlatformEntryFlowShellImpl({
setSelectedPuzzleDetail(null);
setPuzzleRuntimeReturnStage('puzzle-gallery-detail');
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
setPuzzleGenerationState(null);
setIsPuzzleNextLevelGenerating(false);
setPuzzleShelfError(null);
@@ -3283,6 +3294,7 @@ export function PlatformEntryFlowShellImpl({
const leavePuzzleFlow = useCallback(() => {
setPuzzleOperation(null);
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
setPuzzleGenerationState(null);
setIsPuzzleNextLevelGenerating(false);
setActiveCreativeAgentSessionId(null);
@@ -3773,6 +3785,7 @@ export function PlatformEntryFlowShellImpl({
puzzleFlow.setSession(response.session);
setPuzzleOperation(null);
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
enterCreateTab();
setActiveCreativeAgentSessionId(creativeAgentSession.sessionId);
setCreativeDraftEditError(null);
@@ -4007,7 +4020,7 @@ export function PlatformEntryFlowShellImpl({
detailItem?: PuzzleWorkSummary,
mirrorErrorToPublicDetail = false,
levelId?: string | null,
options: { embedded?: boolean } = {},
options: { embedded?: boolean; authMode?: PuzzleRuntimeAuthMode } = {},
) => {
if (isPuzzleBusy) {
return false;
@@ -4023,14 +4036,19 @@ export function PlatformEntryFlowShellImpl({
profileId: item.profileId,
levelId: levelId ?? null,
};
const { run } = options.embedded
? await startPuzzleRun(
startRunPayload,
RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS,
)
: await startPuzzleRun(startRunPayload);
const authMode = options.embedded
? 'isolated'
: (options.authMode ?? 'default');
const { run } =
authMode === 'isolated'
? await startPuzzleRun(
startRunPayload,
PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS,
)
: await startPuzzleRun(startRunPayload);
setSelectedPuzzleDetail(item);
setPuzzleRun(run);
setPuzzleRuntimeAuthMode(authMode);
setPuzzleRuntimeReturnStage(returnStage);
if (!options.embedded) {
setSelectionStage('puzzle-runtime');
@@ -4255,6 +4273,7 @@ export function PlatformEntryFlowShellImpl({
const run = startLocalPuzzleRun(item);
setSelectedPuzzleDetail(item);
setPuzzleRun(run);
setPuzzleRuntimeAuthMode('default');
setPuzzleRuntimeReturnStage('puzzle-result');
setSelectionStage('puzzle-runtime');
} catch (error) {
@@ -4496,10 +4515,17 @@ export function PlatformEntryFlowShellImpl({
: await getPuzzleGalleryDetail(currentLevel.profileId).then(
(response) => response.item,
);
const { run } = await startPuzzleRun({
const startRunPayload = {
profileId: currentLevel.profileId,
levelId: resolvePuzzleRestartLevelId(currentRun, detailItem),
});
};
const { run } =
puzzleRuntimeAuthMode === 'isolated'
? await startPuzzleRun(
startRunPayload,
PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS,
)
: await startPuzzleRun(startRunPayload);
setSelectedPuzzleDetail(detailItem);
puzzleRunRef.current = run;
setPuzzleRun(run);
@@ -4513,6 +4539,7 @@ export function PlatformEntryFlowShellImpl({
}, [
isPuzzleBusy,
puzzleRun,
puzzleRuntimeAuthMode,
resolvePuzzleErrorMessage,
selectedPuzzleDetail,
setIsPuzzleBusy,
@@ -4618,7 +4645,16 @@ export function PlatformEntryFlowShellImpl({
return;
}
void submitPuzzleLeaderboard(puzzleRun.runId, payload)
const submitLeaderboardPromise =
puzzleRuntimeAuthMode === 'isolated'
? submitPuzzleLeaderboard(
puzzleRun.runId,
payload,
PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS,
)
: submitPuzzleLeaderboard(puzzleRun.runId, payload);
void submitLeaderboardPromise
.then(({ run }) => {
setPuzzleRun((currentRun) => {
if (!currentRun) {
@@ -4641,6 +4677,7 @@ export function PlatformEntryFlowShellImpl({
authUi?.user?.displayName,
platformBootstrap,
puzzleRun,
puzzleRuntimeAuthMode,
resolvePuzzleErrorMessage,
setPuzzleError,
]);
@@ -4678,10 +4715,20 @@ export function PlatformEntryFlowShellImpl({
: getPuzzleGalleryDetail(targetProfileId).then(
(response) => response.item,
);
const advancePromise =
puzzleRuntimeAuthMode === 'isolated'
? advancePuzzleNextLevel(
puzzleRun.runId,
{
targetProfileId,
},
PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS,
)
: advancePuzzleNextLevel(puzzleRun.runId, {
targetProfileId,
});
const [{ run }, item] = await Promise.all([
advancePuzzleNextLevel(puzzleRun.runId, {
targetProfileId,
}),
advancePromise,
itemPromise,
]);
setSelectedPuzzleDetail(item);
@@ -4695,7 +4742,14 @@ export function PlatformEntryFlowShellImpl({
return;
}
const { run } = await advancePuzzleNextLevel(puzzleRun.runId);
const { run } =
puzzleRuntimeAuthMode === 'isolated'
? await advancePuzzleNextLevel(
puzzleRun.runId,
{},
PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS,
)
: await advancePuzzleNextLevel(puzzleRun.runId);
setPuzzleRun(run);
} catch (error) {
setPuzzleError(resolvePuzzleErrorMessage(error, '准备下一关失败。'));
@@ -4708,6 +4762,7 @@ export function PlatformEntryFlowShellImpl({
isPuzzleBusy,
isPuzzleLeaderboardBusy,
puzzleRun,
puzzleRuntimeAuthMode,
resolvePuzzleErrorMessage,
selectedPuzzleDetail,
setIsPuzzleBusy,
@@ -4732,6 +4787,7 @@ export function PlatformEntryFlowShellImpl({
puzzleFlow.setSession(response.session);
setPuzzleOperation(null);
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
enterCreateTab();
setSelectionStage('puzzle-result');
})
@@ -4777,6 +4833,7 @@ export function PlatformEntryFlowShellImpl({
: currentRun;
puzzleRunRef.current = null;
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
setActiveRecommendRuntimeKind(null);
if (closedRun.currentLevel) {
@@ -5596,34 +5653,36 @@ export function PlatformEntryFlowShellImpl({
const openRecommendGalleryDetail = useCallback(
(entry: PlatformPublicGalleryCard) => {
if (isBigFishGalleryEntry(entry)) {
openPublicWorkDetail(entry);
return;
}
runProtectedAction(() => {
if (isBigFishGalleryEntry(entry)) {
openPublicWorkDetail(entry);
return;
}
if (isPuzzleGalleryEntry(entry)) {
void openPuzzlePublicWorkDetail(entry.profileId, {
tab: platformBootstrap.platformTab,
});
return;
}
if (isPuzzleGalleryEntry(entry)) {
void openPuzzlePublicWorkDetail(entry.profileId, {
tab: platformBootstrap.platformTab,
});
return;
}
if (isMatch3DGalleryEntry(entry)) {
openPublicWorkDetail(entry);
return;
}
if (isMatch3DGalleryEntry(entry)) {
openPublicWorkDetail(entry);
return;
}
if (isSquareHoleGalleryEntry(entry)) {
openPublicWorkDetail(entry);
return;
}
if (isSquareHoleGalleryEntry(entry)) {
openPublicWorkDetail(entry);
return;
}
if (isVisualNovelGalleryEntry(entry)) {
void openVisualNovelPublicWorkDetail(entry.profileId);
return;
}
if (isVisualNovelGalleryEntry(entry)) {
void openVisualNovelPublicWorkDetail(entry.profileId);
return;
}
void openRpgPublicWorkDetail(entry);
void openRpgPublicWorkDetail(entry);
});
},
[
openPuzzlePublicWorkDetail,
@@ -5631,6 +5690,7 @@ export function PlatformEntryFlowShellImpl({
openRpgPublicWorkDetail,
openVisualNovelPublicWorkDetail,
platformBootstrap.platformTab,
runProtectedAction,
],
);
const openPuzzleDetail = useCallback(
@@ -5673,6 +5733,7 @@ export function PlatformEntryFlowShellImpl({
async (item: PuzzleWorkSummary) => {
setPuzzleOperation(null);
setPuzzleRun(null);
setPuzzleRuntimeAuthMode('default');
setSelectedPuzzleDetail(null);
if (!item.sourceSessionId?.trim()) {
if (item.publicationStatus === 'published') {
@@ -5960,6 +6021,8 @@ export function PlatformEntryFlowShellImpl({
'work-detail',
work,
true,
null,
{ authMode: 'isolated' },
);
return;
}
@@ -6462,6 +6525,7 @@ export function PlatformEntryFlowShellImpl({
if (
selectionStage !== 'platform' ||
platformBootstrap.platformTab !== 'home' ||
!platformBootstrap.isAuthenticated ||
!platformBootstrap.canReadProtectedData ||
platformBootstrap.isLoadingPlatform
) {
@@ -6494,6 +6558,7 @@ export function PlatformEntryFlowShellImpl({
isStartingRecommendEntry,
platformBootstrap.canReadProtectedData,
platformBootstrap.isLoadingPlatform,
platformBootstrap.isAuthenticated,
platformBootstrap.platformTab,
recommendRuntimeEntries,
selectRecommendRuntimeEntry,
@@ -8594,6 +8659,9 @@ export function PlatformEntryFlowShellImpl({
selectedPuzzleDetail.profileId,
'puzzle-gallery-detail',
selectedPuzzleDetail,
false,
null,
{ authMode: 'isolated' },
);
}}
/>