Update Match3D/image-generation docs & code
Adds/updates documentation, assets and implementation for Match3D and puzzle image generation workflows. Key changes: decision logs and pitfalls updated to prefer VectorEngine Gemini for Match3D material sheets and to require edits (multipart) for 1:1 container reference images; guidance added for when to use APIMart vs VectorEngine. .env.example clarified APIMart/Responses config. Many new public assets and PPT visuals added. Code changes across frontend and backend: updated shared contracts, server-rs match3d/puzzle/image-generation handlers, VectorEngine/OpenAI image generation clients, and multiple React components/tests to handle UI/background/container image signing, edits workflow, and puzzle UI background resolution. Added src/services/puzzle-runtime/puzzleUiBackgroundSource.ts and related test updates. Includes notes about multipart HTTP/1.1 requirement and test/verification commands in docs.
This commit is contained in:
@@ -56,10 +56,10 @@ const testEntryConfig = {
|
||||
id: 'visual-novel',
|
||||
title: '视觉小说',
|
||||
subtitle: '分支叙事体验',
|
||||
badge: '可创建',
|
||||
badge: '敬请期待',
|
||||
imageSrc: '/creation-type-references/visual-novel.webp',
|
||||
visible: true,
|
||||
open: true,
|
||||
visible: false,
|
||||
open: false,
|
||||
sortOrder: 60,
|
||||
updatedAtMicros: 1,
|
||||
},
|
||||
@@ -217,9 +217,11 @@ test('creation hub marks generating and newly completed drafts', () => {
|
||||
|
||||
expect(html).toContain('生成中');
|
||||
expect(html).toContain('aria-label="新生成完成"');
|
||||
expect(html).toContain('生成中...');
|
||||
expect(html).toContain('creation-work-card__spinner');
|
||||
});
|
||||
|
||||
test('creation hub published work spans full mobile row', () => {
|
||||
test('creation hub published work uses unified list card layout', () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<CustomWorldCreationHub
|
||||
items={[]}
|
||||
@@ -253,9 +255,10 @@ test('creation hub published work spans full mobile row', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(html).toContain('grid-cols-2');
|
||||
expect(html).toContain('col-span-2 sm:col-span-1');
|
||||
expect(html).not.toContain('grid-cols-1 gap-3 md:grid-cols-2');
|
||||
expect(html).toContain('creation-work-list');
|
||||
expect(html).toContain('platform-category-game-item');
|
||||
expect(html).toContain('creation-work-card__side-cover');
|
||||
expect(html).not.toContain('col-span-2 sm:col-span-1');
|
||||
});
|
||||
|
||||
test('creation hub draft cards use cover background and hide updated time', () => {
|
||||
@@ -318,9 +321,109 @@ test('creation hub draft cards use cover background and hide updated time', () =
|
||||
expect(html).toContain(
|
||||
'class="absolute inset-0 h-full w-full object-cover" src="/covers/new-draft.webp"',
|
||||
);
|
||||
expect(html).toContain('creation-work-card__side-cover');
|
||||
expect(html).toContain('src="/covers/new-draft.webp"');
|
||||
expect(html).toContain(
|
||||
'--creation-work-card-cover-fallback:url(/creation-type-references/puzzle.webp)',
|
||||
);
|
||||
expect(html).not.toContain('1778457601.234567Z');
|
||||
expect(html).not.toContain('2026-05-07');
|
||||
expect(html).not.toContain('更新于');
|
||||
expect(html).not.toContain('最后修改');
|
||||
});
|
||||
|
||||
test('creation hub draft cards fall back to creation type cover when cover is missing', () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<CustomWorldCreationHub
|
||||
mode="works-only"
|
||||
items={[]}
|
||||
puzzleItems={[
|
||||
{
|
||||
workId: 'puzzle:no-cover-draft',
|
||||
profileId: 'puzzle-profile-no-cover',
|
||||
ownerUserId: 'user-1',
|
||||
authorDisplayName: '测试作者',
|
||||
workTitle: '缺少封面的拼图草稿',
|
||||
workDescription: '没有生成封面时也需要保留图像背景。',
|
||||
levelName: '缺少封面的拼图草稿',
|
||||
summary: '没有生成封面时也需要保留图像背景。',
|
||||
themeTags: [],
|
||||
coverImageSrc: null,
|
||||
publicationStatus: 'draft',
|
||||
updatedAt: '2026-05-07T00:00:00.000Z',
|
||||
publishedAt: null,
|
||||
publishReady: false,
|
||||
},
|
||||
]}
|
||||
loading={false}
|
||||
error={null}
|
||||
onRetry={() => {}}
|
||||
onCreateType={noopCreateType}
|
||||
onOpenDraft={() => {}}
|
||||
onEnterPublished={() => {}}
|
||||
entryConfig={testEntryConfig}
|
||||
creationTypes={testCreationTypes}
|
||||
onOpenPuzzleDetail={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(html).toContain('缺少封面的拼图草稿');
|
||||
expect(html).toContain(
|
||||
'class="absolute inset-0 h-full w-full object-cover" src="/creation-type-references/puzzle.webp"',
|
||||
);
|
||||
expect(html).toContain(
|
||||
'--creation-work-card-cover-fallback:url(/creation-type-references/puzzle.webp)',
|
||||
);
|
||||
expect(html).not.toContain('>封面</div>');
|
||||
});
|
||||
|
||||
test('creation hub published card keeps publish info without fixed action text', () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<CustomWorldCreationHub
|
||||
mode="works-only"
|
||||
items={[]}
|
||||
puzzleItems={[
|
||||
{
|
||||
workId: 'puzzle:published-card',
|
||||
profileId: 'puzzle-profile-published',
|
||||
ownerUserId: 'user-1',
|
||||
authorDisplayName: '测试作者',
|
||||
workTitle: '统一卡片作品',
|
||||
workDescription: '作品卡仍要保留原有的积分与统计信息。',
|
||||
levelName: '统一卡片作品',
|
||||
summary: '作品卡仍要保留原有的积分与统计信息。',
|
||||
themeTags: ['潮雾'],
|
||||
coverImageSrc: '/covers/unified-card.webp',
|
||||
publicationStatus: 'published',
|
||||
updatedAt: '2026-05-07T00:00:00.000Z',
|
||||
publishedAt: '2026-05-07T00:00:00.000Z',
|
||||
playCount: 88,
|
||||
remixCount: 9,
|
||||
likeCount: 6,
|
||||
publishReady: true,
|
||||
pointIncentiveTotalPoints: 4,
|
||||
pointIncentiveClaimablePoints: 1,
|
||||
},
|
||||
]}
|
||||
loading={false}
|
||||
error={null}
|
||||
onRetry={() => {}}
|
||||
onCreateType={noopCreateType}
|
||||
onOpenDraft={() => {}}
|
||||
onEnterPublished={() => {}}
|
||||
entryConfig={testEntryConfig}
|
||||
creationTypes={testCreationTypes}
|
||||
onOpenPuzzleDetail={() => {}}
|
||||
onClaimPuzzlePointIncentive={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(html).toContain('积分激励');
|
||||
expect(html).toContain('待领取');
|
||||
expect(html).toContain('游玩');
|
||||
expect(html).toContain('改造');
|
||||
expect(html).toContain('点赞');
|
||||
expect(html).toContain('creation-work-card__side-cover');
|
||||
expect(html).not.toContain('creation-work-card__action');
|
||||
expect(html).not.toContain('>查看详情<');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user