fix: reconcile architecture adjustment merge
This commit is contained in:
@@ -219,6 +219,7 @@ import {
|
|||||||
buildSquareHoleGenerationAnchorEntries,
|
buildSquareHoleGenerationAnchorEntries,
|
||||||
buildWoodenFishGenerationAnchorEntries,
|
buildWoodenFishGenerationAnchorEntries,
|
||||||
createMiniGameDraftGenerationState,
|
createMiniGameDraftGenerationState,
|
||||||
|
type MiniGameDraftGenerationKind,
|
||||||
type MiniGameDraftGenerationState,
|
type MiniGameDraftGenerationState,
|
||||||
resolveMiniGameDraftGenerationStartedAtMs,
|
resolveMiniGameDraftGenerationStartedAtMs,
|
||||||
} from '../../services/miniGameDraftGenerationProgress';
|
} from '../../services/miniGameDraftGenerationProgress';
|
||||||
@@ -234,6 +235,7 @@ import {
|
|||||||
buildSquareHolePublicWorkCode,
|
buildSquareHolePublicWorkCode,
|
||||||
buildVisualNovelPublicWorkCode,
|
buildVisualNovelPublicWorkCode,
|
||||||
buildWoodenFishPublicWorkCode,
|
buildWoodenFishPublicWorkCode,
|
||||||
|
isSamePuzzleClearPublicWorkCode,
|
||||||
isSamePuzzlePublicWorkCode,
|
isSamePuzzlePublicWorkCode,
|
||||||
} from '../../services/publicWorkCode';
|
} from '../../services/publicWorkCode';
|
||||||
import {
|
import {
|
||||||
@@ -373,7 +375,12 @@ import {
|
|||||||
selectAdjacentPlatformRecommendEntry,
|
selectAdjacentPlatformRecommendEntry,
|
||||||
} from '../rpg-entry/rpgEntryPublicGalleryViewModel';
|
} from '../rpg-entry/rpgEntryPublicGalleryViewModel';
|
||||||
import {
|
import {
|
||||||
|
isBigFishGalleryEntry,
|
||||||
isEdutainmentGalleryEntry,
|
isEdutainmentGalleryEntry,
|
||||||
|
isJumpHopGalleryEntry,
|
||||||
|
isPuzzleGalleryEntry,
|
||||||
|
isPuzzleClearGalleryEntry,
|
||||||
|
mapPuzzleClearWorkToPlatformGalleryCard,
|
||||||
mapPuzzleWorkToPlatformGalleryCard,
|
mapPuzzleWorkToPlatformGalleryCard,
|
||||||
type PlatformPublicGalleryCard,
|
type PlatformPublicGalleryCard,
|
||||||
resolvePlatformPublicWorkCode,
|
resolvePlatformPublicWorkCode,
|
||||||
@@ -415,6 +422,7 @@ import {
|
|||||||
buildBigFishCreationUrlState,
|
buildBigFishCreationUrlState,
|
||||||
buildJumpHopCreationUrlState,
|
buildJumpHopCreationUrlState,
|
||||||
buildMatch3DCreationUrlState,
|
buildMatch3DCreationUrlState,
|
||||||
|
buildPuzzleClearCreationUrlState,
|
||||||
buildPuzzleCreationUrlState,
|
buildPuzzleCreationUrlState,
|
||||||
buildPuzzleDraftRuntimeUrlState,
|
buildPuzzleDraftRuntimeUrlState,
|
||||||
buildPuzzlePublishedRuntimeUrlState,
|
buildPuzzlePublishedRuntimeUrlState,
|
||||||
@@ -456,6 +464,7 @@ import {
|
|||||||
buildPendingBigFishWorks,
|
buildPendingBigFishWorks,
|
||||||
buildPendingJumpHopWorks,
|
buildPendingJumpHopWorks,
|
||||||
buildPendingMatch3DWorks,
|
buildPendingMatch3DWorks,
|
||||||
|
buildPendingPuzzleClearWorks,
|
||||||
buildPendingPuzzleWorks,
|
buildPendingPuzzleWorks,
|
||||||
buildPendingSquareHoleWorks,
|
buildPendingSquareHoleWorks,
|
||||||
buildPendingVisualNovelWorks,
|
buildPendingVisualNovelWorks,
|
||||||
@@ -557,6 +566,8 @@ import {
|
|||||||
} from './platformMiniGameDraftPayloadModel';
|
} from './platformMiniGameDraftPayloadModel';
|
||||||
import {
|
import {
|
||||||
buildJumpHopPendingSession,
|
buildJumpHopPendingSession,
|
||||||
|
buildPuzzleClearPendingSession,
|
||||||
|
buildPuzzleClearSessionFromWorkDetail,
|
||||||
buildPuzzleRuntimeWorkFromSession,
|
buildPuzzleRuntimeWorkFromSession,
|
||||||
buildSquareHoleProfileFromSession,
|
buildSquareHoleProfileFromSession,
|
||||||
buildVisualNovelSessionFromWorkDetail,
|
buildVisualNovelSessionFromWorkDetail,
|
||||||
@@ -752,7 +763,7 @@ async function resumePuzzleProfileSaveArchiveRaw(worldKey: string) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS =
|
const RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS: JumpHopRuntimeRequestOptions =
|
||||||
BACKGROUND_AUTH_REQUEST_OPTIONS;
|
BACKGROUND_AUTH_REQUEST_OPTIONS;
|
||||||
const RECOMMEND_PUZZLE_BACKGROUND_AUTH_OPTIONS: JumpHopRuntimeRequestOptions =
|
const RECOMMEND_PUZZLE_BACKGROUND_AUTH_OPTIONS: JumpHopRuntimeRequestOptions =
|
||||||
RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS;
|
RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS;
|
||||||
@@ -778,6 +789,16 @@ function resolveCurrentRecommendRuntimeAuthPlan(
|
|||||||
hasStoredAccessToken: Boolean(getStoredAccessToken()),
|
hasStoredAccessToken: Boolean(getStoredAccessToken()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function shouldUseRecommendRuntimeGuestAuth(authUi: RecommendRuntimeAuthUi) {
|
||||||
|
return (
|
||||||
|
resolveCurrentRecommendRuntimeAuthPlan(authUi, {
|
||||||
|
embedded: true,
|
||||||
|
allowRuntimeGuestAuth: true,
|
||||||
|
}).requestKind === 'runtime-guest'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async function buildRecommendRuntimeOptionsFromAuthPlan(
|
async function buildRecommendRuntimeOptionsFromAuthPlan(
|
||||||
plan: ReturnType<typeof resolvePlatformRecommendRuntimeAuthPlan>,
|
plan: ReturnType<typeof resolvePlatformRecommendRuntimeAuthPlan>,
|
||||||
) {
|
) {
|
||||||
@@ -797,6 +818,28 @@ async function buildRecommendRuntimeAuthOptions(
|
|||||||
resolveCurrentRecommendRuntimeAuthPlan(authUi, { embedded }),
|
resolveCurrentRecommendRuntimeAuthPlan(authUi, { embedded }),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveRecommendEntryShareStage(
|
||||||
|
entry: PlatformPublicGalleryCard,
|
||||||
|
): PublishShareModalPayload['stage'] {
|
||||||
|
if (isBigFishGalleryEntry(entry)) {
|
||||||
|
return 'big-fish-runtime';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPuzzleGalleryEntry(entry)) {
|
||||||
|
return 'puzzle-gallery-detail';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'work-detail';
|
||||||
|
}
|
||||||
|
|
||||||
|
function pushPuzzleResultHistoryEntry(
|
||||||
|
session: PuzzleAgentSessionSnapshot | null,
|
||||||
|
) {
|
||||||
|
pushAppHistoryPath('/creation/puzzle/result');
|
||||||
|
writeCreationUrlState(buildPuzzleCreationUrlState(session));
|
||||||
|
}
|
||||||
|
|
||||||
const PUZZLE_DRAFT_GENERATION_POINT_COST = 2;
|
const PUZZLE_DRAFT_GENERATION_POINT_COST = 2;
|
||||||
const MATCH3D_DRAFT_GENERATION_POINT_COST = 10;
|
const MATCH3D_DRAFT_GENERATION_POINT_COST = 10;
|
||||||
const BARK_BATTLE_DRAFT_GENERATION_POINT_COST = 3;
|
const BARK_BATTLE_DRAFT_GENERATION_POINT_COST = 3;
|
||||||
@@ -2795,6 +2838,7 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
bigFishEntries: bigFishGalleryEntries,
|
bigFishEntries: bigFishGalleryEntries,
|
||||||
match3dEntries: match3dGalleryEntries,
|
match3dEntries: match3dGalleryEntries,
|
||||||
puzzleEntries: puzzleGalleryEntries,
|
puzzleEntries: puzzleGalleryEntries,
|
||||||
|
puzzleClearEntries: puzzleClearGalleryEntries,
|
||||||
barkBattleGalleryEntries,
|
barkBattleGalleryEntries,
|
||||||
barkBattleWorks,
|
barkBattleWorks,
|
||||||
jumpHopEntries: jumpHopGalleryEntries,
|
jumpHopEntries: jumpHopGalleryEntries,
|
||||||
@@ -12358,6 +12402,12 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
{ authMode: intent.authMode },
|
{ authMode: intent.authMode },
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
case 'start-puzzle-clear':
|
||||||
|
setPublicWorkDetailError(null);
|
||||||
|
void startPuzzleClearRunFromProfile(intent.profileId, {
|
||||||
|
returnStage: intent.returnStage,
|
||||||
|
});
|
||||||
|
return;
|
||||||
case 'start-jump-hop':
|
case 'start-jump-hop':
|
||||||
setPublicWorkDetailError(null);
|
setPublicWorkDetailError(null);
|
||||||
void startJumpHopRunFromProfile(intent.profileId, {
|
void startJumpHopRunFromProfile(intent.profileId, {
|
||||||
@@ -12491,6 +12541,8 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
setBigFishError(intent.errorMessage);
|
setBigFishError(intent.errorMessage);
|
||||||
} else if (intent.errorTarget === 'puzzle') {
|
} else if (intent.errorTarget === 'puzzle') {
|
||||||
setPuzzleError(intent.errorMessage);
|
setPuzzleError(intent.errorMessage);
|
||||||
|
} else if (intent.errorTarget === 'puzzle-clear') {
|
||||||
|
setPuzzleClearError(intent.errorMessage);
|
||||||
} else if (intent.errorTarget === 'match3d') {
|
} else if (intent.errorTarget === 'match3d') {
|
||||||
setMatch3DError(intent.errorMessage);
|
setMatch3DError(intent.errorMessage);
|
||||||
} else if (intent.errorTarget === 'square-hole') {
|
} else if (intent.errorTarget === 'square-hole') {
|
||||||
@@ -12514,6 +12566,12 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
{ embedded: intent.embedded },
|
{ embedded: intent.embedded },
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case 'start-puzzle-clear':
|
||||||
|
started = await startPuzzleClearRunFromProfile(intent.profileId, {
|
||||||
|
embedded: intent.embedded,
|
||||||
|
returnStage: intent.returnStage,
|
||||||
|
});
|
||||||
|
break;
|
||||||
case 'start-jump-hop':
|
case 'start-jump-hop':
|
||||||
started = await startJumpHopRunFromProfile(intent.profileId, {
|
started = await startJumpHopRunFromProfile(intent.profileId, {
|
||||||
embedded: intent.embedded,
|
embedded: intent.embedded,
|
||||||
@@ -13092,6 +13150,7 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
hasBigFishRun: Boolean(bigFishRun),
|
hasBigFishRun: Boolean(bigFishRun),
|
||||||
hasJumpHopRun: Boolean(jumpHopRun),
|
hasJumpHopRun: Boolean(jumpHopRun),
|
||||||
hasMatch3DRun: Boolean(match3dRun),
|
hasMatch3DRun: Boolean(match3dRun),
|
||||||
|
hasPuzzleClearRun: Boolean(puzzleClearRun),
|
||||||
hasSquareHoleRun: Boolean(squareHoleRun),
|
hasSquareHoleRun: Boolean(squareHoleRun),
|
||||||
hasVisualNovelRun: Boolean(visualNovelRun),
|
hasVisualNovelRun: Boolean(visualNovelRun),
|
||||||
hasWoodenFishRun: Boolean(woodenFishRun),
|
hasWoodenFishRun: Boolean(woodenFishRun),
|
||||||
@@ -13114,6 +13173,7 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
hasBigFishRun: Boolean(bigFishRun),
|
hasBigFishRun: Boolean(bigFishRun),
|
||||||
hasJumpHopRun: Boolean(jumpHopRun),
|
hasJumpHopRun: Boolean(jumpHopRun),
|
||||||
hasMatch3DRun: Boolean(match3dRun),
|
hasMatch3DRun: Boolean(match3dRun),
|
||||||
|
hasPuzzleClearRun: Boolean(puzzleClearRun),
|
||||||
hasSquareHoleRun: Boolean(squareHoleRun),
|
hasSquareHoleRun: Boolean(squareHoleRun),
|
||||||
hasVisualNovelRun: Boolean(visualNovelRun),
|
hasVisualNovelRun: Boolean(visualNovelRun),
|
||||||
hasWoodenFishRun: Boolean(woodenFishRun),
|
hasWoodenFishRun: Boolean(woodenFishRun),
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import type { BigFishSessionSnapshotResponse } from '../../../packages/shared/sr
|
|||||||
import type { BabyObjectMatchDraft } from '../../../packages/shared/src/contracts/edutainmentBabyObject';
|
import type { BabyObjectMatchDraft } from '../../../packages/shared/src/contracts/edutainmentBabyObject';
|
||||||
import type { Match3DAgentSessionSnapshot } from '../../../packages/shared/src/contracts/match3dAgent';
|
import type { Match3DAgentSessionSnapshot } from '../../../packages/shared/src/contracts/match3dAgent';
|
||||||
import type { PuzzleAgentSessionSnapshot } from '../../../packages/shared/src/contracts/puzzleAgentSession';
|
import type { PuzzleAgentSessionSnapshot } from '../../../packages/shared/src/contracts/puzzleAgentSession';
|
||||||
|
import type {
|
||||||
|
PuzzleClearSessionSnapshotResponse,
|
||||||
|
PuzzleClearWorkProfileResponse,
|
||||||
|
} from '../../../packages/shared/src/contracts/puzzleClear';
|
||||||
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
||||||
import type { SquareHoleSessionSnapshot } from '../../../packages/shared/src/contracts/squareHoleAgent';
|
import type { SquareHoleSessionSnapshot } from '../../../packages/shared/src/contracts/squareHoleAgent';
|
||||||
import type { VisualNovelAgentSessionSnapshot } from '../../../packages/shared/src/contracts/visualNovel';
|
import type { VisualNovelAgentSessionSnapshot } from '../../../packages/shared/src/contracts/visualNovel';
|
||||||
@@ -393,6 +397,21 @@ export function buildJumpHopCreationUrlState(params: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildPuzzleClearCreationUrlState(params: {
|
||||||
|
session?: PuzzleClearSessionSnapshotResponse | null;
|
||||||
|
work?: PuzzleClearWorkProfileResponse | null;
|
||||||
|
}): CreationUrlState {
|
||||||
|
const sessionId = normalizeCreationUrlValue(params.session?.sessionId);
|
||||||
|
const profileId = normalizeCreationUrlValue(
|
||||||
|
params.work?.summary.profileId ?? params.session?.draft?.profileId,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
sessionId,
|
||||||
|
profileId,
|
||||||
|
workId: normalizeCreationUrlValue(params.work?.summary.workId ?? profileId),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function buildWoodenFishCreationUrlState(params: {
|
export function buildWoodenFishCreationUrlState(params: {
|
||||||
session?: WoodenFishSessionSnapshotResponse | null;
|
session?: WoodenFishSessionSnapshotResponse | null;
|
||||||
work?: WoodenFishWorkProfileResponse | null;
|
work?: WoodenFishWorkProfileResponse | null;
|
||||||
|
|||||||
@@ -751,6 +751,7 @@ function buildJumpHopWork(
|
|||||||
profileId: 'jump-hop-profile-base',
|
profileId: 'jump-hop-profile-base',
|
||||||
ownerUserId: 'user-1',
|
ownerUserId: 'user-1',
|
||||||
sourceSessionId: 'jump-hop-session-base',
|
sourceSessionId: 'jump-hop-session-base',
|
||||||
|
themeText: '潮雾港口',
|
||||||
workTitle: '潮雾跳一跳',
|
workTitle: '潮雾跳一跳',
|
||||||
workDescription: '潮雾港口跳一跳。',
|
workDescription: '潮雾港口跳一跳。',
|
||||||
themeTags: [],
|
themeTags: [],
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { CustomWorldWorkSummary } from '../../../packages/shared/src/contra
|
|||||||
import type { BabyObjectMatchDraft } from '../../../packages/shared/src/contracts/edutainmentBabyObject';
|
import type { BabyObjectMatchDraft } from '../../../packages/shared/src/contracts/edutainmentBabyObject';
|
||||||
import type { JumpHopWorkSummaryResponse } from '../../../packages/shared/src/contracts/jumpHop';
|
import type { JumpHopWorkSummaryResponse } from '../../../packages/shared/src/contracts/jumpHop';
|
||||||
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
|
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
|
||||||
|
import type { PuzzleClearWorkSummaryResponse } from '../../../packages/shared/src/contracts/puzzleClear';
|
||||||
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
||||||
import type { SquareHoleWorkSummary } from '../../../packages/shared/src/contracts/squareHoleWorks';
|
import type { SquareHoleWorkSummary } from '../../../packages/shared/src/contracts/squareHoleWorks';
|
||||||
import type { VisualNovelWorkSummary } from '../../../packages/shared/src/contracts/visualNovel';
|
import type { VisualNovelWorkSummary } from '../../../packages/shared/src/contracts/visualNovel';
|
||||||
@@ -1191,6 +1192,7 @@ export function buildPendingJumpHopWorks(
|
|||||||
profileId: `jump-hop-profile-${sessionId}`,
|
profileId: `jump-hop-profile-${sessionId}`,
|
||||||
ownerUserId: '',
|
ownerUserId: '',
|
||||||
sourceSessionId: sessionId,
|
sourceSessionId: sessionId,
|
||||||
|
themeText: state.title ?? '跳一跳草稿',
|
||||||
workTitle: '跳一跳草稿',
|
workTitle: '跳一跳草稿',
|
||||||
workDescription:
|
workDescription:
|
||||||
state.status === 'failed'
|
state.status === 'failed'
|
||||||
@@ -1210,6 +1212,48 @@ export function buildPendingJumpHopWorks(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildPendingPuzzleClearWorks(
|
||||||
|
pending: Record<string, PendingDraftShelfState> | undefined,
|
||||||
|
existingItems: readonly PuzzleClearWorkSummaryResponse[],
|
||||||
|
): PuzzleClearWorkSummaryResponse[] {
|
||||||
|
if (!pending) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.entries(pending)
|
||||||
|
.filter(([sessionId]) =>
|
||||||
|
existingItems.every((item) => item.sourceSessionId !== sessionId),
|
||||||
|
)
|
||||||
|
.map(([sessionId, state]) => {
|
||||||
|
const generationStatus =
|
||||||
|
state.status === 'failed'
|
||||||
|
? 'failed'
|
||||||
|
: state.status === 'generating'
|
||||||
|
? 'generating'
|
||||||
|
: 'ready';
|
||||||
|
return {
|
||||||
|
runtimeKind: 'puzzle-clear',
|
||||||
|
workId: `puzzle-clear-work-${sessionId}`,
|
||||||
|
profileId: sessionId,
|
||||||
|
ownerUserId: '',
|
||||||
|
sourceSessionId: sessionId,
|
||||||
|
workTitle: '拼消消草稿',
|
||||||
|
workDescription:
|
||||||
|
state.status === 'failed'
|
||||||
|
? '拼消消草稿生成失败,可重新打开处理。'
|
||||||
|
: '正在生成拼消消草稿。',
|
||||||
|
themePrompt: '',
|
||||||
|
coverImageSrc: null,
|
||||||
|
publicationStatus: 'draft',
|
||||||
|
playCount: 0,
|
||||||
|
updatedAt: state.updatedAt,
|
||||||
|
publishedAt: null,
|
||||||
|
publishReady: false,
|
||||||
|
generationStatus,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function buildPendingWoodenFishWorks(
|
export function buildPendingWoodenFishWorks(
|
||||||
pending: Record<string, PendingDraftShelfState> | undefined,
|
pending: Record<string, PendingDraftShelfState> | undefined,
|
||||||
existingItems: readonly WoodenFishWorkSummaryResponse[],
|
existingItems: readonly WoodenFishWorkSummaryResponse[],
|
||||||
|
|||||||
@@ -213,6 +213,7 @@ function buildJumpHopDraft(
|
|||||||
templateId: 'jump-hop',
|
templateId: 'jump-hop',
|
||||||
templateName: '跳一跳',
|
templateName: '跳一跳',
|
||||||
profileId: 'jump-hop-profile-1',
|
profileId: 'jump-hop-profile-1',
|
||||||
|
themeText: '草稿主题',
|
||||||
workTitle: '草稿跳一跳',
|
workTitle: '草稿跳一跳',
|
||||||
workDescription: '从草稿恢复。',
|
workDescription: '从草稿恢复。',
|
||||||
themeTags: ['草稿'],
|
themeTags: ['草稿'],
|
||||||
@@ -236,6 +237,7 @@ function buildJumpHopPayload(
|
|||||||
): JumpHopWorkspaceCreateRequest {
|
): JumpHopWorkspaceCreateRequest {
|
||||||
return {
|
return {
|
||||||
templateId: 'jump-hop',
|
templateId: 'jump-hop',
|
||||||
|
themeText: '表单主题',
|
||||||
workTitle: '表单跳一跳',
|
workTitle: '表单跳一跳',
|
||||||
workDescription: '从表单提交。',
|
workDescription: '从表单提交。',
|
||||||
themeTags: ['表单'],
|
themeTags: ['表单'],
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export function buildPuzzleWorkUpdatePayloadFromDraft(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function buildJumpHopDraftActionPayload(
|
export function buildJumpHopDraftActionPayload(
|
||||||
actionType: 'compile-draft' | 'regenerate-character' | 'regenerate-tiles',
|
actionType: 'compile-draft' | 'regenerate-tiles',
|
||||||
input: {
|
input: {
|
||||||
payload?: JumpHopWorkspaceCreateRequest | null;
|
payload?: JumpHopWorkspaceCreateRequest | null;
|
||||||
draft?: JumpHopSessionSnapshotResponse['draft'] | null;
|
draft?: JumpHopSessionSnapshotResponse['draft'] | null;
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ function buildJumpHopSummary(
|
|||||||
profileId: 'jump-hop-profile-1',
|
profileId: 'jump-hop-profile-1',
|
||||||
ownerUserId: 'user-1',
|
ownerUserId: 'user-1',
|
||||||
sourceSessionId: ' jump-hop-session-1 ',
|
sourceSessionId: ' jump-hop-session-1 ',
|
||||||
|
themeText: '云阶机关',
|
||||||
workTitle: '云阶跳跃',
|
workTitle: '云阶跳跃',
|
||||||
workDescription: '越过云阶。',
|
workDescription: '越过云阶。',
|
||||||
themeTags: ['云阶'],
|
themeTags: ['云阶'],
|
||||||
@@ -522,6 +523,7 @@ describe('platformMiniGameSessionMappingModel', () => {
|
|||||||
templateId: 'jump-hop',
|
templateId: 'jump-hop',
|
||||||
templateName: '跳一跳',
|
templateName: '跳一跳',
|
||||||
profileId: 'jump-hop-profile-1',
|
profileId: 'jump-hop-profile-1',
|
||||||
|
themeText: '云阶机关',
|
||||||
workTitle: '云阶跳跃',
|
workTitle: '云阶跳跃',
|
||||||
workDescription: '越过云阶。',
|
workDescription: '越过云阶。',
|
||||||
themeTags: ['云阶'],
|
themeTags: ['云阶'],
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
import type { JumpHopSessionSnapshotResponse, JumpHopWorkSummaryResponse } from '../../../packages/shared/src/contracts/jumpHop';
|
import type {
|
||||||
|
JumpHopSessionSnapshotResponse,
|
||||||
|
JumpHopWorkSummaryResponse,
|
||||||
|
} from '../../../packages/shared/src/contracts/jumpHop';
|
||||||
|
import type {
|
||||||
|
PuzzleClearSessionSnapshotResponse,
|
||||||
|
PuzzleClearWorkProfileResponse,
|
||||||
|
PuzzleClearWorkSummaryResponse,
|
||||||
|
} from '../../../packages/shared/src/contracts/puzzleClear';
|
||||||
import type { PuzzleAgentSessionSnapshot } from '../../../packages/shared/src/contracts/puzzleAgentSession';
|
import type { PuzzleAgentSessionSnapshot } from '../../../packages/shared/src/contracts/puzzleAgentSession';
|
||||||
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
||||||
import type { SquareHoleSessionSnapshot } from '../../../packages/shared/src/contracts/squareHoleAgent';
|
import type { SquareHoleSessionSnapshot } from '../../../packages/shared/src/contracts/squareHoleAgent';
|
||||||
@@ -59,6 +67,54 @@ export function buildPuzzleRuntimeWorkFromSession(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildPuzzleClearSessionFromWorkDetail(
|
||||||
|
work: PuzzleClearWorkProfileResponse,
|
||||||
|
fallbackItem?: PuzzleClearWorkSummaryResponse | null,
|
||||||
|
): PuzzleClearSessionSnapshotResponse {
|
||||||
|
const sessionId =
|
||||||
|
normalizeCreationUrlValue(work.summary.sourceSessionId) ??
|
||||||
|
normalizeCreationUrlValue(fallbackItem?.sourceSessionId) ??
|
||||||
|
work.summary.profileId;
|
||||||
|
return {
|
||||||
|
sessionId,
|
||||||
|
ownerUserId: work.summary.ownerUserId,
|
||||||
|
status: work.summary.generationStatus,
|
||||||
|
draft: work.draft,
|
||||||
|
createdAt: work.summary.updatedAt,
|
||||||
|
updatedAt: work.summary.updatedAt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildPuzzleClearPendingSession(
|
||||||
|
item: PuzzleClearWorkSummaryResponse,
|
||||||
|
): PuzzleClearSessionSnapshotResponse {
|
||||||
|
const sessionId =
|
||||||
|
normalizeCreationUrlValue(item.sourceSessionId) ?? item.profileId;
|
||||||
|
return {
|
||||||
|
sessionId,
|
||||||
|
ownerUserId: item.ownerUserId,
|
||||||
|
status: item.generationStatus,
|
||||||
|
draft: {
|
||||||
|
templateId: 'puzzle-clear',
|
||||||
|
templateName: '拼消消',
|
||||||
|
profileId: item.profileId,
|
||||||
|
workTitle: item.workTitle,
|
||||||
|
workDescription: item.workDescription,
|
||||||
|
themePrompt: item.themePrompt,
|
||||||
|
boardBackgroundPrompt: item.themePrompt,
|
||||||
|
generateBoardBackground: true,
|
||||||
|
boardBackgroundAsset: null,
|
||||||
|
cardBackImageSrc: null,
|
||||||
|
atlasAsset: null,
|
||||||
|
patternGroups: [],
|
||||||
|
cardAssets: [],
|
||||||
|
generationStatus: item.generationStatus,
|
||||||
|
},
|
||||||
|
createdAt: item.updatedAt,
|
||||||
|
updatedAt: item.updatedAt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function buildSquareHoleProfileFromSession(
|
export function buildSquareHoleProfileFromSession(
|
||||||
session: SquareHoleSessionSnapshot | null,
|
session: SquareHoleSessionSnapshot | null,
|
||||||
): SquareHoleWorkProfile | null {
|
): SquareHoleWorkProfile | null {
|
||||||
@@ -122,6 +178,7 @@ export function buildJumpHopPendingSession(
|
|||||||
templateId: 'jump-hop',
|
templateId: 'jump-hop',
|
||||||
templateName: '跳一跳',
|
templateName: '跳一跳',
|
||||||
profileId: item.profileId,
|
profileId: item.profileId,
|
||||||
|
themeText: item.themeText,
|
||||||
workTitle: item.workTitle,
|
workTitle: item.workTitle,
|
||||||
workDescription: item.workDescription,
|
workDescription: item.workDescription,
|
||||||
themeTags: item.themeTags,
|
themeTags: item.themeTags,
|
||||||
|
|||||||
@@ -303,6 +303,7 @@ function buildJumpHopCard(
|
|||||||
profileId,
|
profileId,
|
||||||
ownerUserId: 'user-1',
|
ownerUserId: 'user-1',
|
||||||
authorDisplayName: '测试作者',
|
authorDisplayName: '测试作者',
|
||||||
|
themeText: '潮雾港',
|
||||||
workTitle: '潮雾跳一跳',
|
workTitle: '潮雾跳一跳',
|
||||||
workDescription: '潮雾跳一跳说明。',
|
workDescription: '潮雾跳一跳说明。',
|
||||||
coverImageSrc: null,
|
coverImageSrc: null,
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ function buildJumpHopEntry(
|
|||||||
profileId: 'jump-hop-profile',
|
profileId: 'jump-hop-profile',
|
||||||
ownerUserId: 'user-1',
|
ownerUserId: 'user-1',
|
||||||
authorDisplayName: '玩家',
|
authorDisplayName: '玩家',
|
||||||
|
themeText: '一路向前',
|
||||||
workTitle: '跳一跳',
|
workTitle: '跳一跳',
|
||||||
workDescription: '一路向前。',
|
workDescription: '一路向前。',
|
||||||
coverImageSrc: '/jump-hop-cover.png',
|
coverImageSrc: '/jump-hop-cover.png',
|
||||||
@@ -166,6 +167,13 @@ function buildTypedEntry(
|
|||||||
switch (sourceType) {
|
switch (sourceType) {
|
||||||
case 'puzzle':
|
case 'puzzle':
|
||||||
return { ...common, ...overrides, sourceType };
|
return { ...common, ...overrides, sourceType };
|
||||||
|
case 'puzzle-clear':
|
||||||
|
return {
|
||||||
|
...common,
|
||||||
|
...overrides,
|
||||||
|
sourceType,
|
||||||
|
themePrompt: '拼消消主题',
|
||||||
|
};
|
||||||
case 'big-fish':
|
case 'big-fish':
|
||||||
return { ...common, ...overrides, sourceType };
|
return { ...common, ...overrides, sourceType };
|
||||||
case 'match3d':
|
case 'match3d':
|
||||||
@@ -769,6 +777,7 @@ test('platform public gallery flow builds feeds with visibility gates and bark b
|
|||||||
bigFishEntries: [hiddenBigFish],
|
bigFishEntries: [hiddenBigFish],
|
||||||
match3dEntries: [],
|
match3dEntries: [],
|
||||||
puzzleEntries: [],
|
puzzleEntries: [],
|
||||||
|
puzzleClearEntries: [],
|
||||||
barkBattleGalleryEntries: [],
|
barkBattleGalleryEntries: [],
|
||||||
barkBattleWorks: [draftBarkFallback, publishedBarkFallback],
|
barkBattleWorks: [draftBarkFallback, publishedBarkFallback],
|
||||||
jumpHopEntries: [],
|
jumpHopEntries: [],
|
||||||
@@ -793,6 +802,7 @@ test('platform public gallery flow builds feeds with visibility gates and bark b
|
|||||||
bigFishEntries: [hiddenBigFish],
|
bigFishEntries: [hiddenBigFish],
|
||||||
match3dEntries: [],
|
match3dEntries: [],
|
||||||
puzzleEntries: [],
|
puzzleEntries: [],
|
||||||
|
puzzleClearEntries: [],
|
||||||
barkBattleGalleryEntries: [
|
barkBattleGalleryEntries: [
|
||||||
buildBarkBattleWork({
|
buildBarkBattleWork({
|
||||||
workId: 'gallery-bark',
|
workId: 'gallery-bark',
|
||||||
@@ -828,6 +838,7 @@ test('platform public gallery flow preserves feed tie order and featured slice',
|
|||||||
bigFishEntries: [],
|
bigFishEntries: [],
|
||||||
match3dEntries: [],
|
match3dEntries: [],
|
||||||
puzzleEntries: [],
|
puzzleEntries: [],
|
||||||
|
puzzleClearEntries: [],
|
||||||
barkBattleGalleryEntries: [],
|
barkBattleGalleryEntries: [],
|
||||||
barkBattleWorks: [
|
barkBattleWorks: [
|
||||||
buildBarkBattleWork({
|
buildBarkBattleWork({
|
||||||
@@ -868,6 +879,7 @@ test('platform public gallery flow preserves feed tie order and featured slice',
|
|||||||
bigFishEntries: [],
|
bigFishEntries: [],
|
||||||
match3dEntries: [],
|
match3dEntries: [],
|
||||||
puzzleEntries: [],
|
puzzleEntries: [],
|
||||||
|
puzzleClearEntries: [],
|
||||||
barkBattleGalleryEntries: [],
|
barkBattleGalleryEntries: [],
|
||||||
barkBattleWorks: [],
|
barkBattleWorks: [],
|
||||||
jumpHopEntries: [],
|
jumpHopEntries: [],
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ import type { CustomWorldGalleryCard } from '../../../packages/shared/src/contra
|
|||||||
import type { SquareHoleWorkSummary } from '../../../packages/shared/src/contracts/squareHoleWorks';
|
import type { SquareHoleWorkSummary } from '../../../packages/shared/src/contracts/squareHoleWorks';
|
||||||
import type { VisualNovelWorkSummary } from '../../../packages/shared/src/contracts/visualNovel';
|
import type { VisualNovelWorkSummary } from '../../../packages/shared/src/contracts/visualNovel';
|
||||||
import type { WoodenFishGalleryCardResponse } from '../../../packages/shared/src/contracts/woodenFish';
|
import type { WoodenFishGalleryCardResponse } from '../../../packages/shared/src/contracts/woodenFish';
|
||||||
|
import type { PuzzleClearGalleryCardResponse } from '../../services/puzzle-clear/puzzleClearClient';
|
||||||
import {
|
import {
|
||||||
isBarkBattleGalleryEntry,
|
isBarkBattleGalleryEntry,
|
||||||
isBigFishGalleryEntry,
|
isBigFishGalleryEntry,
|
||||||
isEdutainmentGalleryEntry,
|
isEdutainmentGalleryEntry,
|
||||||
isJumpHopGalleryEntry,
|
isJumpHopGalleryEntry,
|
||||||
isMatch3DGalleryEntry,
|
isMatch3DGalleryEntry,
|
||||||
|
isPuzzleClearGalleryEntry,
|
||||||
isPuzzleGalleryEntry,
|
isPuzzleGalleryEntry,
|
||||||
isSquareHoleGalleryEntry,
|
isSquareHoleGalleryEntry,
|
||||||
isVisualNovelGalleryEntry,
|
isVisualNovelGalleryEntry,
|
||||||
@@ -22,6 +24,7 @@ import {
|
|||||||
mapBarkBattleWorkToPlatformGalleryCard,
|
mapBarkBattleWorkToPlatformGalleryCard,
|
||||||
mapBigFishWorkToPlatformGalleryCard,
|
mapBigFishWorkToPlatformGalleryCard,
|
||||||
mapJumpHopWorkToPlatformGalleryCard,
|
mapJumpHopWorkToPlatformGalleryCard,
|
||||||
|
mapPuzzleClearWorkToPlatformGalleryCard,
|
||||||
mapPuzzleWorkToPlatformGalleryCard,
|
mapPuzzleWorkToPlatformGalleryCard,
|
||||||
mapSquareHoleWorkToPlatformGalleryCard,
|
mapSquareHoleWorkToPlatformGalleryCard,
|
||||||
mapVisualNovelWorkToPlatformGalleryCard,
|
mapVisualNovelWorkToPlatformGalleryCard,
|
||||||
@@ -43,6 +46,7 @@ export type RecommendRuntimeKind =
|
|||||||
| 'jump-hop'
|
| 'jump-hop'
|
||||||
| 'match3d'
|
| 'match3d'
|
||||||
| 'puzzle'
|
| 'puzzle'
|
||||||
|
| 'puzzle-clear'
|
||||||
| 'square-hole'
|
| 'square-hole'
|
||||||
| 'wooden-fish'
|
| 'wooden-fish'
|
||||||
| 'visual-novel'
|
| 'visual-novel'
|
||||||
@@ -53,6 +57,7 @@ export type PlatformRecommendRuntimeStartErrorTarget =
|
|||||||
| 'big-fish'
|
| 'big-fish'
|
||||||
| 'match3d'
|
| 'match3d'
|
||||||
| 'puzzle'
|
| 'puzzle'
|
||||||
|
| 'puzzle-clear'
|
||||||
| 'square-hole';
|
| 'square-hole';
|
||||||
|
|
||||||
export type PlatformRecommendRuntimeStartIntent =
|
export type PlatformRecommendRuntimeStartIntent =
|
||||||
@@ -73,6 +78,12 @@ export type PlatformRecommendRuntimeStartIntent =
|
|||||||
returnStage: 'platform';
|
returnStage: 'platform';
|
||||||
embedded: true;
|
embedded: true;
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: 'start-puzzle-clear';
|
||||||
|
profileId: string;
|
||||||
|
returnStage: 'platform';
|
||||||
|
embedded: true;
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: 'start-jump-hop';
|
type: 'start-jump-hop';
|
||||||
profileId: string;
|
profileId: string;
|
||||||
@@ -133,6 +144,7 @@ export type PlatformRecommendRuntimeReadyState = {
|
|||||||
hasBigFishRun?: boolean;
|
hasBigFishRun?: boolean;
|
||||||
hasJumpHopRun?: boolean;
|
hasJumpHopRun?: boolean;
|
||||||
hasMatch3DRun?: boolean;
|
hasMatch3DRun?: boolean;
|
||||||
|
hasPuzzleClearRun?: boolean;
|
||||||
hasSquareHoleRun?: boolean;
|
hasSquareHoleRun?: boolean;
|
||||||
hasVisualNovelRun?: boolean;
|
hasVisualNovelRun?: boolean;
|
||||||
hasWoodenFishRun?: boolean;
|
hasWoodenFishRun?: boolean;
|
||||||
@@ -161,6 +173,7 @@ export type PlatformPublicGalleryFeedsInput = {
|
|||||||
bigFishEntries: readonly BigFishWorkSummary[];
|
bigFishEntries: readonly BigFishWorkSummary[];
|
||||||
match3dEntries: readonly Match3DWorkSummary[];
|
match3dEntries: readonly Match3DWorkSummary[];
|
||||||
puzzleEntries: readonly PuzzleWorkSummary[];
|
puzzleEntries: readonly PuzzleWorkSummary[];
|
||||||
|
puzzleClearEntries: readonly PuzzleClearGalleryCardResponse[];
|
||||||
barkBattleGalleryEntries: readonly BarkBattleWorkSummary[];
|
barkBattleGalleryEntries: readonly BarkBattleWorkSummary[];
|
||||||
barkBattleWorks: readonly BarkBattleWorkSummary[];
|
barkBattleWorks: readonly BarkBattleWorkSummary[];
|
||||||
jumpHopEntries: readonly JumpHopGalleryCardResponse[];
|
jumpHopEntries: readonly JumpHopGalleryCardResponse[];
|
||||||
@@ -194,21 +207,23 @@ export function getPlatformPublicGalleryEntryKey(
|
|||||||
? 'big-fish'
|
? 'big-fish'
|
||||||
: isPuzzleGalleryEntry(entry)
|
: isPuzzleGalleryEntry(entry)
|
||||||
? 'puzzle'
|
? 'puzzle'
|
||||||
: isJumpHopGalleryEntry(entry)
|
: isPuzzleClearGalleryEntry(entry)
|
||||||
? 'jump-hop'
|
? 'puzzle-clear'
|
||||||
: isWoodenFishGalleryEntry(entry)
|
: isJumpHopGalleryEntry(entry)
|
||||||
? 'wooden-fish'
|
? 'jump-hop'
|
||||||
: isMatch3DGalleryEntry(entry)
|
: isWoodenFishGalleryEntry(entry)
|
||||||
? 'match3d'
|
? 'wooden-fish'
|
||||||
: isSquareHoleGalleryEntry(entry)
|
: isMatch3DGalleryEntry(entry)
|
||||||
? 'square-hole'
|
? 'match3d'
|
||||||
: isVisualNovelGalleryEntry(entry)
|
: isSquareHoleGalleryEntry(entry)
|
||||||
? 'visual-novel'
|
? 'square-hole'
|
||||||
: isBarkBattleGalleryEntry(entry)
|
: isVisualNovelGalleryEntry(entry)
|
||||||
? 'bark-battle'
|
? 'visual-novel'
|
||||||
: isEdutainmentGalleryEntry(entry)
|
: isBarkBattleGalleryEntry(entry)
|
||||||
? `edutainment:${entry.templateId}`
|
? 'bark-battle'
|
||||||
: 'rpg';
|
: isEdutainmentGalleryEntry(entry)
|
||||||
|
? `edutainment:${entry.templateId}`
|
||||||
|
: 'rpg';
|
||||||
return `${kind}:${entry.ownerUserId}:${entry.profileId}`;
|
return `${kind}:${entry.ownerUserId}:${entry.profileId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,6 +238,10 @@ export function getPlatformRecommendRuntimeKind(
|
|||||||
return 'puzzle';
|
return 'puzzle';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPuzzleClearGalleryEntry(entry)) {
|
||||||
|
return 'puzzle-clear';
|
||||||
|
}
|
||||||
|
|
||||||
if (isJumpHopGalleryEntry(entry)) {
|
if (isJumpHopGalleryEntry(entry)) {
|
||||||
return 'jump-hop';
|
return 'jump-hop';
|
||||||
}
|
}
|
||||||
@@ -297,6 +316,15 @@ export function resolvePlatformRecommendRuntimeStartIntent(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPuzzleClearGalleryEntry(entry)) {
|
||||||
|
return {
|
||||||
|
type: 'start-puzzle-clear',
|
||||||
|
profileId: entry.profileId,
|
||||||
|
returnStage: 'platform',
|
||||||
|
embedded: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (isJumpHopGalleryEntry(entry)) {
|
if (isJumpHopGalleryEntry(entry)) {
|
||||||
return {
|
return {
|
||||||
type: 'start-jump-hop',
|
type: 'start-jump-hop',
|
||||||
@@ -423,6 +451,9 @@ export function isPlatformRecommendRuntimeReadyForEntry(
|
|||||||
state.puzzleRunCurrentLevelProfileId === entry.profileId
|
state.puzzleRunCurrentLevelProfileId === entry.profileId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (expectedKind === 'puzzle-clear') {
|
||||||
|
return Boolean(state.hasPuzzleClearRun);
|
||||||
|
}
|
||||||
if (expectedKind === 'square-hole') {
|
if (expectedKind === 'square-hole') {
|
||||||
return Boolean(state.hasSquareHoleRun);
|
return Boolean(state.hasSquareHoleRun);
|
||||||
}
|
}
|
||||||
@@ -527,6 +558,7 @@ export function buildPlatformPublicGalleryFeeds(
|
|||||||
...bigFishEntries,
|
...bigFishEntries,
|
||||||
...input.match3dEntries.map(mapMatch3DWorkToPublicWorkDetail),
|
...input.match3dEntries.map(mapMatch3DWorkToPublicWorkDetail),
|
||||||
...input.puzzleEntries.map(mapPuzzleWorkToPlatformGalleryCard),
|
...input.puzzleEntries.map(mapPuzzleWorkToPlatformGalleryCard),
|
||||||
|
...input.puzzleClearEntries.map(mapPuzzleClearWorkToPlatformGalleryCard),
|
||||||
...barkBattleGalleryEntries,
|
...barkBattleGalleryEntries,
|
||||||
...input.jumpHopEntries.map(mapJumpHopWorkToPlatformGalleryCard),
|
...input.jumpHopEntries.map(mapJumpHopWorkToPlatformGalleryCard),
|
||||||
...barkBattleFallbackEntries,
|
...barkBattleFallbackEntries,
|
||||||
@@ -539,6 +571,7 @@ export function buildPlatformPublicGalleryFeeds(
|
|||||||
...bigFishEntries,
|
...bigFishEntries,
|
||||||
...input.match3dEntries.map(mapMatch3DWorkToPublicWorkDetail),
|
...input.match3dEntries.map(mapMatch3DWorkToPublicWorkDetail),
|
||||||
...input.puzzleEntries.map(mapPuzzleWorkToPlatformGalleryCard),
|
...input.puzzleEntries.map(mapPuzzleWorkToPlatformGalleryCard),
|
||||||
|
...input.puzzleClearEntries.map(mapPuzzleClearWorkToPlatformGalleryCard),
|
||||||
...(barkBattleGalleryEntries.length > 0
|
...(barkBattleGalleryEntries.length > 0
|
||||||
? barkBattleGalleryEntries
|
? barkBattleGalleryEntries
|
||||||
: barkBattleFallbackEntries),
|
: barkBattleFallbackEntries),
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import type { JumpHopGalleryCardResponse } from '../../../packages/shared/src/co
|
|||||||
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
|
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
|
||||||
import type { PuzzleRunSnapshot } from '../../../packages/shared/src/contracts/puzzleRuntimeSession';
|
import type { PuzzleRunSnapshot } from '../../../packages/shared/src/contracts/puzzleRuntimeSession';
|
||||||
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
||||||
|
import type { PuzzleClearGalleryCardResponse } from '../../../packages/shared/src/contracts/puzzleClear';
|
||||||
import type {
|
import type {
|
||||||
CustomWorldGalleryCard,
|
CustomWorldGalleryCard,
|
||||||
CustomWorldLibraryEntry,
|
CustomWorldLibraryEntry,
|
||||||
@@ -25,6 +26,7 @@ import {
|
|||||||
mapBarkBattleWorkToPublicWorkDetail,
|
mapBarkBattleWorkToPublicWorkDetail,
|
||||||
mapBigFishWorkToPublicWorkDetail,
|
mapBigFishWorkToPublicWorkDetail,
|
||||||
mapJumpHopWorkToPublicWorkDetail,
|
mapJumpHopWorkToPublicWorkDetail,
|
||||||
|
mapPuzzleClearWorkToPublicWorkDetail,
|
||||||
mapPublicWorkDetailToBigFishWork,
|
mapPublicWorkDetailToBigFishWork,
|
||||||
mapPublicWorkDetailToPuzzleWork,
|
mapPublicWorkDetailToPuzzleWork,
|
||||||
mapPublicWorkDetailToSquareHoleWork,
|
mapPublicWorkDetailToSquareHoleWork,
|
||||||
@@ -133,6 +135,13 @@ function buildTypedEntry<TSourceType extends PlatformGallerySourceType>(
|
|||||||
...overrides,
|
...overrides,
|
||||||
sourceType,
|
sourceType,
|
||||||
});
|
});
|
||||||
|
case 'puzzle-clear':
|
||||||
|
return narrowTypedEntry<TSourceType>({
|
||||||
|
...common,
|
||||||
|
...overrides,
|
||||||
|
sourceType,
|
||||||
|
themePrompt: '拼消消主题',
|
||||||
|
});
|
||||||
case 'big-fish':
|
case 'big-fish':
|
||||||
return narrowTypedEntry<TSourceType>({
|
return narrowTypedEntry<TSourceType>({
|
||||||
...common,
|
...common,
|
||||||
@@ -324,6 +333,7 @@ function buildJumpHopGalleryCard(
|
|||||||
profileId: 'jump-hop-profile',
|
profileId: 'jump-hop-profile',
|
||||||
ownerUserId: 'user-1',
|
ownerUserId: 'user-1',
|
||||||
authorDisplayName: '玩家',
|
authorDisplayName: '玩家',
|
||||||
|
themeText: '跳一跳',
|
||||||
workTitle: '跳一跳作品',
|
workTitle: '跳一跳作品',
|
||||||
workDescription: '跳一跳摘要',
|
workDescription: '跳一跳摘要',
|
||||||
coverImageSrc: '/jump-hop-cover.png',
|
coverImageSrc: '/jump-hop-cover.png',
|
||||||
@@ -339,6 +349,31 @@ function buildJumpHopGalleryCard(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildPuzzleClearGalleryCard(
|
||||||
|
overrides: Partial<PuzzleClearGalleryCardResponse> = {},
|
||||||
|
): PuzzleClearGalleryCardResponse {
|
||||||
|
return {
|
||||||
|
runtimeKind: 'puzzle-clear',
|
||||||
|
publicWorkCode: 'PCLR-0001',
|
||||||
|
workId: 'puzzle-clear-work',
|
||||||
|
profileId: 'puzzle-clear-profile',
|
||||||
|
ownerUserId: 'user-1',
|
||||||
|
sourceSessionId: 'puzzle-clear-session',
|
||||||
|
authorDisplayName: '玩家',
|
||||||
|
workTitle: '拼消消作品',
|
||||||
|
workDescription: '拼消消摘要',
|
||||||
|
themePrompt: '水果',
|
||||||
|
coverImageSrc: '/puzzle-clear-cover.png',
|
||||||
|
publicationStatus: 'published',
|
||||||
|
playCount: 6,
|
||||||
|
updatedAt: '2026-06-01T01:00:00.000Z',
|
||||||
|
publishedAt: '2026-06-01T00:00:00.000Z',
|
||||||
|
publishReady: true,
|
||||||
|
generationStatus: 'ready',
|
||||||
|
...overrides,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function buildWoodenFishGalleryCard(
|
function buildWoodenFishGalleryCard(
|
||||||
overrides: Partial<WoodenFishGalleryCardResponse> = {},
|
overrides: Partial<WoodenFishGalleryCardResponse> = {},
|
||||||
): WoodenFishGalleryCardResponse {
|
): WoodenFishGalleryCardResponse {
|
||||||
@@ -448,6 +483,7 @@ test('platform public work detail flow resolves detail kind for every play kind'
|
|||||||
> = [
|
> = [
|
||||||
['big-fish', 'big-fish'],
|
['big-fish', 'big-fish'],
|
||||||
['puzzle', 'puzzle'],
|
['puzzle', 'puzzle'],
|
||||||
|
['puzzle-clear', 'puzzle-clear'],
|
||||||
['jump-hop', 'jump-hop'],
|
['jump-hop', 'jump-hop'],
|
||||||
['wooden-fish', 'wooden-fish'],
|
['wooden-fish', 'wooden-fish'],
|
||||||
['match3d', 'match3d'],
|
['match3d', 'match3d'],
|
||||||
@@ -509,6 +545,13 @@ test('platform public work detail flow resolves open strategy', () => {
|
|||||||
kind: 'edutainment',
|
kind: 'edutainment',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
buildTypedEntry('puzzle-clear'),
|
||||||
|
{
|
||||||
|
type: 'use-entry',
|
||||||
|
kind: 'puzzle-clear',
|
||||||
|
},
|
||||||
|
],
|
||||||
[
|
[
|
||||||
buildTypedEntry('puzzle'),
|
buildTypedEntry('puzzle'),
|
||||||
{
|
{
|
||||||
@@ -595,6 +638,14 @@ test('platform public work detail flow maps work summaries to detail entries', (
|
|||||||
profileId: 'jump-hop-profile',
|
profileId: 'jump-hop-profile',
|
||||||
publicWorkCode: 'JH-0001',
|
publicWorkCode: 'JH-0001',
|
||||||
});
|
});
|
||||||
|
expect(
|
||||||
|
mapPuzzleClearWorkToPublicWorkDetail(buildPuzzleClearGalleryCard()),
|
||||||
|
).toMatchObject({
|
||||||
|
sourceType: 'puzzle-clear',
|
||||||
|
workId: 'puzzle-clear-work',
|
||||||
|
profileId: 'puzzle-clear-profile',
|
||||||
|
publicWorkCode: 'PCLR-0001',
|
||||||
|
});
|
||||||
expect(
|
expect(
|
||||||
mapWoodenFishWorkToPublicWorkDetail(buildWoodenFishGalleryCard()),
|
mapWoodenFishWorkToPublicWorkDetail(buildWoodenFishGalleryCard()),
|
||||||
).toMatchObject({
|
).toMatchObject({
|
||||||
@@ -773,6 +824,12 @@ test('platform public work detail flow resolves like intent', () => {
|
|||||||
type: 'like-puzzle',
|
type: 'like-puzzle',
|
||||||
profileId: 'puzzle-profile',
|
profileId: 'puzzle-profile',
|
||||||
});
|
});
|
||||||
|
expect(
|
||||||
|
resolvePlatformPublicWorkLikeIntent(buildTypedEntry('puzzle-clear')),
|
||||||
|
).toEqual({
|
||||||
|
type: 'unsupported',
|
||||||
|
errorMessage: '拼消消点赞将在后续版本开放。',
|
||||||
|
});
|
||||||
expect(resolvePlatformPublicWorkLikeIntent(buildRpgEntry())).toEqual({
|
expect(resolvePlatformPublicWorkLikeIntent(buildRpgEntry())).toEqual({
|
||||||
type: 'like-rpg-gallery',
|
type: 'like-rpg-gallery',
|
||||||
ownerUserId: 'user-1',
|
ownerUserId: 'user-1',
|
||||||
@@ -826,6 +883,12 @@ test('platform public work detail flow resolves remix intent', () => {
|
|||||||
profileId: 'puzzle-profile',
|
profileId: 'puzzle-profile',
|
||||||
selectionStage: 'puzzle-result',
|
selectionStage: 'puzzle-result',
|
||||||
});
|
});
|
||||||
|
expect(
|
||||||
|
resolvePlatformPublicWorkRemixIntent(buildTypedEntry('puzzle-clear')),
|
||||||
|
).toEqual({
|
||||||
|
type: 'unsupported',
|
||||||
|
errorMessage: '拼消消作品改造将在后续版本开放。',
|
||||||
|
});
|
||||||
expect(resolvePlatformPublicWorkRemixIntent(buildRpgEntry())).toEqual({
|
expect(resolvePlatformPublicWorkRemixIntent(buildRpgEntry())).toEqual({
|
||||||
type: 'remix-rpg-gallery',
|
type: 'remix-rpg-gallery',
|
||||||
ownerUserId: 'user-1',
|
ownerUserId: 'user-1',
|
||||||
@@ -1038,6 +1101,15 @@ test('platform public work detail flow resolves edit intent for unsupported and
|
|||||||
type: 'blocked',
|
type: 'blocked',
|
||||||
errorMessage: '这份跳一跳作品暂时请从作品架编辑。',
|
errorMessage: '这份跳一跳作品暂时请从作品架编辑。',
|
||||||
});
|
});
|
||||||
|
expect(
|
||||||
|
resolvePlatformPublicWorkEditIntent(
|
||||||
|
buildTypedEntry('puzzle-clear'),
|
||||||
|
buildEditIntentDeps(),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
type: 'blocked',
|
||||||
|
errorMessage: '这份拼消消作品暂时请从作品架编辑。',
|
||||||
|
});
|
||||||
expect(
|
expect(
|
||||||
resolvePlatformPublicWorkEditIntent(
|
resolvePlatformPublicWorkEditIntent(
|
||||||
buildTypedEntry('wooden-fish'),
|
buildTypedEntry('wooden-fish'),
|
||||||
@@ -1126,6 +1198,16 @@ test('platform public work detail flow resolves start intent for direct launches
|
|||||||
profileId: 'jump-hop-profile',
|
profileId: 'jump-hop-profile',
|
||||||
returnStage: 'work-detail',
|
returnStage: 'work-detail',
|
||||||
});
|
});
|
||||||
|
expect(
|
||||||
|
resolvePlatformPublicWorkStartIntent(
|
||||||
|
buildTypedEntry('puzzle-clear'),
|
||||||
|
buildStartIntentDeps(),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
type: 'start-puzzle-clear',
|
||||||
|
profileId: 'puzzle-clear-profile',
|
||||||
|
returnStage: 'work-detail',
|
||||||
|
});
|
||||||
expect(
|
expect(
|
||||||
resolvePlatformPublicWorkStartIntent(
|
resolvePlatformPublicWorkStartIntent(
|
||||||
buildTypedEntry('wooden-fish'),
|
buildTypedEntry('wooden-fish'),
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ import type {
|
|||||||
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
|
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
|
||||||
import type { PuzzleRunSnapshot } from '../../../packages/shared/src/contracts/puzzleRuntimeSession';
|
import type { PuzzleRunSnapshot } from '../../../packages/shared/src/contracts/puzzleRuntimeSession';
|
||||||
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
||||||
|
import type {
|
||||||
|
PuzzleClearGalleryCardResponse,
|
||||||
|
PuzzleClearWorkProfileResponse,
|
||||||
|
} from '../../../packages/shared/src/contracts/puzzleClear';
|
||||||
import type {
|
import type {
|
||||||
CustomWorldGalleryCard,
|
CustomWorldGalleryCard,
|
||||||
CustomWorldLibraryEntry,
|
CustomWorldLibraryEntry,
|
||||||
@@ -25,6 +29,7 @@ import {
|
|||||||
isEdutainmentGalleryEntry,
|
isEdutainmentGalleryEntry,
|
||||||
isJumpHopGalleryEntry,
|
isJumpHopGalleryEntry,
|
||||||
isMatch3DGalleryEntry,
|
isMatch3DGalleryEntry,
|
||||||
|
isPuzzleClearGalleryEntry,
|
||||||
isPuzzleGalleryEntry,
|
isPuzzleGalleryEntry,
|
||||||
isSquareHoleGalleryEntry,
|
isSquareHoleGalleryEntry,
|
||||||
isVisualNovelGalleryEntry,
|
isVisualNovelGalleryEntry,
|
||||||
@@ -32,6 +37,7 @@ import {
|
|||||||
mapBarkBattleWorkToPlatformGalleryCard,
|
mapBarkBattleWorkToPlatformGalleryCard,
|
||||||
mapBigFishWorkToPlatformGalleryCard,
|
mapBigFishWorkToPlatformGalleryCard,
|
||||||
mapJumpHopWorkToPlatformGalleryCard,
|
mapJumpHopWorkToPlatformGalleryCard,
|
||||||
|
mapPuzzleClearWorkToPlatformGalleryCard,
|
||||||
mapPuzzleWorkToPlatformGalleryCard,
|
mapPuzzleWorkToPlatformGalleryCard,
|
||||||
mapSquareHoleWorkToPlatformGalleryCard,
|
mapSquareHoleWorkToPlatformGalleryCard,
|
||||||
mapVisualNovelWorkToPlatformGalleryCard,
|
mapVisualNovelWorkToPlatformGalleryCard,
|
||||||
@@ -50,6 +56,7 @@ export type PlatformPublicWorkDetailKind =
|
|||||||
| 'jump-hop'
|
| 'jump-hop'
|
||||||
| 'match3d'
|
| 'match3d'
|
||||||
| 'puzzle'
|
| 'puzzle'
|
||||||
|
| 'puzzle-clear'
|
||||||
| 'rpg'
|
| 'rpg'
|
||||||
| 'square-hole'
|
| 'square-hole'
|
||||||
| 'visual-novel'
|
| 'visual-novel'
|
||||||
@@ -199,6 +206,11 @@ export type PlatformPublicWorkStartIntent =
|
|||||||
returnStage: 'work-detail';
|
returnStage: 'work-detail';
|
||||||
authMode: 'isolated';
|
authMode: 'isolated';
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: 'start-puzzle-clear';
|
||||||
|
profileId: string;
|
||||||
|
returnStage: 'work-detail';
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: 'start-jump-hop';
|
type: 'start-jump-hop';
|
||||||
profileId: string;
|
profileId: string;
|
||||||
@@ -325,6 +337,12 @@ export function mapJumpHopWorkToPublicWorkDetail(
|
|||||||
return mapJumpHopWorkToPlatformGalleryCard(item);
|
return mapJumpHopWorkToPlatformGalleryCard(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function mapPuzzleClearWorkToPublicWorkDetail(
|
||||||
|
item: PuzzleClearGalleryCardResponse | PuzzleClearWorkProfileResponse,
|
||||||
|
): PlatformPublicGalleryCard {
|
||||||
|
return mapPuzzleClearWorkToPlatformGalleryCard(item);
|
||||||
|
}
|
||||||
|
|
||||||
export function mapBarkBattleWorkToPublicWorkDetail(
|
export function mapBarkBattleWorkToPublicWorkDetail(
|
||||||
item: BarkBattleWorkSummary,
|
item: BarkBattleWorkSummary,
|
||||||
): PlatformPublicGalleryCard {
|
): PlatformPublicGalleryCard {
|
||||||
@@ -512,6 +530,10 @@ export function getPlatformPublicWorkDetailKind(
|
|||||||
return 'puzzle';
|
return 'puzzle';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPuzzleClearGalleryEntry(entry)) {
|
||||||
|
return 'puzzle-clear';
|
||||||
|
}
|
||||||
|
|
||||||
if (isJumpHopGalleryEntry(entry)) {
|
if (isJumpHopGalleryEntry(entry)) {
|
||||||
return 'jump-hop';
|
return 'jump-hop';
|
||||||
}
|
}
|
||||||
@@ -560,6 +582,13 @@ export function resolvePlatformPublicWorkDetailOpenStrategy(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPuzzleClearGalleryEntry(entry)) {
|
||||||
|
return {
|
||||||
|
type: 'use-entry',
|
||||||
|
kind: 'puzzle-clear',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (isJumpHopGalleryEntry(entry)) {
|
if (isJumpHopGalleryEntry(entry)) {
|
||||||
return {
|
return {
|
||||||
type: 'load-jump-hop-detail',
|
type: 'load-jump-hop-detail',
|
||||||
@@ -653,6 +682,13 @@ export function resolvePlatformPublicWorkLikeIntent(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPuzzleClearGalleryEntry(entry)) {
|
||||||
|
return {
|
||||||
|
type: 'unsupported',
|
||||||
|
errorMessage: '拼消消点赞将在后续版本开放。',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (isBarkBattleGalleryEntry(entry)) {
|
if (isBarkBattleGalleryEntry(entry)) {
|
||||||
return {
|
return {
|
||||||
type: 'unsupported',
|
type: 'unsupported',
|
||||||
@@ -700,6 +736,13 @@ export function resolvePlatformPublicWorkRemixIntent(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPuzzleClearGalleryEntry(entry)) {
|
||||||
|
return {
|
||||||
|
type: 'unsupported',
|
||||||
|
errorMessage: '拼消消作品改造将在后续版本开放。',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (isMatch3DGalleryEntry(entry)) {
|
if (isMatch3DGalleryEntry(entry)) {
|
||||||
return {
|
return {
|
||||||
type: 'unsupported',
|
type: 'unsupported',
|
||||||
@@ -833,6 +876,13 @@ export function resolvePlatformPublicWorkEditIntent(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPuzzleClearGalleryEntry(entry)) {
|
||||||
|
return {
|
||||||
|
type: 'blocked',
|
||||||
|
errorMessage: '这份拼消消作品暂时请从作品架编辑。',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (isWoodenFishGalleryEntry(entry)) {
|
if (isWoodenFishGalleryEntry(entry)) {
|
||||||
return {
|
return {
|
||||||
type: 'blocked',
|
type: 'blocked',
|
||||||
@@ -944,6 +994,14 @@ export function resolvePlatformPublicWorkStartIntent(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPuzzleClearGalleryEntry(entry)) {
|
||||||
|
return {
|
||||||
|
type: 'start-puzzle-clear',
|
||||||
|
profileId: entry.profileId,
|
||||||
|
returnStage: 'work-detail',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (isJumpHopGalleryEntry(entry)) {
|
if (isJumpHopGalleryEntry(entry)) {
|
||||||
return {
|
return {
|
||||||
type: 'start-jump-hop',
|
type: 'start-jump-hop',
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ const PROTECTED_DATA_LOSS_STABLE_STAGE_BY_STAGE = {
|
|||||||
'puzzle-result': false,
|
'puzzle-result': false,
|
||||||
'puzzle-gallery-detail': true,
|
'puzzle-gallery-detail': true,
|
||||||
'puzzle-runtime': false,
|
'puzzle-runtime': false,
|
||||||
|
'puzzle-clear-workspace': true,
|
||||||
|
'puzzle-clear-generating': false,
|
||||||
|
'puzzle-clear-result': false,
|
||||||
|
'puzzle-clear-runtime': false,
|
||||||
'custom-world-generating': false,
|
'custom-world-generating': false,
|
||||||
'custom-world-result': false,
|
'custom-world-result': false,
|
||||||
} as const satisfies Record<SelectionStage, boolean>;
|
} as const satisfies Record<SelectionStage, boolean>;
|
||||||
|
|||||||
@@ -358,6 +358,7 @@ const {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('../../services/apiClient', () => ({
|
vi.mock('../../services/apiClient', () => ({
|
||||||
|
BACKGROUND_AUTH_REQUEST_OPTIONS: {},
|
||||||
refreshStoredAccessToken: mockRefreshStoredAccessToken,
|
refreshStoredAccessToken: mockRefreshStoredAccessToken,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -2670,7 +2671,7 @@ test('profile total play time card always uses hours', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const playTimeCard = screen.getByRole('button', {
|
const playTimeCard = screen.getByRole('button', {
|
||||||
name: /累计游玩/u,
|
name: /累计游戏时长/u,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(within(playTimeCard).getByText('1.5小时')).toBeTruthy();
|
expect(within(playTimeCard).getByText('1.5小时')).toBeTruthy();
|
||||||
@@ -2684,11 +2685,11 @@ test('profile played works card shows count unit', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const playedCard = screen.getByRole('button', {
|
const playedCard = screen.getByRole('button', {
|
||||||
name: /已玩游戏\s*1个/u,
|
name: /已玩游戏数量\s*1个/u,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(within(playedCard).getByText('1个')).toBeTruthy();
|
expect(within(playedCard).getByText('1个')).toBeTruthy();
|
||||||
expect(within(playedCard).queryByText('已玩游戏数量')).toBeNull();
|
expect(within(playedCard).getByText('已玩游戏数量')).toBeTruthy();
|
||||||
await screen.findByText('1 / 1');
|
await screen.findByText('1 / 1');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2700,8 +2701,12 @@ test('profile stats cards are centered without update timestamp', async () => {
|
|||||||
const walletCard = screen.getByRole('button', {
|
const walletCard = screen.getByRole('button', {
|
||||||
name: /泥点余额\s*0/u,
|
name: /泥点余额\s*0/u,
|
||||||
});
|
});
|
||||||
const playTimeCard = screen.getByRole('button', { name: /累计游玩\s*0小时/u });
|
const playTimeCard = screen.getByRole('button', {
|
||||||
const playedCard = screen.getByRole('button', { name: /已玩游戏\s*0个/u });
|
name: /累计游戏时长\s*0小时/u,
|
||||||
|
});
|
||||||
|
const playedCard = screen.getByRole('button', {
|
||||||
|
name: /已玩游戏数量\s*0个/u,
|
||||||
|
});
|
||||||
|
|
||||||
for (const card of [walletCard, playTimeCard, playedCard]) {
|
for (const card of [walletCard, playTimeCard, playedCard]) {
|
||||||
expect(card.className).toContain('platform-profile-stat-card');
|
expect(card.className).toContain('platform-profile-stat-card');
|
||||||
@@ -2753,8 +2758,8 @@ test('mobile profile page matches the reference layout sections', async () => {
|
|||||||
expect(statPanel.className).toContain('platform-profile-stats-panel');
|
expect(statPanel.className).toContain('platform-profile-stats-panel');
|
||||||
expect(statPanel.querySelector('.platform-profile-stats-grid')).toBeTruthy();
|
expect(statPanel.querySelector('.platform-profile-stats-grid')).toBeTruthy();
|
||||||
expect(within(statPanel).getByRole('button', { name: /泥点余额\s*70/u })).toBeTruthy();
|
expect(within(statPanel).getByRole('button', { name: /泥点余额\s*70/u })).toBeTruthy();
|
||||||
expect(within(statPanel).getByRole('button', { name: /累计游玩\s*0小时/u })).toBeTruthy();
|
expect(within(statPanel).getByRole('button', { name: /累计游戏时长\s*0小时/u })).toBeTruthy();
|
||||||
expect(within(statPanel).getByRole('button', { name: /已玩游戏\s*0个/u })).toBeTruthy();
|
expect(within(statPanel).getByRole('button', { name: /已玩游戏数量\s*0个/u })).toBeTruthy();
|
||||||
expect(
|
expect(
|
||||||
within(statPanel).getByRole('button', { name: /泥点余额\s*70/u }).className,
|
within(statPanel).getByRole('button', { name: /泥点余额\s*70/u }).className,
|
||||||
).toContain('platform-profile-stat-card');
|
).toContain('platform-profile-stat-card');
|
||||||
|
|||||||
@@ -326,6 +326,15 @@ const WECHAT_PAY_CONFIRM_RETRY_DELAYS_MS = [800, 1600, 3000] as const;
|
|||||||
const WECHAT_NATIVE_PAY_QR_IMAGE_SIZE = 180;
|
const WECHAT_NATIVE_PAY_QR_IMAGE_SIZE = 180;
|
||||||
const PROFILE_QR_SCAN_INTERVAL_MS = 360;
|
const PROFILE_QR_SCAN_INTERVAL_MS = 360;
|
||||||
|
|
||||||
|
function getDelayUntilNextProfileTaskReset(nowMs = Date.now()) {
|
||||||
|
const shiftedNow = nowMs + PROFILE_TASK_BEIJING_OFFSET_MS;
|
||||||
|
const nextDayStart =
|
||||||
|
Math.floor(shiftedNow / PROFILE_TASK_DAY_MS) * PROFILE_TASK_DAY_MS +
|
||||||
|
PROFILE_TASK_DAY_MS;
|
||||||
|
const nextResetAt = nextDayStart - PROFILE_TASK_BEIJING_OFFSET_MS;
|
||||||
|
return Math.max(PROFILE_TASK_MIN_RESET_DELAY_MS, nextResetAt - nowMs);
|
||||||
|
}
|
||||||
|
|
||||||
type ProfileReferralPanel = 'invite' | 'redeem' | 'community';
|
type ProfileReferralPanel = 'invite' | 'redeem' | 'community';
|
||||||
type ProfilePopupPanel = ProfileReferralPanel | 'saveArchives';
|
type ProfilePopupPanel = ProfileReferralPanel | 'saveArchives';
|
||||||
type BarcodeDetectorLike = {
|
type BarcodeDetectorLike = {
|
||||||
|
|||||||
@@ -1018,6 +1018,9 @@ export function describePlatformPublicWorkKind(
|
|||||||
if (isPuzzleGalleryEntry(entry)) {
|
if (isPuzzleGalleryEntry(entry)) {
|
||||||
return formatPlatformWorkDisplayTag('拼图');
|
return formatPlatformWorkDisplayTag('拼图');
|
||||||
}
|
}
|
||||||
|
if (isPuzzleClearGalleryEntry(entry)) {
|
||||||
|
return formatPlatformWorkDisplayTag('拼消消');
|
||||||
|
}
|
||||||
if (isMatch3DGalleryEntry(entry)) {
|
if (isMatch3DGalleryEntry(entry)) {
|
||||||
return formatPlatformWorkDisplayTag('抓大鹅');
|
return formatPlatformWorkDisplayTag('抓大鹅');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ describe('jumpHopClient runtime requests', () => {
|
|||||||
it('submits jump input with a generated client event id', async () => {
|
it('submits jump input with a generated client event id', async () => {
|
||||||
await submitJumpHopJump(
|
await submitJumpHopJump(
|
||||||
'run/1',
|
'run/1',
|
||||||
{ chargeMs: 320 },
|
{ dragDistance: 320 },
|
||||||
{ runtimeGuestToken: 'runtime-guest-token' },
|
{ runtimeGuestToken: 'runtime-guest-token' },
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ describe('jumpHopClient runtime requests', () => {
|
|||||||
Authorization: 'Bearer runtime-guest-token',
|
Authorization: 'Bearer runtime-guest-token',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
chargeMs: 320,
|
dragDistance: 320,
|
||||||
clientEventId: 'jump-run/1-1780000000000',
|
clientEventId: 'jump-run/1-1780000000000',
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type {
|
|||||||
JumpHopGalleryCardResponse,
|
JumpHopGalleryCardResponse,
|
||||||
JumpHopGalleryDetailResponse,
|
JumpHopGalleryDetailResponse,
|
||||||
JumpHopGalleryResponse,
|
JumpHopGalleryResponse,
|
||||||
|
JumpHopJumpRequest,
|
||||||
JumpHopLeaderboardResponse,
|
JumpHopLeaderboardResponse,
|
||||||
JumpHopRunResponse,
|
JumpHopRunResponse,
|
||||||
JumpHopRuntimeRunSnapshotResponse,
|
JumpHopRuntimeRunSnapshotResponse,
|
||||||
@@ -22,7 +23,11 @@ import {
|
|||||||
requestJson,
|
requestJson,
|
||||||
} from '../apiClient';
|
} from '../apiClient';
|
||||||
import { createCreationAgentClient } from '../creation-agent';
|
import { createCreationAgentClient } from '../creation-agent';
|
||||||
import { type RuntimeGuestRequestOptions } from '../runtimeGuestAuth';
|
import {
|
||||||
|
buildRuntimeGuestAuthOptions,
|
||||||
|
buildRuntimeGuestHeaders,
|
||||||
|
type RuntimeGuestRequestOptions,
|
||||||
|
} from '../runtimeGuestAuth';
|
||||||
import { buildRuntimeApiPath, requestRuntimeJson } from '../runtimeRequest';
|
import { buildRuntimeApiPath, requestRuntimeJson } from '../runtimeRequest';
|
||||||
|
|
||||||
const JUMP_HOP_API_BASE = '/api/creation/jump-hop/sessions';
|
const JUMP_HOP_API_BASE = '/api/creation/jump-hop/sessions';
|
||||||
@@ -40,11 +45,10 @@ type JumpHopRuntimeMode = 'draft' | 'published';
|
|||||||
type JumpHopStartRunOptions = JumpHopRuntimeRequestOptions & {
|
type JumpHopStartRunOptions = JumpHopRuntimeRequestOptions & {
|
||||||
runtimeMode?: JumpHopRuntimeMode;
|
runtimeMode?: JumpHopRuntimeMode;
|
||||||
};
|
};
|
||||||
type JumpHopJumpPayload = {
|
type JumpHopJumpPayload = Pick<
|
||||||
dragDistance: number;
|
JumpHopJumpRequest,
|
||||||
dragVectorX?: number;
|
'dragDistance' | 'dragVectorX' | 'dragVectorY'
|
||||||
dragVectorY?: number;
|
>;
|
||||||
};
|
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
JumpHopActionRequest,
|
JumpHopActionRequest,
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ import {
|
|||||||
buildCustomWorldPublicWorkCode,
|
buildCustomWorldPublicWorkCode,
|
||||||
buildJumpHopPublicWorkCode,
|
buildJumpHopPublicWorkCode,
|
||||||
buildMatch3DPublicWorkCode,
|
buildMatch3DPublicWorkCode,
|
||||||
|
buildPuzzleClearPublicWorkCode,
|
||||||
buildWoodenFishPublicWorkCode,
|
buildWoodenFishPublicWorkCode,
|
||||||
isSameCustomWorldPublicWorkCode,
|
isSameCustomWorldPublicWorkCode,
|
||||||
isSameJumpHopPublicWorkCode,
|
isSameJumpHopPublicWorkCode,
|
||||||
isSameMatch3DPublicWorkCode,
|
isSameMatch3DPublicWorkCode,
|
||||||
|
isSamePuzzleClearPublicWorkCode,
|
||||||
isSameWoodenFishPublicWorkCode,
|
isSameWoodenFishPublicWorkCode,
|
||||||
} from './publicWorkCode';
|
} from './publicWorkCode';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user