From 7b23cce67a1b9e61a48d89dedbd088d37b10ecd4 Mon Sep 17 00:00:00 2001 From: brother7 <7brother7@gmail.com> Date: Thu, 6 Aug 2026 13:00:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=A7=86=E9=A2=91=E9=A6=96?= =?UTF-8?q?=E5=B8=A7=E9=80=89=E6=8B=A9=E5=BC=B9=E7=AA=97=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:选择作品图片后需等待 Agent 整轮响应,弹窗长时间不关闭。 修复:选择后立即关闭弹窗并继续提交 Asset ID,失败信息转到主对话区;补充慢响应回归测试。 --- .../20260806-video-source-picker-4d8a.md | 43 +++++++++++++++++++ src/pages/ImageCanvas/index.tsx | 7 ++- tests/unit/image-canvas-page.test.tsx | 8 ++++ 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 .project-docs/30-worklog/tasks/20260806-video-source-picker-4d8a.md diff --git a/.project-docs/30-worklog/tasks/20260806-video-source-picker-4d8a.md b/.project-docs/30-worklog/tasks/20260806-video-source-picker-4d8a.md new file mode 100644 index 0000000..4853e70 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260806-video-source-picker-4d8a.md @@ -0,0 +1,43 @@ +# Task: 修复作品图片选择与视频首帧附件提交 + +## Identity + +- Task ID: 20260806-video-source-picker-4d8a +- Mode: Feature +- Branch: codex/fix-video-source-selection +- Worktree: D:\Datas\OthersProjects\makelore-video-source-selection +- Base commit: 929b12485257e03faa45495a8eb429b63fdec038 +- Owner: codex +- Status: Completed + +## Scope + +- 修复从作品列表选择视频首帧后弹窗持续停留的问题。 +- 保持 `resultAssets[].assetId` 到 Gateway `attachment_asset_ids` 的现有传递链路。 +- 增加慢 Agent 响应场景的回归测试。 + +## Intent And Constraints + +- 用户确认选择后立即关闭弹窗,不等待整轮 Agent 响应。 +- Agent 请求失败时在主对话区展示错误,不把错误留在已关闭弹窗中。 +- 不触碰原客户端工作区中的其他未提交改动。 + +## Outcome + +- 作品图片选择后弹窗立即关闭,同时继续提交真实 Asset ID。 +- 请求失败会回到对话区错误提示,用户仍可重新选择。 +- 回归测试覆盖 Agent Promise 未完成时的弹窗状态。 + +## Verification + +- `vitest image-canvas-page + works-square-design-workspace`:38 passed。 +- `pnpm typecheck`:通过。 +- `pnpm build:vite`:通过(仅保留既有 chunk 体积提示)。 + +## Follow-ups + +- None recorded. + +## Promotion Candidates + +- None recorded. diff --git a/src/pages/ImageCanvas/index.tsx b/src/pages/ImageCanvas/index.tsx index 64d5cef..52c4fd6 100644 --- a/src/pages/ImageCanvas/index.tsx +++ b/src/pages/ImageCanvas/index.tsx @@ -547,15 +547,14 @@ export function ImageCanvas() { const requestedWorkspaceId = workspace.workspaceId; setFirstFrameBusyKey(asset.assetId); setFirstFrameError(null); + setActionError(null); setSubmitting(true); + setFirstFramePickerOpen(false); try { await sendMessage('使用作品图片作为视频首帧', [asset.assetId]); - if (useImageWorkspaceStore.getState().activeWorkspaceId === requestedWorkspaceId) { - setFirstFramePickerOpen(false); - } } catch (error) { if (useImageWorkspaceStore.getState().activeWorkspaceId === requestedWorkspaceId) { - setFirstFrameError(error instanceof Error ? error.message : String(error)); + setActionError(error instanceof Error ? error.message : String(error)); } } finally { setFirstFrameBusyKey(null); diff --git a/tests/unit/image-canvas-page.test.tsx b/tests/unit/image-canvas-page.test.tsx index 688f1de..2b75a91 100644 --- a/tests/unit/image-canvas-page.test.tsx +++ b/tests/unit/image-canvas-page.test.tsx @@ -570,6 +570,8 @@ describe('ImageCanvas Workspace-first design experience', () => { }); it('submits a successful work Asset id when it is selected as the video first frame', async () => { + const pendingSelection = deferred(); + sendImageWorkspaceMessageMock.mockReturnValueOnce(pendingSelection.promise); fetchImageWorkspaceProjectMock.mockResolvedValueOnce({ ...workspaceFixture(), turnRevision: 2, @@ -603,6 +605,12 @@ describe('ImageCanvas Workspace-first design experience', () => { expect.stringMatching(/^turn-/), ['asset-one'], )); + expect(screen.queryByRole('dialog', { name: '选择视频首帧' })).not.toBeInTheDocument(); + + await act(async () => { + pendingSelection.resolve(workspaceFixture()); + await pendingSelection.promise; + }); }); it('uploads a local first-frame image and submits its Asset id to the Agent', async () => {