优化素材库多选操作 #114

Merged
kdletters merged 38 commits from fix/multi-select into master 2026-08-08 11:11:26 +08:00
Member

  • 实现shift ctrl的范围选扩选
  • 实现多选下载(为一个zip)
  • 原本有搜索和文件夹折叠展开功能, 我的处理是: 只作为方便查找的用途. 最终操作会有"目前一些(比如待删除)元素被隐藏了,请再确认"的提示.

result:

root@k88936-t14p: ~/Downloads# unzip 未命名画布-选中素材-20260806-195631.zip
Archive:  未命名画布-选中素材-20260806-195631.zip
   creating: 未命名画布-选中素材/
   creating: 未命名画布-选中素材/images/
   creating: 未命名画布-选中素材/media/
 extracting: 未命名画布-选中素材/media/001-角色动作(原始视频).mp4
   creating: 未命名画布-选中素材/sequences/
   creating: 未命名画布-选中素材/sequences/002-角色动作/
   creating: 未命名画布-选中素材/sequences/002-角色动作/frames/
 extracting: 未命名画布-选中素材/sequences/002-角色动作/frames/frame-01.png
 extracting: 未命名画布-选中素材/sequences/002-角色动作/frames/frame-02.png
 extracting: 未命名画布-选中素材/sequences/002-角色动作/frames/frame-03.png
...
 extracting: 未命名画布-选中素材/sequences/002-角色动作/frames/frame-31.png
 extracting: 未命名画布-选中素材/sequences/002-角色动作/frames/frame-32.png
 extracting: 未命名画布-选中素材/sequences/002-角色动作/metadata.json
 extracting: 未命名画布-选中素材/sequences/002-角色动作/skeleton.json
 extracting: 未命名画布-选中素材/sequences/002-角色动作/README.md
 extracting: 未命名画布-选中素材/sequences/002-角色动作/manifest.txt
 extracting: 未命名画布-选中素材/metadata.json
 extracting: 未命名画布-选中素材/manifest.txt

动作的导出存在很大的问题, 在另一个pr #117 解决

<video src="attachments/2377fc8b-50e4-4919-ba41-5027b957709f" title="2026-07-27 16-15-53.mp4" controls></video> - 实现shift ctrl的范围选扩选 - 实现多选下载(为一个zip) - 原本有搜索和文件夹折叠展开功能, 我的处理是: 只作为方便查找的用途. 最终操作会有"目前一些(比如待删除)元素被隐藏了,请再确认"的提示. result: ```shell root@k88936-t14p: ~/Downloads# unzip 未命名画布-选中素材-20260806-195631.zip Archive: 未命名画布-选中素材-20260806-195631.zip creating: 未命名画布-选中素材/ creating: 未命名画布-选中素材/images/ creating: 未命名画布-选中素材/media/ extracting: 未命名画布-选中素材/media/001-角色动作(原始视频).mp4 creating: 未命名画布-选中素材/sequences/ creating: 未命名画布-选中素材/sequences/002-角色动作/ creating: 未命名画布-选中素材/sequences/002-角色动作/frames/ extracting: 未命名画布-选中素材/sequences/002-角色动作/frames/frame-01.png extracting: 未命名画布-选中素材/sequences/002-角色动作/frames/frame-02.png extracting: 未命名画布-选中素材/sequences/002-角色动作/frames/frame-03.png ... extracting: 未命名画布-选中素材/sequences/002-角色动作/frames/frame-31.png extracting: 未命名画布-选中素材/sequences/002-角色动作/frames/frame-32.png extracting: 未命名画布-选中素材/sequences/002-角色动作/metadata.json extracting: 未命名画布-选中素材/sequences/002-角色动作/skeleton.json extracting: 未命名画布-选中素材/sequences/002-角色动作/README.md extracting: 未命名画布-选中素材/sequences/002-角色动作/manifest.txt extracting: 未命名画布-选中素材/metadata.json extracting: 未命名画布-选中素材/manifest.txt ``` ~~动作的导出存在很大的问题, 在另一个pr #117 解决~~
k88936 added 12 commits 2026-07-27 17:20:53 +08:00
重写素材库的普通点击、Ctrl/Cmd 追加和 Shift 连续范围选择。

清理退出选择模式后的选中状态,并让整行素材统一响应选择操作。

支持单素材直接下载和多素材 ZIP 下载,文件名精确到秒。

固定批量操作栏并修复移动端素材列表可操作空间。

补充选择、导出、侧栏交互测试以及对应技术文档。
根据 click detail 识别键盘激活并提前清理残留指针类型

新增触摸手势后键盘选择的回归测试
使用显式条件分支构建互斥操作区

保持选择、上传、重命名和普通状态行为不变
为下载、删除和取消按钮定义三条等宽显式列轨

避免窄侧栏生成尺寸不一致的隐式列
在 JSX 前推导全选动作词和已选数量标签

移除批量工具栏中的嵌套三元表达式
使用同步 ref 互斥量保护集合导出和单选导出

在导出 finally 中释放互斥量并保留 state 作为忙碌 UI

新增同一事件循环连续导出的回归测试
让单素材导出返回浏览器下载是否已触发

仅在选中素材下载成功后展示成功状态

新增单选下载成功提示断言
使用共享四路并发读取器限制素材和序列帧网络读取

预先稳定规划去重文件名并按规划顺序写入 ZIP

覆盖外层素材并发、并发上限和逆序完成帧顺序
全选或取消全选前清空上次单项选择锚点

覆盖全选清空后 Shift 点击不扩展旧范围的回归场景
将选中素材集合和范围锚点合并到同一个状态

让单击、全选、可见协调、框选和模式切换返回纯状态转移

新增可见范围协调后 Shift 选择的回归测试
同步素材多选导出技术口径
Project CI / Repository checks (pull_request) Failing after 9s
Project CI / Backend tests (pull_request) Failing after 9s
Project CI / Frontend tests (pull_request) Failing after 33s
Project CI / Native shell tests (pull_request) Successful in 1m51s
59759360b7
记录全选与取消全选清空范围锚点

记录四路并发读取、同步互斥和确定性 ZIP 顺序验收
k88936 added this to the 美术画布 project 2026-07-27 17:21:00 +08:00
k88936 added 1 commit 2026-07-31 16:19:17 +08:00
Merge remote-tracking branch 'origin/master' into fix/multi-select
Project CI / Native shell tests (pull_request) Successful in 11m34s
Project CI / Frontend tests (pull_request) Failing after 12s
Project CI / Repository checks (pull_request) Failing after 46s
Project CI / Backend tests (pull_request) Failing after 2m37s
1297ac192e
# Conflicts:
#	docs/project-memory/shared-memory/decision-log.md
k88936 added 1 commit 2026-07-31 16:57:08 +08:00
fix: 合并回归问题
Project CI / Repository checks (pull_request) Failing after 7s
Project CI / Backend tests (pull_request) Failing after 8s
Project CI / Frontend tests (pull_request) Successful in 2m44s
Project CI / Native shell tests (pull_request) Successful in 12m14s
cd159163c5
修复文件encoding要求
更新测试
k88936 added 8 commits 2026-08-03 14:04:26 +08:00
# Conflicts:
#	docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md
#	src/components/image-editor/ImageCanvasAssetLibraryModel.test.ts
#	src/components/image-editor/ImageCanvasSidebarView.test.tsx
考虑到整个素材库的规模可能很大, 改用map查询
重构多选逻辑到一个单独的hook
不在最终提交时过滤, 只有选择操作会影响最终结果集合
- 添加 `useEffect`,在 `isAssetSelectionMode` 为 true 时关闭菜单。
- 更新测试以覆盖新行为。
更新行为文档
补充测试
新增 lostpointercapture 指针匹配清理且不重复释放捕获
贯通素材选择 Hook 到素材列表的丢失捕获事件
补充生命周期回归测试和前端拆分文档
style: 调整关闭按钮的图标样式,增加统一尺寸类名
Project CI / Repository checks (pull_request) Failing after 10s
Project CI / Backend tests (pull_request) Failing after 10s
Project CI / Frontend tests (pull_request) Failing after 20s
Project CI / Native shell tests (pull_request) Successful in 10m34s
31e0cb7456
k88936 added 1 commit 2026-08-03 15:59:00 +08:00
Merge remote-tracking branch 'origin/master' into fix/multi-select
Project CI / Repository checks (pull_request) Failing after 10s
Project CI / Backend tests (pull_request) Failing after 9s
Project CI / Frontend tests (pull_request) Failing after 20s
Project CI / Native shell tests (pull_request) Failing after 3m18s
bc665c45d7
k88936 added 1 commit 2026-08-03 16:00:09 +08:00
Merge remote-tracking branch 'origin/master' into fix/multi-select
Project CI / Repository checks (pull_request) Successful in 56s
Project CI / Backend tests (pull_request) Successful in 3m46s
Project CI / Frontend tests (pull_request) Successful in 3m1s
Project CI / Native shell tests (pull_request) Failing after 5m15s
1b942e174c
k88936 added 1 commit 2026-08-03 17:17:47 +08:00
Merge branch 'master' into fix/multi-select
Project CI / Repository checks (pull_request) Successful in 1m9s
Project CI / Frontend tests (pull_request) Successful in 3m19s
Project CI / Backend tests (pull_request) Successful in 3m57s
Project CI / Native shell tests (pull_request) Successful in 11m40s
83115ad9b2
k88936 marked the pull request as ready for review 2026-08-03 18:48:38 +08:00
k88936 added 1 commit 2026-08-03 19:11:13 +08:00
Merge branch 'master' into fix/multi-select
Project CI / Repository checks (pull_request) Successful in 56s
Project CI / Frontend tests (pull_request) Successful in 3m11s
Project CI / Backend tests (pull_request) Successful in 4m17s
Project CI / Native shell tests (pull_request) Successful in 13m5s
3aefd70b5a
kdletters requested changes 2026-08-03 20:03:56 +08:00
Dismissed
kdletters left a comment
Member

请求更改。当前 head 3aefd70b5ad47806fc5a07e1f82e594646d87728 有以下问题需要处理:

[P1] 角色动作的批量下载无法导出完整序列帧

新增的 downloadSelectedAssetssrc/components/image-editor/ImageCanvasEditorView.tsx:1434selectedAssetscreateAssetActionLayer() 转为导出图层,但当前素材库 EditorAssetSnapshot 不包含 imageSequenceFramesmapAssetLibrarySnapshot() 又会把 assetKind="character-animation" 的首帧素材识别为普通 image,并在 generationInputsOrNull() 中丢弃后端 generationInputs.characterAnimation.frames。因此从素材库选择角色动作时,无论单选还是混合批量,最终都只会下载首帧 PNG,无法进入 image-sequence 分支生成完整序列 ZIP。

PR 正文提到由 #117 解决,但 #117 当前仍为 WIP、CI 失败且存在冲突,PR 114 不能把尚未可合并的后续 PR 当作当前功能已完成的前置条件。请在本 PR 内打通完整帧契约,或等 #117 合入 master 后重新同步并验证。

[P2] 仅有 objectKey 的有效私有素材无法进入多选和批量下载

src/components/image-editor/useImageCanvasAssetSelection.ts:37 的新 getSelectableAssets() 要求 asset.src 非空;但当前素材展示契约与 ImageCanvasAssetRowView 测试明确支持 src="" + objectKey 的持久素材通过换签正常显示。此类卡片仍显示“选择素材”,实际点击、Shift、框选和全选都不会改变选择,因为目标不在 visibleAssetIds 中。批量导出又在 useImageCanvasAssetExportWorkflow.ts:761 按非空 src 过滤,修复选择边界时还需同步让 objectKey-only 素材走换签/字节读取链路,并补选择与导出回归测试。

验证:当前 head 定向前端测试 94/94 通过,typecheck、编码检查、git diff --check、merge-tree 和 4 组远端 CI 均通过;上述问题属于现有测试未覆盖的素材契约缺口。

请求更改。当前 head `3aefd70b5ad47806fc5a07e1f82e594646d87728` 有以下问题需要处理: [P1] 角色动作的批量下载无法导出完整序列帧 新增的 `downloadSelectedAssets` 在 `src/components/image-editor/ImageCanvasEditorView.tsx:1434` 将 `selectedAssets` 经 `createAssetActionLayer()` 转为导出图层,但当前素材库 `EditorAssetSnapshot` 不包含 `imageSequenceFrames`;`mapAssetLibrarySnapshot()` 又会把 `assetKind="character-animation"` 的首帧素材识别为普通 `image`,并在 `generationInputsOrNull()` 中丢弃后端 `generationInputs.characterAnimation.frames`。因此从素材库选择角色动作时,无论单选还是混合批量,最终都只会下载首帧 PNG,无法进入 `image-sequence` 分支生成完整序列 ZIP。 PR 正文提到由 #117 解决,但 #117 当前仍为 WIP、CI 失败且存在冲突,PR 114 不能把尚未可合并的后续 PR 当作当前功能已完成的前置条件。请在本 PR 内打通完整帧契约,或等 #117 合入 master 后重新同步并验证。 [P2] 仅有 objectKey 的有效私有素材无法进入多选和批量下载 `src/components/image-editor/useImageCanvasAssetSelection.ts:37` 的新 `getSelectableAssets()` 要求 `asset.src` 非空;但当前素材展示契约与 `ImageCanvasAssetRowView` 测试明确支持 `src="" + objectKey` 的持久素材通过换签正常显示。此类卡片仍显示“选择素材”,实际点击、Shift、框选和全选都不会改变选择,因为目标不在 `visibleAssetIds` 中。批量导出又在 `useImageCanvasAssetExportWorkflow.ts:761` 按非空 `src` 过滤,修复选择边界时还需同步让 objectKey-only 素材走换签/字节读取链路,并补选择与导出回归测试。 验证:当前 head 定向前端测试 94/94 通过,typecheck、编码检查、git diff --check、merge-tree 和 4 组远端 CI 均通过;上述问题属于现有测试未覆盖的素材契约缺口。
k88936 marked the pull request as work in progress 2026-08-04 11:41:58 +08:00
k88936 added 3 commits 2026-08-06 18:45:04 +08:00
统一使用 src || objectKey 判断素材是否可读
已同步导出方案文档
合并主线角色动作序列帧、完美像素、外部编辑器与 AI 游戏创作 Runtime 最新改动
保留 objectKey-only 私有素材多选、批量导出与统一时间戳语义
统一素材删除门禁、参考图上传锁和侧栏选择状态清理
同步图片画布技术方案与角色动作下载集成测试
合并主分支
Project CI / Repository checks (pull_request) Successful in 55s
Project CI / Frontend tests (pull_request) Successful in 3m0s
Project CI / Backend tests (pull_request) Successful in 3m43s
Project CI / Native shell tests (pull_request) Successful in 12m37s
ef42374b44
无冲突
k88936 marked the pull request as ready for review 2026-08-06 19:46:07 +08:00
k88936 added 4 commits 2026-08-07 14:03:13 +08:00
修复触摸滚动、滚动框选坐标和抬手/取消语义
统一不可选素材行的交互与无障碍状态
支持仅帧来源的序列帧导出并统一导出互斥锁
补充定向回归测试并同步素材选择与导出文档
阻断选择模式下的素材移动与外部文件投放并清理拖拽状态
固定隐藏素材删除确认目标并在选择范围漂移时关闭弹窗
收敛选择交互契约与素材行标签分支
修正短视口侧栏高度并补充定向回归测试和文档
明确记录框选热路径的性能问题与优化边界
注明序列部分成功是 master 既有行为并等待契约讨论
合并主分支
Project CI / Repository checks (pull_request) Successful in 1m1s
Project CI / Frontend tests (pull_request) Failing after 2m35s
Project CI / Backend tests (pull_request) Successful in 4m10s
Project CI / Native shell tests (pull_request) Successful in 15m40s
ab5ec2c40f
解决简单合并冲突
k88936 added 1 commit 2026-08-07 14:30:56 +08:00
修复项目切换清单竞态测试超时
Project CI / Repository checks (pull_request) Successful in 1m1s
Project CI / Frontend tests (pull_request) Successful in 3m28s
Project CI / Backend tests (pull_request) Successful in 4m1s
Project CI / Native shell tests (pull_request) Failing after 10m14s
4911801ed6
等待事件监听注册后再触发 manifest 失效并以有界断言确认读取启动
将迟到响应收尾纳入异步 act 避免测试时序悬挂
补充 React 异步事件测试准则
k88936 requested review from kdletters 2026-08-07 14:42:09 +08:00
kdletters requested changes 2026-08-07 15:09:46 +08:00
Dismissed
kdletters left a comment
Member

请求更改。当前 head 4911801ed67e782f37f63145fcd5d5c36de8943a 仍有一处批量导出数据完整性问题:objectKey-only 私有序列帧会发生去重键碰撞,导致后续动作素材被静默漏导出并产生错误 metadata。请修复序列帧稳定身份并补覆盖两个不同私有序列共同导出的回归测试。另请在合并前将当前失败的 Native shell CI 重跑至绿色或明确处理。

请求更改。当前 head `4911801ed67e782f37f63145fcd5d5c36de8943a` 仍有一处批量导出数据完整性问题:objectKey-only 私有序列帧会发生去重键碰撞,导致后续动作素材被静默漏导出并产生错误 metadata。请修复序列帧稳定身份并补覆盖两个不同私有序列共同导出的回归测试。另请在合并前将当前失败的 Native shell CI 重跑至绿色或明确处理。
@@ -591,0 +483,4 @@
for (const layer of exportableLayers) {
const key = getLayerExportKey(layer);
if (plannedKeys.has(key)) {
Member

[P1] 这里使用 getLayerExportKey(layer) 做集合导出去重,但序列帧 key 当前只拼接 frame.imageSrc,没有使用合法的帧级 objectKey。当两个私有动作序列都只有不同的 objectKey、imageSrc="",且没有 taskId/sourceResourceId 时,两者都会得到 image-sequence:|;第二个动作会在此处被直接跳过,ZIP 漏素材,根 metadata 还会把它映射到首个动作。请把帧级 assetObjectId/objectKey 纳入稳定 key,并补两个 objectKey-only 序列同时导出的回归测试。

[P1] 这里使用 `getLayerExportKey(layer)` 做集合导出去重,但序列帧 key 当前只拼接 `frame.imageSrc`,没有使用合法的帧级 `objectKey`。当两个私有动作序列都只有不同的 objectKey、`imageSrc=""`,且没有 taskId/sourceResourceId 时,两者都会得到 `image-sequence:|`;第二个动作会在此处被直接跳过,ZIP 漏素材,根 metadata 还会把它映射到首个动作。请把帧级 assetObjectId/objectKey 纳入稳定 key,并补两个 objectKey-only 序列同时导出的回归测试。
k88936 marked this conversation as resolved
k88936 added 1 commit 2026-08-07 15:31:35 +08:00
修复私有序列帧批量导出去重
Project CI / Repository checks (pull_request) Successful in 1m10s
Project CI / Frontend tests (pull_request) Successful in 3m20s
Project CI / Backend tests (pull_request) Successful in 3m52s
Project CI / Native shell tests (pull_request) Successful in 15m43s
e87228156c
将帧级 assetObjectId、objectKey 与 imageSrc 纳入有边界的稳定导出身份
补充两个 objectKey-only 私有序列共同导出及 metadata 映射回归
同步角色动作集合导出去重契约文档
k88936 requested review from kdletters 2026-08-07 15:53:45 +08:00
kdletters approved these changes 2026-08-07 18:16:22 +08:00
Dismissed
kdletters scheduled this pull request to auto merge when all checks succeed 2026-08-07 18:16:48 +08:00
k88936 added 2 commits 2026-08-07 22:21:38 +08:00
处理合并冲突
合并主分支
Project CI / Repository checks (pull_request) Successful in 1m40s
Project CI / Frontend tests (pull_request) Successful in 2m59s
Project CI / Backend tests (pull_request) Successful in 3m47s
Project CI / Native shell tests (pull_request) Successful in 14m2s
1cac7a3004
处理合并冲突
k88936 force-pushed fix/multi-select from deb8e9765c to 1cac7a3004 2026-08-07 22:21:38 +08:00 Compare
k88936 dismissed kdletters's review 2026-08-07 22:21:38 +08:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

k88936 requested review from kdletters 2026-08-07 22:33:27 +08:00
k88936 added 1 commit 2026-08-08 10:40:35 +08:00
合并主分支
Project CI / Repository checks (pull_request) Successful in 1m4s
Project CI / Frontend tests (pull_request) Successful in 3m32s
Project CI / Backend tests (pull_request) Successful in 4m10s
Project CI / Native shell tests (pull_request) Successful in 14m12s
e633039d11
解决合并冲突
k88936 removed review request for kdletters 2026-08-08 11:10:30 +08:00
k88936 requested review from kdletters 2026-08-08 11:10:35 +08:00
kdletters merged commit 498b905bd8 into master 2026-08-08 11:11:26 +08:00
kdletters deleted branch fix/multi-select 2026-08-08 11:11:26 +08:00
Sign in to join this conversation.