diff --git a/chap4_proj/chapter_04_santuary.aive b/chap4_proj/chapter_04_santuary.aive index 4fddda5..519365e 100644 --- a/chap4_proj/chapter_04_santuary.aive +++ b/chap4_proj/chapter_04_santuary.aive @@ -44497,23 +44497,33 @@ "cutRanges": [ { "id": "cut_1", - "start": 554.9, + "start": 553.4962968404622, + "end": 561.6 + }, + { + "id": "cut_1", + "start": 553.4962968404622, "end": 561.6 } ], "muteRanges": [ { "id": "mute_2", - "start": 563.72, + "start": 563.1481209350031, "end": 571.5 }, { "id": "mute_3", "start": 34.98, "end": 50.14 + }, + { + "id": "mute_2", + "start": 563.1481209350031, + "end": 571.5 } ], "language": "en", - "createdAt": "2026-04-03T17:11:13.537Z", - "modifiedAt": "2026-04-03T17:11:13.537Z" + "createdAt": "2026-04-03T17:38:19.689Z", + "modifiedAt": "2026-04-03T17:38:19.689Z" } \ No newline at end of file diff --git a/frontend/src/components/WaveformTimeline.tsx b/frontend/src/components/WaveformTimeline.tsx index e90bf44..d32759d 100644 --- a/frontend/src/components/WaveformTimeline.tsx +++ b/frontend/src/components/WaveformTimeline.tsx @@ -695,6 +695,11 @@ export default function WaveformTimeline({ cutMode, muteMode }: { cutMode: boole // Handle keyboard shortcuts for zone editing useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { + const target = e.target as HTMLElement | null; + if (target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.tagName === 'SELECT')) { + return; + } + if (e.key === 'Escape') { setSelectedZone(null); setEditingZone(null); @@ -702,6 +707,8 @@ export default function WaveformTimeline({ cutMode, muteMode }: { cutMode: boole } else if (e.key === 'Delete' || e.key === 'Backspace') { if (selectedZone) { e.preventDefault(); + e.stopPropagation(); + e.stopImmediatePropagation(); if (selectedZone.type === 'cut') { removeCutRange(selectedZone.id); } else { @@ -714,8 +721,9 @@ export default function WaveformTimeline({ cutMode, muteMode }: { cutMode: boole } }; - window.addEventListener('keydown', handleKeyDown); - return () => window.removeEventListener('keydown', handleKeyDown); + // Capture phase ensures zone delete runs before app-level bubble shortcuts. + window.addEventListener('keydown', handleKeyDown, { capture: true }); + return () => window.removeEventListener('keydown', handleKeyDown, { capture: true }); }, [selectedZone, removeCutRange, removeMuteRange]); if (!videoUrl) {