feat(timeline): copy / cut / paste clips (⌘C / ⌘X / ⌘V) (#94)#105
feat(timeline): copy / cut / paste clips (⌘C / ⌘X / ⌘V) (#94)#105cuic19053-hue wants to merge 3 commits into
Conversation
appergb
left a comment
There was a problem hiding this comment.
@cuic19053-hue 自动审核结论:请修改(REQUEST_CHANGES)。核心逻辑架构正确,但当前 CONFLICTING 无法合并:
阻塞项:
- 冲突,需 rebase:分支落后 main 39 个 commit,与 PR#102 在 web/src/store/editActions.ts import 段(第 12-16 行)真实三方冲突。请 rebase 到最新 main,保留两组 import(main 的 trimToPlayheadEdits/FrameRangeReq/KeyframePayloadReq/KeyframeProperty + 本 PR 的 useClipboardStore/Clip)后强推。
合并前请一并修(非阻塞但影响 1:1):
2. 粘贴视频时 addLinkedAudio 恒为 false → 复制带链接音轨的视频会丢音轨;上游 pasteClipsAtPlayhead 会做 linkGroup 重映(issue #94 亦点名此方案)。
3. 空剪贴板粘贴静默无反馈:已定义 i18n 键 edit.clipboardEmpty 但未接 toast。
rebase 后请自验 tsc + vitest 再提交。
Adds the standard clipboard shortcuts that were completely missing. Only
⌘C/⌘X/⌘V were absent — the unmodified C/V already switch tools (razor /
pointer), and the mod-prefixed branch had no handlers.
Frontend only:
- clipboardStore: new Zustand store holding deep snapshots of the selected
clips plus the source first-frame, so a paste can re-place the group
relative to the current playhead. UI-only, never persisted.
- editActions: copyClips / cutClips / pasteClipsAtPlayhead.
- copy: snapshot selected clips + their track index + min startFrame.
- cut: copy then deleteSelectedClips.
- paste: offset each clip's startFrame by `activeFrame - sourceFirstFrame`,
clear addLinkedAudio so the paste stands alone (mirrors upstream
`pasteClipsAtPlayhead` link re-reflection), and select the new clips.
Clips whose source track no longer exists are skipped.
- useKeyboardShortcuts: wire ⌘C / ⌘X / ⌘V inside the existing `if (mod)`
block — no conflict with the unmodified C/V tool switches.
- i18n: 4 new keys (zh-CN + en) for copy / cut / paste / clipboardEmpty.
Closes appergb#94.
…board toast Address review feedback on PR appergb#105: 1. Rebased onto latest main (resolved import conflict: kept both trimToPlayheadEdits and useClipboardStore). 2. copyClips now expands link groups: if a selected clip has a linkGroupId, all linked companions are included in the clipboard (mirrors upstream copyClips), so a paste reproduces the video+audio pair. 3. pasteClipsAtPlayhead now re-establishes link groups after addClips: clips that shared a linkGroupId in the clipboard are re-linked via linkClips, preserving video+audio linkage. 4. Empty-clipboard paste now shows a toast (edit.clipboardEmpty) instead of silently doing nothing. Added toast mechanism to uiStore + Toast component in App.tsx.
fa27d06 to
3192a2e
Compare
|
Rebased onto latest main and addressed all review feedback. Ready for re-review. Changes:
\pnpm run build\ (tsc -b + vite build) passes. |
appergb
left a comment
There was a problem hiding this comment.
@cuic19053-hue 复审 ✅ 你的修复方向正确,已逐一回应上轮反馈:
- 空剪贴板提示:uiStore 加
pushToast/clearToast+ App.tsx Toast 组件,粘贴空时pushToast(t("edit.clipboardEmpty")),死键已消费。✔ - linkGroup 重映射:
copyClips展开链接伴随、pasteClipsAtPlayhead用sourceLinkGroups对齐res.affectedClipIds建newGroupMap再linkClips重链,addLinkedAudio:false避免重复音轨——粘贴 A/V 链接对会成对保留。✔ 贴近上游 pasteClipsAtPlayhead。
editActions.ts 并新增 keyframe 函数 + dict.ts 新增键)。请再 rebase 一次到最新 main,在 editActions.ts/dict.ts 保留两边(你的 clipboard 函数 + #119 的 keyframe 函数/键)。
💡 一处建议(非阻塞,请确认):linkGroup 重映依赖 res.affectedClipIds[i] 与输入 entries[i] 同序对齐。若 addClips/后端不保证返回顺序与输入一致,重链可能配错对。建议确认 addClips 保序,或改用更稳的映射(如按返回里携带的 source 标识匹配)。
rebase + CI 双绿后我会做最终审核 + 合并。👍
…0624 # Conflicts: # web/src/i18n/dict.ts
appergb
left a comment
There was a problem hiding this comment.
✅ 批准(Sonnet 4.6 复审 + 主控自查)。前两轮的阻塞项已在当前 diff 中切实修复:
- 链接组重映射已修:
copyClips把链接伴随 clip 一并纳入剪贴板;pasteClipsAtPlayhead以sourceLinkGroups[]与affectedClipIds[]按序对齐、对每组linkClips重建链接,addLinkedAudio:false避免重复音轨——语义等价上游EditorViewModel+Clipboard.swift的 group remap。 - 空剪贴板反馈已补:⌘V 路径在剪贴板为空时
pushToast(t("edit.clipboardEmpty"));uiStore 加 toast/pushToast/clearToast + App.tsx Toast 组件,链路完整。 - rebase/冲突已解:已合 origin/main,
mergeable:MERGEABLE,CI 双绿(Rust + Web)。
改动文件均在剪辑/UI 层(editActions/clipboardStore/uiStore/useKeyboardShortcuts/App/dict),不碰 #91 媒体重写区;对 TimelinePlaybackLayer.tsx 仅删一个尾随空格,无逻辑影响。粘贴偏移用 sourceTrackIndex + (activeFrame - sourceFirstFrame) 与上游相对偏移路径不同但语义等价,属可接受的 1:1 复刻。
已具备合并条件(待 owner 决定 --admin 合并)。
|
@appergb 本 PR 已 APPROVED + CLEAN + CI 双绿(Rust ✅ Web ✅),可合并。贡献者账号无 MergePullRequest 权限,烦请 owner 执行 merge(squash),谢谢! |
Summary
Adds the standard copy / cut / paste clipboard shortcuts (⌘C / ⌘X / ⌘V) that were completely missing. Closes #94.
Changes
web/src/store/clipboardStore.ts(new) — Zustand store holding deep snapshots of the selected clips plus the source first-frame, so a paste can re-place the group relative to the current playhead. UI-only, never persisted.web/src/store/editActions.ts—copyClips/cutClips/pasteClipsAtPlayhead:startFrame.deleteSelectedClips.startFramebyactiveFrame - sourceFirstFrame, clearaddLinkedAudioso the paste stands alone (mirrors upstreampasteClipsAtPlayheadlink re-reflection), and select the new clips. Clips whose source track no longer exists are skipped.addClipsnow returns theEditResultso paste can readaffectedClipIds.web/src/hooks/useKeyboardShortcuts.ts— wire ⌘C / ⌘X / ⌘V inside the existingif (mod)block. No conflict with the unmodified C/V tool switches (those are in the separate no-mod branch).web/src/i18n/dict.ts— 4 new keys (zh-CN + en):edit.copy/edit.cut/edit.paste/edit.clipboardEmpty.Verification
pnpm tsc --noEmit✅pnpm build✅ (1640 modules, 5.81s)User flow
Notes
addLinkedAudioso the new clips don't re-link to the originals. The backend assigns fresh link groups on demand.addClips/removeClipscommands.