diff options
| author | Simon Orzel <simonorzel@gmail.com> | 2025-07-17 03:00:38 +0200 |
|---|---|---|
| committer | Simon Orzel <simonorzel@gmail.com> | 2025-07-17 03:00:38 +0200 |
| commit | 167f366c6d791dfc054d64f50e83828960668e55 (patch) | |
| tree | 28d6b037a2d0597990d290520a8265cca1ef66d7 /apps/web/src/components/editor/timeline/timeline-action-handlers.tsx | |
| parent | 1505c1b12f516c65b6a3d076f0e9623a294031d6 (diff) | |
| download | opencut-167f366c6d791dfc054d64f50e83828960668e55.tar.gz | |
feat: bunx biome format --write .
Diffstat (limited to 'apps/web/src/components/editor/timeline/timeline-action-handlers.tsx')
| -rw-r--r-- | apps/web/src/components/editor/timeline/timeline-action-handlers.tsx | 308 |
1 files changed, 154 insertions, 154 deletions
diff --git a/apps/web/src/components/editor/timeline/timeline-action-handlers.tsx b/apps/web/src/components/editor/timeline/timeline-action-handlers.tsx index c9560507..0e7323d3 100644 --- a/apps/web/src/components/editor/timeline/timeline-action-handlers.tsx +++ b/apps/web/src/components/editor/timeline/timeline-action-handlers.tsx @@ -4,175 +4,175 @@ import { useTimelineStore } from "@/stores/timeline-store"; import { usePlaybackStore } from "@/stores/playback-store"; export function useTimelineActionHandlers() { - const { - tracks, - addElementToTrack, - removeElementFromTrack, - selectedElements, - clearSelectedElements, - splitElement, - splitAndKeepLeft, - splitAndKeepRight, - separateAudio, - } = useTimelineStore(); - const { currentTime } = usePlaybackStore(); + const { + tracks, + addElementToTrack, + removeElementFromTrack, + selectedElements, + clearSelectedElements, + splitElement, + splitAndKeepLeft, + splitAndKeepRight, + separateAudio, + } = useTimelineStore(); + const { currentTime } = usePlaybackStore(); - // Create optimized lookup maps for O(1) access instead of O(n) find operations - const trackMap = useMemo(() => { - const map = new Map(); - tracks.forEach(track => { - map.set(track.id, track); - // Also create element lookup for this track - const elementMap = new Map(); - track.elements.forEach(element => { - elementMap.set(element.id, element); - }); - map.set(`${track.id}_elements`, elementMap); - }); - return map; - }, [tracks]); + // Create optimized lookup maps for O(1) access instead of O(n) find operations + const trackMap = useMemo(() => { + const map = new Map(); + tracks.forEach((track) => { + map.set(track.id, track); + // Also create element lookup for this track + const elementMap = new Map(); + track.elements.forEach((element) => { + elementMap.set(element.id, element); + }); + map.set(`${track.id}_elements`, elementMap); + }); + return map; + }, [tracks]); - // Helper function for O(1) track/element lookup - const findTrackAndElement = (trackId: string, elementId: string) => { - const track = trackMap.get(trackId); - const elementMap = trackMap.get(`${trackId}_elements`); - const element = elementMap?.get(elementId); - return { track, element }; - }; + // Helper function for O(1) track/element lookup + const findTrackAndElement = (trackId: string, elementId: string) => { + const track = trackMap.get(trackId); + const elementMap = trackMap.get(`${trackId}_elements`); + const element = elementMap?.get(elementId); + return { track, element }; + }; - // Action handlers for toolbar - const handleSplitSelected = () => { - if (selectedElements.length === 0) { - toast.error("No elements selected"); - return; - } - let splitCount = 0; - selectedElements.forEach(({ trackId, elementId }) => { - const { track, element } = findTrackAndElement(trackId, elementId); - if (element && track) { - const effectiveStart = element.startTime; - const effectiveEnd = - element.startTime + - (element.duration - element.trimStart - element.trimEnd); + // Action handlers for toolbar + const handleSplitSelected = () => { + if (selectedElements.length === 0) { + toast.error("No elements selected"); + return; + } + let splitCount = 0; + selectedElements.forEach(({ trackId, elementId }) => { + const { track, element } = findTrackAndElement(trackId, elementId); + if (element && track) { + const effectiveStart = element.startTime; + const effectiveEnd = + element.startTime + + (element.duration - element.trimStart - element.trimEnd); - if (currentTime > effectiveStart && currentTime < effectiveEnd) { - const newElementId = splitElement(trackId, elementId, currentTime); - if (newElementId) splitCount++; - } - } - }); - if (splitCount === 0) { - toast.error("Playhead must be within selected elements to split"); - } - }; + if (currentTime > effectiveStart && currentTime < effectiveEnd) { + const newElementId = splitElement(trackId, elementId, currentTime); + if (newElementId) splitCount++; + } + } + }); + if (splitCount === 0) { + toast.error("Playhead must be within selected elements to split"); + } + }; - const handleDuplicateSelected = () => { - if (selectedElements.length === 0) { - toast.error("No elements selected"); - return; - } - const canDuplicate = selectedElements.length === 1; - if (!canDuplicate) return; + const handleDuplicateSelected = () => { + if (selectedElements.length === 0) { + toast.error("No elements selected"); + return; + } + const canDuplicate = selectedElements.length === 1; + if (!canDuplicate) return; - selectedElements.forEach(({ trackId, elementId }) => { - const { element } = findTrackAndElement(trackId, elementId); + selectedElements.forEach(({ trackId, elementId }) => { + const { element } = findTrackAndElement(trackId, elementId); - if (element) { - const newStartTime = - element.startTime + - (element.duration - element.trimStart - element.trimEnd) + - 0.1; + if (element) { + const newStartTime = + element.startTime + + (element.duration - element.trimStart - element.trimEnd) + + 0.1; - // Create element without id (will be generated by store) - const { id, ...elementWithoutId } = element; + // Create element without id (will be generated by store) + const { id, ...elementWithoutId } = element; - addElementToTrack(trackId, { - ...elementWithoutId, - startTime: newStartTime, - }); + addElementToTrack(trackId, { + ...elementWithoutId, + startTime: newStartTime, + }); - // We can't predict the new id, so just clear selection for now - // TODO: addElementToTrack could return the new element id - } - }); + // We can't predict the new id, so just clear selection for now + // TODO: addElementToTrack could return the new element id + } + }); - clearSelectedElements(); - }; + clearSelectedElements(); + }; - const handleFreezeSelected = () => { - toast.info("Freeze frame functionality coming soon!"); - }; + const handleFreezeSelected = () => { + toast.info("Freeze frame functionality coming soon!"); + }; - const handleSplitAndKeepLeft = () => { - if (selectedElements.length !== 1) { - toast.error("Select exactly one element"); - return; - } - const { trackId, elementId } = selectedElements[0]; - const { element } = findTrackAndElement(trackId, elementId); - if (!element) return; - const effectiveStart = element.startTime; - const effectiveEnd = - element.startTime + - (element.duration - element.trimStart - element.trimEnd); - if (currentTime <= effectiveStart || currentTime >= effectiveEnd) { - toast.error("Playhead must be within selected element"); - return; - } - splitAndKeepLeft(trackId, elementId, currentTime); - }; + const handleSplitAndKeepLeft = () => { + if (selectedElements.length !== 1) { + toast.error("Select exactly one element"); + return; + } + const { trackId, elementId } = selectedElements[0]; + const { element } = findTrackAndElement(trackId, elementId); + if (!element) return; + const effectiveStart = element.startTime; + const effectiveEnd = + element.startTime + + (element.duration - element.trimStart - element.trimEnd); + if (currentTime <= effectiveStart || currentTime >= effectiveEnd) { + toast.error("Playhead must be within selected element"); + return; + } + splitAndKeepLeft(trackId, elementId, currentTime); + }; - const handleSplitAndKeepRight = () => { - if (selectedElements.length !== 1) { - toast.error("Select exactly one element"); - return; - } - const { trackId, elementId } = selectedElements[0]; - const { element } = findTrackAndElement(trackId, elementId); - if (!element) return; - const effectiveStart = element.startTime; - const effectiveEnd = - element.startTime + - (element.duration - element.trimStart - element.trimEnd); - if (currentTime <= effectiveStart || currentTime >= effectiveEnd) { - toast.error("Playhead must be within selected element"); - return; - } - splitAndKeepRight(trackId, elementId, currentTime); - }; + const handleSplitAndKeepRight = () => { + if (selectedElements.length !== 1) { + toast.error("Select exactly one element"); + return; + } + const { trackId, elementId } = selectedElements[0]; + const { element } = findTrackAndElement(trackId, elementId); + if (!element) return; + const effectiveStart = element.startTime; + const effectiveEnd = + element.startTime + + (element.duration - element.trimStart - element.trimEnd); + if (currentTime <= effectiveStart || currentTime >= effectiveEnd) { + toast.error("Playhead must be within selected element"); + return; + } + splitAndKeepRight(trackId, elementId, currentTime); + }; - const handleSeparateAudio = () => { - if (selectedElements.length !== 1) { - toast.error("Select exactly one media element to separate audio"); - return; - } - const { trackId, elementId } = selectedElements[0]; - const { track } = findTrackAndElement(trackId, elementId); - if (!track || track.type !== "media") { - toast.error("Select a media element to separate audio"); - return; - } - separateAudio(trackId, elementId); - }; + const handleSeparateAudio = () => { + if (selectedElements.length !== 1) { + toast.error("Select exactly one media element to separate audio"); + return; + } + const { trackId, elementId } = selectedElements[0]; + const { track } = findTrackAndElement(trackId, elementId); + if (!track || track.type !== "media") { + toast.error("Select a media element to separate audio"); + return; + } + separateAudio(trackId, elementId); + }; - const handleDeleteSelected = () => { - if (selectedElements.length === 0) { - toast.error("No elements selected"); - return; - } - selectedElements.forEach(({ trackId, elementId }) => { - removeElementFromTrack(trackId, elementId); - }); - clearSelectedElements(); - }; + const handleDeleteSelected = () => { + if (selectedElements.length === 0) { + toast.error("No elements selected"); + return; + } + selectedElements.forEach(({ trackId, elementId }) => { + removeElementFromTrack(trackId, elementId); + }); + clearSelectedElements(); + }; - return { - handleSplitSelected, - handleDuplicateSelected, - handleFreezeSelected, - handleSplitAndKeepLeft, - handleSplitAndKeepRight, - handleSeparateAudio, - handleDeleteSelected, - }; + return { + handleSplitSelected, + handleDuplicateSelected, + handleFreezeSelected, + handleSplitAndKeepLeft, + handleSplitAndKeepRight, + handleSeparateAudio, + handleDeleteSelected, + }; } |
