优化各元素输入框中的启发提示文本
音效、背景音乐和图标素材改为空值加灰色启发提示。 角色规范、图标规范和自定义规范输入框补充灰色启发提示。 同步更新相关前端组件测试。
This commit is contained in:
@@ -779,8 +779,8 @@ function ImageCanvasAudioGenerationComposerView({
|
||||
disabled={isGenerating}
|
||||
placeholder={
|
||||
isSoundEffect
|
||||
? '描述需要生成的游戏音效'
|
||||
: '描述需要生成的游戏背景音乐'
|
||||
? '你希望生成什么音效?'
|
||||
: '你希望生成什么音乐?'
|
||||
}
|
||||
size="sm"
|
||||
density="compact"
|
||||
|
||||
@@ -74,6 +74,28 @@ describe('ImageCanvasGenerationDialogModel', () => {
|
||||
originalHeight: 1024,
|
||||
},
|
||||
});
|
||||
expect(
|
||||
createSpecDialogDraft({ canvasSize, viewport, specType: 'character' }),
|
||||
).toMatchObject({
|
||||
mode: 'spec',
|
||||
specType: 'character',
|
||||
specValues: {
|
||||
playSetting: '',
|
||||
artStyle: '',
|
||||
bodyRatio: '3',
|
||||
},
|
||||
});
|
||||
expect(
|
||||
createSpecDialogDraft({ canvasSize, viewport, specType: 'ui' }),
|
||||
).toMatchObject({
|
||||
mode: 'spec',
|
||||
specType: 'ui',
|
||||
specValues: {
|
||||
playSetting: '',
|
||||
artStyle: '',
|
||||
bodyRatio: '3',
|
||||
},
|
||||
});
|
||||
expect(
|
||||
createSpecDialogDraft({ canvasSize, viewport, specType: 'icon' }),
|
||||
).toMatchObject({
|
||||
@@ -153,16 +175,9 @@ describe('ImageCanvasGenerationDialogModel', () => {
|
||||
imageModel: 'unknown-model',
|
||||
aspectRatio: '1:1',
|
||||
imageSize: '1K',
|
||||
prompt: '返回按钮\n设置按钮\n下一关按钮\n提示按钮\n原图按钮\n冻结按钮',
|
||||
prompt: '',
|
||||
iconSpecReference: null,
|
||||
iconDescriptions: [
|
||||
'返回按钮',
|
||||
'设置按钮',
|
||||
'下一关按钮',
|
||||
'提示按钮',
|
||||
'原图按钮',
|
||||
'冻结按钮',
|
||||
],
|
||||
iconDescriptions: [],
|
||||
placeholder: {
|
||||
x: 300,
|
||||
y: 180,
|
||||
@@ -228,8 +243,7 @@ describe('ImageCanvasGenerationDialogModel', () => {
|
||||
expect(createSoundEffectGenerationDialogDraft({ canvasSize, viewport }))
|
||||
.toMatchObject({
|
||||
mode: 'audio-sound-effect',
|
||||
prompt:
|
||||
'短促清脆的游戏交互音效,带轻微闪光质感,干净收尾,适合按钮确认或收集奖励。',
|
||||
prompt: '',
|
||||
status: 'idle',
|
||||
composerOpen: true,
|
||||
soundModel: 'audio1.0',
|
||||
@@ -246,8 +260,7 @@ describe('ImageCanvasGenerationDialogModel', () => {
|
||||
expect(createBackgroundMusicGenerationDialogDraft({ canvasSize, viewport }))
|
||||
.toMatchObject({
|
||||
mode: 'audio-background-music',
|
||||
prompt:
|
||||
'适合轻松冒险游戏的循环背景音乐,温暖明亮,旋律简洁,不包含人声。',
|
||||
prompt: '',
|
||||
status: 'idle',
|
||||
composerOpen: true,
|
||||
makeInstrumental: true,
|
||||
|
||||
@@ -50,11 +50,6 @@ const VIDEO_REFERENCE_LIMITS = {
|
||||
video: 3,
|
||||
audio: 3,
|
||||
} as const;
|
||||
const DEFAULT_SOUND_EFFECT_PROMPT =
|
||||
'短促清脆的游戏交互音效,带轻微闪光质感,干净收尾,适合按钮确认或收集奖励。';
|
||||
const DEFAULT_BACKGROUND_MUSIC_PROMPT =
|
||||
'适合轻松冒险游戏的循环背景音乐,温暖明亮,旋律简洁,不包含人声。';
|
||||
|
||||
function getViewportWorldCenter({
|
||||
canvasSize,
|
||||
viewport,
|
||||
@@ -194,6 +189,10 @@ export function createGenerateDialogDraft({
|
||||
};
|
||||
}
|
||||
|
||||
function shouldUseSpecPlaceholderValues(specType: SpecGenerationType) {
|
||||
return specType === 'character' || specType === 'ui';
|
||||
}
|
||||
|
||||
export function createSpecDialogDraft({
|
||||
canvasSize,
|
||||
viewport,
|
||||
@@ -210,7 +209,12 @@ export function createSpecDialogDraft({
|
||||
status: 'idle',
|
||||
composerOpen: true,
|
||||
specType,
|
||||
specValues: { ...DEFAULT_SPEC_FORM_VALUES[specType] },
|
||||
specValues: {
|
||||
...DEFAULT_SPEC_FORM_VALUES[specType],
|
||||
...(shouldUseSpecPlaceholderValues(specType)
|
||||
? { playSetting: '', artStyle: '' }
|
||||
: {}),
|
||||
},
|
||||
placeholder: {
|
||||
x: worldCenter.x - SPEC_FRAME_ORIGINAL_SIZE.width / 2,
|
||||
y: worldCenter.y - SPEC_FRAME_ORIGINAL_SIZE.height / 2,
|
||||
@@ -274,11 +278,11 @@ export function createIconGenerationDialogDraft({
|
||||
const dimensionDefaults = resolveImageDimensionDefaults(normalizedImageModel);
|
||||
return {
|
||||
mode: 'icon',
|
||||
prompt: formatIconDescriptionsText(DEFAULT_ICON_DESCRIPTIONS),
|
||||
prompt: '',
|
||||
status: 'idle',
|
||||
composerOpen: true,
|
||||
iconSpecReference: null,
|
||||
iconDescriptions: [...DEFAULT_ICON_DESCRIPTIONS],
|
||||
iconDescriptions: [],
|
||||
imageModel: normalizedImageModel,
|
||||
aspectRatio: dimensionDefaults.aspectRatio,
|
||||
imageSize: dimensionDefaults.imageSize,
|
||||
@@ -373,7 +377,7 @@ export function createSoundEffectGenerationDialogDraft({
|
||||
const worldCenter = getViewportWorldCenter({ canvasSize, viewport });
|
||||
return {
|
||||
mode: 'audio-sound-effect',
|
||||
prompt: DEFAULT_SOUND_EFFECT_PROMPT,
|
||||
prompt: '',
|
||||
status: 'idle',
|
||||
composerOpen: true,
|
||||
soundModel: DEFAULT_SOUND_EFFECT_MODEL,
|
||||
@@ -399,7 +403,7 @@ export function createBackgroundMusicGenerationDialogDraft({
|
||||
const worldCenter = getViewportWorldCenter({ canvasSize, viewport });
|
||||
return {
|
||||
mode: 'audio-background-music',
|
||||
prompt: DEFAULT_BACKGROUND_MUSIC_PROMPT,
|
||||
prompt: '',
|
||||
status: 'idle',
|
||||
composerOpen: true,
|
||||
makeInstrumental: true,
|
||||
|
||||
@@ -103,6 +103,18 @@ describe('ImageCanvasIconSpritesheetComposerView', () => {
|
||||
expect(requestUpload).toHaveBeenCalledWith('icon-spec');
|
||||
});
|
||||
|
||||
it('uses a grey hint instead of default icon text for new icon drafts', () => {
|
||||
render(
|
||||
<IconComposerHarness
|
||||
initialDialog={createIconDialog({ iconDescriptions: [] })}
|
||||
/>,
|
||||
);
|
||||
|
||||
const input = screen.getByLabelText('素材描述') as HTMLTextAreaElement;
|
||||
expect(input.value).toBe('');
|
||||
expect(input.placeholder).toBe('你需要哪些图标?');
|
||||
});
|
||||
|
||||
it('keeps the spec reference as a single first-row card without extra source buttons', () => {
|
||||
render(<IconComposerHarness initialDialog={createIconDialog()} />);
|
||||
|
||||
|
||||
@@ -63,8 +63,7 @@ export function ImageCanvasIconSpritesheetComposerView({
|
||||
onSubmit,
|
||||
}: ImageCanvasIconSpritesheetComposerViewProps) {
|
||||
const descriptionText =
|
||||
dialog.prompt ||
|
||||
(dialog.iconDescriptions ?? DEFAULT_ICON_DESCRIPTIONS).join('\n');
|
||||
dialog.prompt || (dialog.iconDescriptions ?? []).join('\n');
|
||||
useImageCanvasFloatingOptionDismiss({
|
||||
isOpen: isIconSpecMenuOpen,
|
||||
boundaryRefs: [iconSpecButtonRef],
|
||||
@@ -176,7 +175,7 @@ export function ImageCanvasIconSpritesheetComposerView({
|
||||
aria-label="素材描述"
|
||||
value={descriptionText}
|
||||
disabled={dialog.status === 'generating'}
|
||||
placeholder="描述要生成的多个素材,每行一个。"
|
||||
placeholder="你需要哪些图标?"
|
||||
size="sm"
|
||||
density="compact"
|
||||
className="image-canvas-editor__generation-prompt image-canvas-editor__generation-prompt--borderless"
|
||||
|
||||
@@ -161,6 +161,13 @@ describe('ImageCanvasSpecGenerationPanelView', () => {
|
||||
onUpdateSpecFormValue: updateSpecFormValue,
|
||||
});
|
||||
|
||||
expect(
|
||||
(screen.getByLabelText('玩法设定') as HTMLInputElement).placeholder,
|
||||
).toBe('这是什么类型的游戏?');
|
||||
expect(
|
||||
(screen.getByLabelText('美术风格') as HTMLInputElement).placeholder,
|
||||
).toBe('游戏的画风是怎样的?');
|
||||
|
||||
fireEvent.change(screen.getByLabelText('玩法设定'), {
|
||||
target: { value: '战棋玩法' },
|
||||
});
|
||||
@@ -183,6 +190,34 @@ describe('ImageCanvasSpecGenerationPanelView', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('uses gameplay and art style hints for icon specs', () => {
|
||||
renderPanel({
|
||||
dialog: createSpecDialog({
|
||||
specType: 'ui',
|
||||
specValues: {
|
||||
playSetting: '',
|
||||
artStyle: '',
|
||||
bodyRatio: '3',
|
||||
characterView: '右向斜侧身站姿',
|
||||
customPrompt: '',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
expect((screen.getByLabelText('玩法设定') as HTMLInputElement).value).toBe(
|
||||
'',
|
||||
);
|
||||
expect(
|
||||
(screen.getByLabelText('玩法设定') as HTMLInputElement).placeholder,
|
||||
).toBe('这是什么类型的游戏?');
|
||||
expect((screen.getByLabelText('美术风格') as HTMLInputElement).value).toBe(
|
||||
'',
|
||||
);
|
||||
expect(
|
||||
(screen.getByLabelText('美术风格') as HTMLInputElement).placeholder,
|
||||
).toBe('游戏的画风是怎样的?');
|
||||
});
|
||||
|
||||
it('renders custom prompt and hides reference upload for icon specs', () => {
|
||||
const updateSpecFormValue = vi.fn();
|
||||
renderPanel({
|
||||
@@ -199,6 +234,13 @@ describe('ImageCanvasSpecGenerationPanelView', () => {
|
||||
onUpdateSpecFormValue: updateSpecFormValue,
|
||||
});
|
||||
|
||||
const customPrompt = screen.getByLabelText(
|
||||
'自定义规范提示词',
|
||||
) as HTMLTextAreaElement;
|
||||
expect(customPrompt.placeholder).toBe(
|
||||
'写下你想要的任何内容,陶泥儿帮你形成新的约束',
|
||||
);
|
||||
|
||||
fireEvent.change(screen.getByLabelText('自定义规范提示词'), {
|
||||
target: { value: '新的规范提示' },
|
||||
});
|
||||
|
||||
@@ -60,6 +60,10 @@ type ImageCanvasSpecGenerationPanelViewProps = {
|
||||
onSubmit: (dialog: GenerateDialogState) => void;
|
||||
};
|
||||
|
||||
function shouldShowSpecInputPlaceholders(dialog: GenerateDialogState) {
|
||||
return dialog.specType === 'character' || dialog.specType === 'ui';
|
||||
}
|
||||
|
||||
export function ImageCanvasSpecGenerationPanelView({
|
||||
dialog,
|
||||
style,
|
||||
@@ -77,6 +81,7 @@ export function ImageCanvasSpecGenerationPanelView({
|
||||
onSubmit,
|
||||
}: ImageCanvasSpecGenerationPanelViewProps) {
|
||||
const isUiDesignDialog = dialog.mode === 'ui-design';
|
||||
const showSpecInputPlaceholders = shouldShowSpecInputPlaceholders(dialog);
|
||||
const specSizeLabel = resolveEditorImageSizeLabel({
|
||||
aspectRatio: SPEC_GENERATION_ASPECT_RATIO,
|
||||
imageSize: SPEC_GENERATION_IMAGE_SIZE,
|
||||
@@ -237,6 +242,7 @@ export function ImageCanvasSpecGenerationPanelView({
|
||||
variant="textarea"
|
||||
aria-label="自定义规范提示词"
|
||||
value={dialog.specValues?.customPrompt ?? ''}
|
||||
placeholder="写下你想要的任何内容,陶泥儿帮你形成新的约束"
|
||||
disabled={isGenerating}
|
||||
size="sm"
|
||||
density="compact"
|
||||
@@ -258,6 +264,11 @@ export function ImageCanvasSpecGenerationPanelView({
|
||||
<PlatformTextField
|
||||
aria-label="玩法设定"
|
||||
value={dialog.specValues?.playSetting ?? ''}
|
||||
placeholder={
|
||||
showSpecInputPlaceholders
|
||||
? '这是什么类型的游戏?'
|
||||
: undefined
|
||||
}
|
||||
disabled={isGenerating}
|
||||
size="sm"
|
||||
density="compact"
|
||||
@@ -277,6 +288,11 @@ export function ImageCanvasSpecGenerationPanelView({
|
||||
<PlatformTextField
|
||||
aria-label="美术风格"
|
||||
value={dialog.specValues?.artStyle ?? ''}
|
||||
placeholder={
|
||||
showSpecInputPlaceholders
|
||||
? '游戏的画风是怎样的?'
|
||||
: undefined
|
||||
}
|
||||
disabled={isGenerating}
|
||||
size="sm"
|
||||
density="compact"
|
||||
|
||||
@@ -7667,10 +7667,18 @@ button.image-canvas-editor__reference-chip:disabled {
|
||||
min-height: 1.96rem;
|
||||
}
|
||||
|
||||
.image-canvas-editor__spec-input::placeholder {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.image-canvas-editor__spec-textarea {
|
||||
min-height: 3.8rem;
|
||||
}
|
||||
|
||||
.image-canvas-editor__spec-textarea::placeholder {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.image-canvas-editor__spec-textarea--view {
|
||||
min-height: 3.1rem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user