feat: unify creation entry templates
This commit is contained in:
@@ -43,9 +43,7 @@ describe('UnifiedCreationPage', () => {
|
||||
]);
|
||||
expect(fields[2]?.getAttribute('data-field-kind')).toBe('audio');
|
||||
expect(fields[3]?.getAttribute('data-required')).toBe('true');
|
||||
expect(screen.getByTestId('unified-creation-play-badge').textContent).toBe(
|
||||
'wooden-fish',
|
||||
);
|
||||
expect(screen.queryByTestId('unified-creation-play-badge')).toBeNull();
|
||||
fireEvent.click(screen.getByRole('button', { name: '返回' }));
|
||||
expect(onBack).toHaveBeenCalledTimes(1);
|
||||
expect(screen.queryByLabelText('创作字段')).toBeNull();
|
||||
|
||||
@@ -26,7 +26,7 @@ export function UnifiedCreationPage({
|
||||
data-result-stage={spec.resultStage}
|
||||
>
|
||||
<header className="unified-creation-page__header shrink-0 pb-3">
|
||||
<div className="mb-2 flex items-center justify-between gap-3">
|
||||
<div className="mb-2 flex items-center gap-3">
|
||||
{onBack ? (
|
||||
<button
|
||||
type="button"
|
||||
@@ -42,12 +42,6 @@ export function UnifiedCreationPage({
|
||||
) : (
|
||||
<span aria-hidden="true" className="min-h-8 w-0 shrink-0" />
|
||||
)}
|
||||
<span
|
||||
className="unified-creation-page__play-badge shrink-0 rounded-full border border-[var(--platform-subpanel-border)] bg-white/80 px-3 py-1 text-[11px] font-black text-[var(--platform-text-soft)]"
|
||||
data-testid="unified-creation-play-badge"
|
||||
>
|
||||
{spec.playId}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<h1 className="m-0 min-w-0 truncate text-[1.35rem] font-black leading-tight tracking-normal text-[var(--platform-text-strong)] sm:text-[1.65rem]">
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { CustomWorldGenerationProgress } from '../../../packages/shared/src/contracts/runtime';
|
||||
import type { CustomWorldStructuredAnchorEntry } from '../../services/customWorldAgentGenerationProgress';
|
||||
import { CustomWorldGenerationView } from '../CustomWorldGenerationView';
|
||||
import type { UnifiedCreationPlayId } from './unifiedCreationSpecs';
|
||||
import { getUnifiedGenerationCopy } from './unifiedGenerationCopy';
|
||||
import type { UnifiedGenerationPlayId } from './unifiedGenerationCopy';
|
||||
|
||||
type UnifiedGenerationPageProps = {
|
||||
playId: UnifiedCreationPlayId;
|
||||
playId: UnifiedGenerationPlayId;
|
||||
settingText: string;
|
||||
anchorEntries?: CustomWorldStructuredAnchorEntry[];
|
||||
progress: CustomWorldGenerationProgress | null;
|
||||
|
||||
@@ -6,9 +6,21 @@ import {
|
||||
} from './unifiedCreationSpecs';
|
||||
|
||||
describe('unified creation specs', () => {
|
||||
test('统一壳当前覆盖拼图、抓大鹅、跳一跳和敲木鱼', () => {
|
||||
test('统一壳覆盖所有已有创作模板工作台', () => {
|
||||
expect(listUnifiedCreationSpecs().map((spec) => spec.playId).sort()).toEqual(
|
||||
['jump-hop', 'match3d', 'puzzle', 'wooden-fish'],
|
||||
[
|
||||
'baby-object-match',
|
||||
'bark-battle',
|
||||
'big-fish',
|
||||
'creative-agent',
|
||||
'jump-hop',
|
||||
'match3d',
|
||||
'puzzle',
|
||||
'rpg',
|
||||
'square-hole',
|
||||
'visual-novel',
|
||||
'wooden-fish',
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
@@ -22,7 +34,12 @@ describe('unified creation specs', () => {
|
||||
expect([...fieldKinds].sort()).toEqual(['audio', 'image', 'select', 'text']);
|
||||
});
|
||||
|
||||
test('四条链路都映射到统一创作、生成、结果阶段', () => {
|
||||
test('主要链路都映射到统一创作、生成、结果阶段', () => {
|
||||
expect(getUnifiedCreationSpec('rpg')).toMatchObject({
|
||||
workspaceStage: 'agent-workspace',
|
||||
generationStage: 'custom-world-generating',
|
||||
resultStage: 'custom-world-result',
|
||||
});
|
||||
expect(getUnifiedCreationSpec('puzzle')).toMatchObject({
|
||||
workspaceStage: 'puzzle-agent-workspace',
|
||||
generationStage: 'puzzle-generating',
|
||||
@@ -43,5 +60,20 @@ describe('unified creation specs', () => {
|
||||
generationStage: 'wooden-fish-generating',
|
||||
resultStage: 'wooden-fish-result',
|
||||
});
|
||||
expect(getUnifiedCreationSpec('bark-battle')).toMatchObject({
|
||||
workspaceStage: 'bark-battle-workspace',
|
||||
generationStage: 'bark-battle-generating',
|
||||
resultStage: 'bark-battle-result',
|
||||
});
|
||||
expect(getUnifiedCreationSpec('visual-novel')).toMatchObject({
|
||||
workspaceStage: 'visual-novel-agent-workspace',
|
||||
generationStage: 'visual-novel-generating',
|
||||
resultStage: 'visual-novel-result',
|
||||
});
|
||||
expect(getUnifiedCreationSpec('baby-object-match')).toMatchObject({
|
||||
workspaceStage: 'baby-object-match-workspace',
|
||||
generationStage: 'baby-object-match-generating',
|
||||
resultStage: 'baby-object-match-result',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,13 +3,58 @@ import type {
|
||||
UnifiedCreationSpec,
|
||||
} from '../../services/creationEntryConfigService';
|
||||
|
||||
export type UnifiedCreationPlayId = UnifiedCreationSpec['playId'];
|
||||
export const UNIFIED_CREATION_PLAY_IDS = [
|
||||
'rpg',
|
||||
'big-fish',
|
||||
'puzzle',
|
||||
'match3d',
|
||||
'jump-hop',
|
||||
'wooden-fish',
|
||||
'square-hole',
|
||||
'bark-battle',
|
||||
'visual-novel',
|
||||
'baby-object-match',
|
||||
'creative-agent',
|
||||
] as const;
|
||||
|
||||
export type UnifiedCreationPlayId =
|
||||
(typeof UNIFIED_CREATION_PLAY_IDS)[number];
|
||||
export type { UnifiedCreationSpec };
|
||||
|
||||
const FALLBACK_UNIFIED_CREATION_SPECS: Record<
|
||||
UnifiedCreationPlayId,
|
||||
UnifiedCreationSpec
|
||||
> = {
|
||||
rpg: {
|
||||
playId: 'rpg',
|
||||
title: '想做个什么玩法?',
|
||||
workspaceStage: 'agent-workspace',
|
||||
generationStage: 'custom-world-generating',
|
||||
resultStage: 'custom-world-result',
|
||||
fields: [
|
||||
{
|
||||
id: 'message',
|
||||
kind: 'text',
|
||||
label: '创作想法',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
'big-fish': {
|
||||
playId: 'big-fish',
|
||||
title: '想做个什么玩法?',
|
||||
workspaceStage: 'big-fish-agent-workspace',
|
||||
generationStage: 'big-fish-generating',
|
||||
resultStage: 'big-fish-result',
|
||||
fields: [
|
||||
{
|
||||
id: 'message',
|
||||
kind: 'text',
|
||||
label: '玩法想法',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
puzzle: {
|
||||
playId: 'puzzle',
|
||||
title: '想做个什么玩法?',
|
||||
@@ -148,12 +193,135 @@ const FALLBACK_UNIFIED_CREATION_SPECS: Record<
|
||||
},
|
||||
],
|
||||
},
|
||||
'square-hole': {
|
||||
playId: 'square-hole',
|
||||
title: '想做个什么玩法?',
|
||||
workspaceStage: 'square-hole-agent-workspace',
|
||||
generationStage: 'square-hole-generating',
|
||||
resultStage: 'square-hole-result',
|
||||
fields: [
|
||||
{
|
||||
id: 'message',
|
||||
kind: 'text',
|
||||
label: '玩法想法',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
'bark-battle': {
|
||||
playId: 'bark-battle',
|
||||
title: '想做个什么玩法?',
|
||||
workspaceStage: 'bark-battle-workspace',
|
||||
generationStage: 'bark-battle-generating',
|
||||
resultStage: 'bark-battle-result',
|
||||
fields: [
|
||||
{
|
||||
id: 'title',
|
||||
kind: 'text',
|
||||
label: '作品标题',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'themeDescription',
|
||||
kind: 'text',
|
||||
label: '主题/场景描述',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'playerImageDescription',
|
||||
kind: 'text',
|
||||
label: '玩家形象描述',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'opponentImageDescription',
|
||||
kind: 'text',
|
||||
label: '对手形象描述',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'onomatopoeia',
|
||||
kind: 'text',
|
||||
label: '拟声词',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: 'difficultyPreset',
|
||||
kind: 'select',
|
||||
label: '难度',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
'visual-novel': {
|
||||
playId: 'visual-novel',
|
||||
title: '想做个什么玩法?',
|
||||
workspaceStage: 'visual-novel-agent-workspace',
|
||||
generationStage: 'visual-novel-generating',
|
||||
resultStage: 'visual-novel-result',
|
||||
fields: [
|
||||
{
|
||||
id: 'ideaText',
|
||||
kind: 'text',
|
||||
label: '一句话创作',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'visualStyleId',
|
||||
kind: 'select',
|
||||
label: '视觉画风',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
'baby-object-match': {
|
||||
playId: 'baby-object-match',
|
||||
title: '想做个什么玩法?',
|
||||
workspaceStage: 'baby-object-match-workspace',
|
||||
generationStage: 'baby-object-match-generating',
|
||||
resultStage: 'baby-object-match-result',
|
||||
fields: [
|
||||
{
|
||||
id: 'itemAName',
|
||||
kind: 'text',
|
||||
label: '物品 A',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'itemBName',
|
||||
kind: 'text',
|
||||
label: '物品 B',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
'creative-agent': {
|
||||
playId: 'creative-agent',
|
||||
title: '想做个什么玩法?',
|
||||
workspaceStage: 'creative-agent-workspace',
|
||||
generationStage: 'puzzle-generating',
|
||||
resultStage: 'puzzle-result',
|
||||
fields: [
|
||||
{
|
||||
id: 'message',
|
||||
kind: 'text',
|
||||
label: '创作想法',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'referenceImage',
|
||||
kind: 'image',
|
||||
label: '参考图',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export function getUnifiedCreationSpec(
|
||||
playId: UnifiedCreationPlayId,
|
||||
configType?: CreationEntryTypeConfig | null,
|
||||
) {
|
||||
): UnifiedCreationSpec {
|
||||
return (
|
||||
configType?.unifiedCreationSpec ?? FALLBACK_UNIFIED_CREATION_SPECS[playId]
|
||||
);
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import type { UnifiedCreationPlayId } from './unifiedCreationSpecs';
|
||||
|
||||
export type UnifiedGenerationPlayId = Extract<
|
||||
UnifiedCreationPlayId,
|
||||
'puzzle' | 'match3d' | 'jump-hop' | 'wooden-fish'
|
||||
>;
|
||||
|
||||
const UNIFIED_GENERATION_COPY = {
|
||||
puzzle: {
|
||||
retryLabel: '重新生成图片',
|
||||
@@ -26,7 +31,7 @@ const UNIFIED_GENERATION_COPY = {
|
||||
activeBadgeLabel: '素材生成中',
|
||||
},
|
||||
} as const satisfies Record<
|
||||
UnifiedCreationPlayId,
|
||||
UnifiedGenerationPlayId,
|
||||
{
|
||||
retryLabel: string;
|
||||
settingTitle: string;
|
||||
@@ -35,6 +40,6 @@ const UNIFIED_GENERATION_COPY = {
|
||||
}
|
||||
>;
|
||||
|
||||
export function getUnifiedGenerationCopy(playId: UnifiedCreationPlayId) {
|
||||
export function getUnifiedGenerationCopy(playId: UnifiedGenerationPlayId) {
|
||||
return UNIFIED_GENERATION_COPY[playId];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user