feat: add puzzle clear template runtime

This commit is contained in:
2026-06-03 22:11:46 +08:00
parent 6e74cf5add
commit 1b5e098225
148 changed files with 19588 additions and 241 deletions

View File

@@ -3,6 +3,7 @@ import type { BigFishWorkSummary } from '../../../packages/shared/src/contracts/
import type { CustomWorldWorkSummary } from '../../../packages/shared/src/contracts/customWorldAgent';
import type { BabyObjectMatchDraft } from '../../../packages/shared/src/contracts/edutainmentBabyObject';
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 { CustomWorldLibraryEntry } from '../../../packages/shared/src/contracts/runtime';
import type { SquareHoleWorkSummary } from '../../../packages/shared/src/contracts/squareHoleWorks';
@@ -17,6 +18,7 @@ import {
buildBigFishPublicWorkCode,
buildJumpHopPublicWorkCode,
buildMatch3DPublicWorkCode,
buildPuzzleClearPublicWorkCode,
buildPuzzlePublicWorkCode,
buildSquareHolePublicWorkCode,
buildVisualNovelPublicWorkCode,
@@ -37,6 +39,7 @@ export type CreationWorkShelfKind =
| 'square-hole'
| 'jump-hop'
| 'wooden-fish'
| 'puzzle-clear'
| 'puzzle'
| 'baby-object-match'
| 'bark-battle'
@@ -97,6 +100,10 @@ export type CreationWorkShelfSource =
kind: 'wooden-fish';
item: WoodenFishWorkSummaryResponse;
}
| {
kind: 'puzzle-clear';
item: PuzzleClearWorkSummaryResponse;
}
| {
kind: 'puzzle';
item: PuzzleWorkSummary;
@@ -153,6 +160,7 @@ export function buildCreationWorkShelfItems(params: {
squareHoleItems?: SquareHoleWorkSummary[];
jumpHopItems?: JumpHopWorkSummaryResponse[];
woodenFishItems?: WoodenFishWorkSummaryResponse[];
puzzleClearItems?: PuzzleClearWorkSummaryResponse[];
puzzleItems: PuzzleWorkSummary[];
babyObjectMatchItems?: BabyObjectMatchDraft[];
barkBattleItems?: BarkBattleWorkSummary[];
@@ -163,6 +171,7 @@ export function buildCreationWorkShelfItems(params: {
canDeleteSquareHole?: boolean;
canDeleteJumpHop?: boolean;
canDeleteWoodenFish?: boolean;
canDeletePuzzleClear?: boolean;
canDeletePuzzle?: boolean;
canDeleteBabyObjectMatch?: boolean;
canDeleteBarkBattle?: boolean;
@@ -180,6 +189,8 @@ export function buildCreationWorkShelfItems(params: {
onDeleteJumpHop?: (item: JumpHopWorkSummaryResponse) => void;
onOpenWoodenFishDetail?: (item: WoodenFishWorkSummaryResponse) => void;
onDeleteWoodenFish?: (item: WoodenFishWorkSummaryResponse) => void;
onOpenPuzzleClearDetail?: (item: PuzzleClearWorkSummaryResponse) => void;
onDeletePuzzleClear?: (item: PuzzleClearWorkSummaryResponse) => void;
onOpenPuzzleDetail?: (item: PuzzleWorkSummary) => void;
onDeletePuzzle?: (item: PuzzleWorkSummary) => void;
onClaimPuzzlePointIncentive?: (item: PuzzleWorkSummary) => void;
@@ -201,6 +212,7 @@ export function buildCreationWorkShelfItems(params: {
squareHoleItems = [],
jumpHopItems = [],
woodenFishItems = [],
puzzleClearItems = [],
puzzleItems,
babyObjectMatchItems = [],
barkBattleItems = [],
@@ -211,6 +223,7 @@ export function buildCreationWorkShelfItems(params: {
canDeleteSquareHole = false,
canDeleteJumpHop = false,
canDeleteWoodenFish = false,
canDeletePuzzleClear = false,
canDeletePuzzle = false,
canDeleteBabyObjectMatch = false,
canDeleteBarkBattle = false,
@@ -228,6 +241,8 @@ export function buildCreationWorkShelfItems(params: {
onDeleteJumpHop,
onOpenWoodenFishDetail,
onDeleteWoodenFish,
onOpenPuzzleClearDetail,
onDeletePuzzleClear,
onOpenPuzzleDetail,
onDeletePuzzle,
onClaimPuzzlePointIncentive,
@@ -278,6 +293,12 @@ export function buildCreationWorkShelfItems(params: {
onDelete: onDeleteWoodenFish,
}),
),
...puzzleClearItems.map((item) =>
mapPuzzleClearWorkToShelfItem(item, canDeletePuzzleClear, {
onOpen: onOpenPuzzleClearDetail,
onDelete: onDeletePuzzleClear,
}),
),
...puzzleItems.map((item) =>
mapPuzzleWorkToShelfItem(item, canDeletePuzzle, {
onOpen: onOpenPuzzleDetail,
@@ -884,6 +905,56 @@ function mapWoodenFishWorkToShelfItem(
};
}
function mapPuzzleClearWorkToShelfItem(
item: PuzzleClearWorkSummaryResponse,
canDelete: boolean,
adapter: WorkShelfAdapter<PuzzleClearWorkSummaryResponse>,
): CreationWorkShelfItem {
const status = item.publicationStatus === 'published' ? 'published' : 'draft';
const publicWorkCode =
status === 'published'
? buildPuzzleClearPublicWorkCode(item.profileId)
: null;
const title = item.workTitle.trim() || '拼消消';
const summary =
item.workDescription.trim() || (status === 'draft' ? '未填写作品描述' : '');
return {
id: item.workId,
kind: 'puzzle-clear',
status,
title,
summary,
authorDisplayName: resolveAuthorDisplayName(item),
updatedAt: item.updatedAt,
coverImageSrc: normalizeCoverImageSrc(item.coverImageSrc),
coverRenderMode: 'image',
coverCharacterImageSrcs: [],
publicWorkCode,
sharePath:
publicWorkCode && status === 'published'
? buildPublicWorkStagePath('work-detail', publicWorkCode)
: null,
openActionLabel: status === 'published' ? '查看详情' : '继续创作',
canDelete,
canShare: status === 'published' && Boolean(publicWorkCode),
badges: [
buildStatusBadge(status),
{ id: 'type', label: '拼消消', tone: 'neutral' },
],
metrics:
status === 'published'
? buildPublishedMetrics({
playCount: item.playCount,
remixCount: 0,
likeCount: 0,
})
: [],
actions: buildWorkShelfActions(item, adapter),
source: { kind: 'puzzle-clear', item },
};
}
function resolveAuthorDisplayName(
...sources: Array<unknown>
@@ -1097,6 +1168,8 @@ function isPersistedCreationWorkGenerating(item: CreationWorkShelfItem) {
return isPersistedPuzzleDraftGenerating(item.source.item);
case 'wooden-fish':
return item.source.item.generationStatus === 'generating';
case 'puzzle-clear':
return item.source.item.generationStatus === 'generating';
case 'bark-battle':
return isPersistedBarkBattleDraftGenerating(item.source.item);
default: