Skip to content

feat(storyboard): SB-2 脚本导入对话框 + 批量建链——E1 整条链贯通 - #225

Merged
KerroKapple merged 1 commit into
mainfrom
feat/sb-2-script-import
Aug 10, 2026
Merged

feat(storyboard): SB-2 脚本导入对话框 + 批量建链——E1 整条链贯通#225
KerroKapple merged 1 commit into
mainfrom
feat/sb-2-script-import

Conversation

@KerroKapple

Copy link
Copy Markdown
Owner

这张卡解决什么

E1 之前只差一个入口:分镜链的每一块(shot 面板 SB-3、直达出图/出视频 SB-4、序列预览 SB-6、按叙事序导出 EX-1′、拆分器 SB-1)都在,但用户手上有本子时,仍得一个节点一个节点地建、一条边一条边地连。

SB-2 把这段路铺上:粘一段脚本进来,一键变成串好的分镜链。至此
「粘贴脚本 → 分镜链 → 出图/出视频 → 序列预览 → 按叙事序导出」整条 E1 贯通。

做了什么

ScriptImportControllerfeatures/storyboard/providers/
N 个 shot 节点 + N-1 条 narrative 边收进单个事务unitOfWorkProvider)。
落点:第一镜在 origin,后续每 kShotChainSpacingX(260) 沿 x 轴排开(shot 卡宽 240,留 20 走线余量)。
typeConfig.shot_notesShotConfigInspector 同键——导入后点开面板就能接着编辑。

ScriptImportDialogfeatures/storyboard/widgets/
粘贴框 + 策略切换(空行分段 / 每行一镜)+ 实时预览(拆成几镜、每镜叫什么)。
拆分规则再讲究也有猜错的时候,用户得先看见结果才敢按创建;切策略预览立刻重算,等于把 SB-1 的规则摊开给人验。

入口:画布 FAB 菜单「导入脚本…」+ 空态 CTA「导入脚本」。都以视口中心为第一镜落点。

两个判断,都记进了 README

失败必须零残留。 半条链(几个建好的散镜 + 几条边)比一个错误提示难收拾得多——用户既不知道哪几镜落地了,也没有一键撤销。所以整批走一个事务,中途任一步抛 InkError 就整体回滚。测试用的 fake UoW 会真回滚(写入先落 staging,闭包整体成功才 commit),不是走个过场;真事务的回滚语义仍由 test/storage/transaction_integration_test.dart(真 PG)兜底。

provider 不加 autoDispose。 调用方只 ref.read 拿一次控制器(不订阅),autoDispose 会在 read 之后立刻销毁 ref——事务 await 完再 invalidate 就撞上已销毁的 ref,画布刷不出新链。控制器本身无状态,常驻代价可忽略。

另外不走 CanvasNodesController:它一次只建一个节点,也不参与事务。这里直接经 scope 写库,落地后 invalidate 节点与边两个控制器让内存态跟上(有专门用例断言这两次 invalidate 都发生了)。

测试

+18(1905 → 1923),0 失败:

  • script_import_controller_test.dart(10):链形状(N 节点 / N-1 边 / sortOrder)、落点与 origin 平移、单镜不自连、只开一个事务、空清单不开事务、节点建失败零残留建边失败零残留、双 invalidate
  • script_import_dialog_test.dart(6):空态禁用创建、预览实时显示镜数与逐镜标题、策略切换重算、成功建链 + 关对话框 + 提示、单镜路径、事务失败提示 + 无残留 + 对话框留着可重试
  • FAB / 空态各 +1 入口用例

本地闸:flutter analyze lib test → No issues;flutter test --exclude-tags golden → +1923 / 0 失败 / 66 skip。

披露

按会话约定,本 PR 跑双轨对抗式评审(/code-review 由用户触发,我无法自行发起)。golden 仍以 CI ubuntu 为准;本卡新增的都是对话框与菜单项,未改动任何 golden 覆盖的界面。

🤖 Generated with Claude Code

粘一段脚本进来,一键变成串好的分镜链。

- ScriptImportController:N 个 shot 节点 + N-1 条 narrative 边收进单个事务。
  半条链(几个散镜 + 几条边)比一个错误提示难收拾——用户既不知道哪几镜落地了,
  也没有一键撤销,所以失败必须零残留;用会真回滚的 fake UoW 兜住这条语义。
- 对话框:粘贴框 + 策略切换 + 实时预览(拆成几镜、每镜叫什么)。拆分规则再讲究
  也有猜错的时候,用户得先看见结果才敢按创建;切策略预览立刻重算。
- 入口:FAB 菜单「导入脚本…」+ 空态 CTA。第一镜落视口中心,后续每 260 排开。

两处坑记在 README:不走 CanvasNodesController(它一次只建一个节点、不入事务);
provider 不加 autoDispose(调用方只 read 不订阅,autoDispose 会在 await 后销毁 ref,
事务落地再 invalidate 就刷不出新链)。

测试 +18(1905 → 1923):链形状/落点/单事务/失败零残留/双 invalidate、预览实时性、
策略切换、成功与失败路径、两处入口。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@KerroKapple
KerroKapple merged commit 8502b26 into main Aug 10, 2026
5 checks passed
@KerroKapple
KerroKapple deleted the feat/sb-2-script-import branch August 10, 2026 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant