This commit is contained in:
2026-04-27 22:50:18 +08:00
parent ded6f6ee2a
commit b6c6640548
77 changed files with 5240 additions and 833 deletions

View File

@@ -28,7 +28,10 @@ import type {
PuzzleAgentSessionSnapshot,
SendPuzzleAgentMessageRequest,
} from '../../../packages/shared/src/contracts/puzzleAgentSession';
import type { PuzzleRunSnapshot } from '../../../packages/shared/src/contracts/puzzleRuntimeSession';
import type {
PuzzleRunSnapshot,
SubmitPuzzleLeaderboardRequest,
} from '../../../packages/shared/src/contracts/puzzleRuntimeSession';
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
import type {
CustomWorldGalleryCard,
@@ -80,7 +83,10 @@ import {
getPuzzleGalleryDetail,
listPuzzleGallery,
} from '../../services/puzzle-gallery';
import { advanceLocalPuzzleNextLevel } from '../../services/puzzle-runtime';
import {
advanceLocalPuzzleNextLevel,
submitPuzzleLeaderboard,
} from '../../services/puzzle-runtime';
import {
dragLocalPuzzlePiece,
startLocalPuzzleRun,
@@ -428,6 +434,8 @@ export function PlatformEntryFlowShellImpl({
useState<PuzzleDetailReturnTarget | null>(null);
const [puzzleRuntimeReturnStage, setPuzzleRuntimeReturnStage] =
useState<PuzzleRuntimeReturnStage>('puzzle-gallery-detail');
const [isPuzzleLeaderboardBusy, setIsPuzzleLeaderboardBusy] = useState(false);
const submittedPuzzleLeaderboardKeysRef = useRef(new Set<string>());
const [puzzleRun, setPuzzleRun] = useState<PuzzleRunSnapshot | null>(null);
const [isPuzzleLoadingLibrary, setIsPuzzleLoadingLibrary] = useState(false);
const [puzzleGenerationState, setPuzzleGenerationState] =
@@ -1285,6 +1293,50 @@ export function PlatformEntryFlowShellImpl({
[isPuzzleBusy, puzzleRun],
);
useEffect(() => {
const currentLevel = puzzleRun?.currentLevel ?? null;
if (!puzzleRun || !currentLevel || currentLevel.status !== 'cleared') {
return;
}
if (currentLevel.elapsedMs === null) {
return;
}
if ((currentLevel.leaderboardEntries ?? []).length > 0) {
return;
}
const submitKey = `${puzzleRun.runId}:${currentLevel.profileId}:${currentLevel.gridSize}:${currentLevel.elapsedMs}`;
if (submittedPuzzleLeaderboardKeysRef.current.has(submitKey)) {
return;
}
submittedPuzzleLeaderboardKeysRef.current.add(submitKey);
setIsPuzzleLeaderboardBusy(true);
const payload: SubmitPuzzleLeaderboardRequest = {
profileId: currentLevel.profileId,
gridSize: currentLevel.gridSize,
elapsedMs: currentLevel.elapsedMs,
nickname: authUi?.user?.displayName?.trim() || '玩家',
};
void submitPuzzleLeaderboard(puzzleRun.runId, payload)
.then(({ run }) => {
setPuzzleRun(run);
})
.catch((error) => {
submittedPuzzleLeaderboardKeysRef.current.delete(submitKey);
setPuzzleError(resolvePuzzleErrorMessage(error, '提交拼图排行榜失败。'));
})
.finally(() => {
setIsPuzzleLeaderboardBusy(false);
});
}, [
authUi?.user?.displayName,
puzzleRun,
resolvePuzzleErrorMessage,
setPuzzleError,
]);
const advancePuzzleLevel = useCallback(async () => {
if (!puzzleRun || isPuzzleBusy) {
return;
@@ -2467,13 +2519,17 @@ export function PlatformEntryFlowShellImpl({
<Suspense
fallback={<LazyPanelFallback label="正在加载拼图玩法..." />}
>
<PuzzleRuntimeShell
run={puzzleRun}
isBusy={isPuzzleBusy || isPuzzleNextLevelGenerating}
error={puzzleError}
onBack={() => {
setSelectionStage(puzzleRuntimeReturnStage);
}}
<PuzzleRuntimeShell
run={puzzleRun}
isBusy={
isPuzzleBusy ||
isPuzzleNextLevelGenerating ||
isPuzzleLeaderboardBusy
}
error={puzzleError}
onBack={() => {
setSelectionStage(puzzleRuntimeReturnStage);
}}
onSwapPieces={(payload) => {
void swapPuzzlePiecesInRun(payload);
}}