禁止快速编辑任务中继续框选
快速编辑进入生成中后移除框选工具和覆盖层 新增挂起请求回归测试覆盖任务开始后的锁定状态 更新图片画布快速编辑项目记忆与验证口径
This commit is contained in:
@@ -380,9 +380,9 @@
|
||||
|
||||
- 现象:用户点击图片素材的“快速编辑”后,画布上额外出现 `Quick Edit Generator` 占位,像是新建了一个生成器;但用户预期是在原图下方框选区域、填写一个提示词和模型,然后直接修改当前图。
|
||||
- 原因:快速编辑入口和提交链路误用了 `createQuickEditGenerationDialogDraft(...)` / `CanvasGenerationDialogState`,把“覆盖源图”的快速编辑伪装成会产出新图层的生成器占位。
|
||||
- 处理:图片快速编辑必须走 `QuickEditPanelState`,打开时归档当前 active generation dialog 但不创建新的 `mode="quick-edit"` dialog;提交时调用 `/api/editor/images/edits`,把当前图片或带编号标注的图片作为 `sourceImageSrc`,成功后覆盖源图,失败时保留快速编辑面板。图片重绘、去背景、视频快速编辑等会产出新图层或异步占位的入口仍可走 generation dialog / placement 链路。
|
||||
- 验证:`npm run test -- src/components/image-editor/useImageCanvasGenerationWorkflow.test.tsx src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.test.tsx src/components/image-editor/ImageCanvasQuickEditPanelView.test.tsx -- --runInBand`,以及按需运行 `npm run test -- src/components/image-editor/ImageCanvasEditorGenerationIntegration.test.tsx -t "快速编辑|quick edit" -- --runInBand`。
|
||||
- 关联:`src/components/image-editor/useImageCanvasGenerationWorkflow.ts`、`src/components/image-editor/ImageCanvasGenerationSubmissionModel.ts`、`src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.ts`、`src/services/image-editor/editorImageReference.ts`。
|
||||
- 处理:图片快速编辑必须走 `QuickEditPanelState`,打开时归档当前 active generation dialog 但不创建新的 `mode="quick-edit"` dialog;提交时调用 `/api/editor/images/edits`,把当前图片或带编号标注的图片作为 `sourceImageSrc`,成功后覆盖源图,失败时保留快速编辑面板。快速编辑任务进入 `generating` 后必须移除框选工具和覆盖层,禁止继续新增框选;失败恢复面板后可继续调整框选再重试。图片重绘、去背景、视频快速编辑等会产出新图层或异步占位的入口仍可走 generation dialog / placement 链路。
|
||||
- 验证:`npm run test -- src/components/image-editor/useImageCanvasGenerationWorkflow.test.tsx src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.test.tsx src/components/image-editor/ImageCanvasQuickEditPanelView.test.tsx src/components/image-editor/ImageCanvasEditorView.test.tsx -- --runInBand`,以及按需运行 `npm run test -- src/components/image-editor/ImageCanvasEditorGenerationIntegration.test.tsx -t "快速编辑|quick edit" -- --runInBand`。
|
||||
- 关联:`src/components/image-editor/ImageCanvasEditorView.tsx`、`src/components/image-editor/useImageCanvasGenerationWorkflow.ts`、`src/components/image-editor/ImageCanvasGenerationSubmissionModel.ts`、`src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.ts`、`src/services/image-editor/editorImageReference.ts`。
|
||||
|
||||
## 图片画布快速编辑完成必须按目标图层回写
|
||||
|
||||
|
||||
@@ -788,6 +788,53 @@ describe('ImageCanvasEditorView', () => {
|
||||
expect(resumedPrompt.value).not.toContain('2号红色圈选框');
|
||||
});
|
||||
|
||||
it('locks quick edit selection tools after the edit task starts', async () => {
|
||||
editEditorImageMock.mockReturnValueOnce(new Promise(() => {}));
|
||||
render(<ImageCanvasEditorView />);
|
||||
|
||||
const sourceLayer = (
|
||||
await screen.findByAltText('画布图片:拼图素材')
|
||||
).closest('button')!;
|
||||
dispatchPointerEvent(sourceLayer, 'pointerdown', {
|
||||
button: 0,
|
||||
pointerId: 74,
|
||||
clientX: 120,
|
||||
clientY: 120,
|
||||
});
|
||||
fireEvent.click(screen.getByRole('button', { name: '快速编辑' }));
|
||||
|
||||
const quickEditDialog = screen.getByRole('dialog', {
|
||||
name: '快速编辑图片',
|
||||
});
|
||||
fireEvent.change(within(quickEditDialog).getByLabelText('快速编辑提示词'), {
|
||||
target: { value: '快速修图' },
|
||||
});
|
||||
fireEvent.click(
|
||||
within(
|
||||
screen.getByRole('toolbar', { name: '快速编辑框选工具' }),
|
||||
).getByRole('button', { name: '矩形框选' }),
|
||||
);
|
||||
|
||||
fireEvent.click(
|
||||
within(quickEditDialog).getByRole('button', { name: '修改' }),
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(editEditorImageMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
expect(
|
||||
screen.queryByRole('toolbar', { name: '快速编辑框选工具' }),
|
||||
).toBeNull();
|
||||
expect(
|
||||
screen.queryByRole('application', { name: 'UI素材框选画布' }),
|
||||
).toBeNull();
|
||||
const submitButton = within(quickEditDialog).getByRole('button', {
|
||||
name: '修改',
|
||||
});
|
||||
expect((submitButton as HTMLButtonElement).disabled).toBe(true);
|
||||
expect(submitButton.textContent).toBe('生成中');
|
||||
});
|
||||
|
||||
it('opens the login modal immediately when entering the editor while logged out', async () => {
|
||||
const openLoginModal = vi.fn();
|
||||
|
||||
|
||||
@@ -820,11 +820,12 @@ export function useImageCanvasGenerationWorkflow({
|
||||
(layer) => layer.id === uiAssetExtractionState.sourceLayerId,
|
||||
) ?? null)
|
||||
: null;
|
||||
const quickEditSelectionSourceLayer = quickEditSelectionState
|
||||
? (layers.find(
|
||||
(layer) => layer.id === quickEditSelectionState.sourceLayerId,
|
||||
) ?? null)
|
||||
: null;
|
||||
const quickEditSelectionSourceLayer =
|
||||
quickEditPanel?.status !== 'generating' && quickEditSelectionState
|
||||
? (layers.find(
|
||||
(layer) => layer.id === quickEditSelectionState.sourceLayerId,
|
||||
) ?? null)
|
||||
: null;
|
||||
const characterAnimationSourceLayer = effectiveCharacterAnimationPanel
|
||||
? (layers.find(
|
||||
(layer) => layer.id === effectiveCharacterAnimationPanel.sourceLayerId,
|
||||
|
||||
Reference in New Issue
Block a user