diff options
| author | melad <meladnaieem@yahoo.com> | 2025-07-31 13:50:22 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-31 12:50:22 +0200 |
| commit | f255ccb818358b90edd0c1bc1f3a690dc1e729ac (patch) | |
| tree | 8c2a0503d591d24edaa6cd0eeea5f152397f6bd3 /apps/web/src/components/editor/timeline/timeline-element.tsx | |
| parent | b229d94a8da7b258f1b49867e8cee225d5feb735 (diff) | |
| download | opencut-f255ccb818358b90edd0c1bc1f3a690dc1e729ac.tar.gz | |
feat: add hide or show for media elements, mute or unmute for audio elements (#500)
* feat: create external tools section (#493)
* feat: create external tools section
* fix: better wording
* Feature, added hide or show for media elements, mute or unmute for audio elements both effective on timeline and preview panel, with overlay icon for indicating so and state storing,
* Minor UI vertical separator between magnifier and other buttons
* fixed the AbortError issue in the AudioWaveform component. The error was occurring because of a race condition during cleanup when the component unmounts.
* feat: implement bookmarking functionality in the timeline and project storage
- Added bookmark management methods in the project store for toggling and checking bookmarks.
- Updated the timeline component to display bookmark markers and integrate bookmark actions in the context menu.
- Enhanced the storage service to handle bookmarks in project serialization and deserialization.
- Updated project types to include bookmarks as an array of numbers.
---------
Co-authored-by: Dominik K. <dominik@koch-bautechnik.de>
Co-authored-by: Maze Winther <mazewinther@gmail.com>
Diffstat (limited to 'apps/web/src/components/editor/timeline/timeline-element.tsx')
| -rw-r--r-- | apps/web/src/components/editor/timeline/timeline-element.tsx | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/apps/web/src/components/editor/timeline/timeline-element.tsx b/apps/web/src/components/editor/timeline/timeline-element.tsx index f581bbf0..96859c38 100644 --- a/apps/web/src/components/editor/timeline/timeline-element.tsx +++ b/apps/web/src/components/editor/timeline/timeline-element.tsx @@ -13,6 +13,10 @@ import { Type, Copy, RefreshCw, + EyeOff, + Eye, + Volume2, + VolumeX, } from "lucide-react"; import { useMediaStore } from "@/stores/media-store"; import { useTimelineStore } from "@/stores/timeline-store"; @@ -66,11 +70,18 @@ export function TimelineElement({ addElementToTrack, replaceElementMedia, rippleEditingEnabled, + toggleElementHidden, } = useTimelineStore(); const { currentTime } = usePlaybackStore(); const [elementMenuOpen, setElementMenuOpen] = useState(false); + const mediaItem = + element.type === "media" + ? mediaItems.find((item) => item.id === element.mediaId) + : null; + const isAudio = mediaItem?.type === "audio"; + const { resizing, isResizing, @@ -141,6 +152,11 @@ export function TimelineElement({ } }; + const handleToggleElementHidden = (e: React.MouseEvent) => { + e.stopPropagation(); + toggleElementHidden(track.id, element.id); + }; + const handleReplaceClip = (e: React.MouseEvent) => { e.stopPropagation(); if (element.type !== "media") { @@ -332,7 +348,7 @@ export function TimelineElement({ track.type )} ${isSelected ? "border-b-[0.5px] border-t-[0.5px] border-foreground" : ""} ${ isBeingDragged ? "z-50" : "z-10" - }`} + } ${element.hidden ? "opacity-50" : ""}`} onClick={(e) => onElementClick && onElementClick(e, element)} onMouseDown={handleElementMouseDown} onContextMenu={(e) => @@ -343,6 +359,16 @@ export function TimelineElement({ {renderElementContent()} </div> + {element.hidden && ( + <div className="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center pointer-events-none"> + {isAudio ? ( + <VolumeX className="h-6 w-6 text-white" /> + ) : ( + <EyeOff className="h-6 w-6 text-white" /> + )} + </div> + )} + {isSelected && ( <> <div @@ -363,6 +389,29 @@ export function TimelineElement({ <Scissors className="h-4 w-4 mr-2" /> Split at playhead </ContextMenuItem> + <ContextMenuItem onClick={handleToggleElementHidden}> + {isAudio ? ( + element.hidden ? ( + <Volume2 className="h-4 w-4 mr-2" /> + ) : ( + <VolumeX className="h-4 w-4 mr-2" /> + ) + ) : element.hidden ? ( + <Eye className="h-4 w-4 mr-2" /> + ) : ( + <EyeOff className="h-4 w-4 mr-2" /> + )} + <span> + {isAudio + ? element.hidden + ? "Unmute" + : "Mute" + : element.hidden + ? "Show" + : "Hide"}{" "} + {element.type === "text" ? "text" : "clip"} + </span> + </ContextMenuItem> <ContextMenuItem onClick={handleElementDuplicateContext}> <Copy className="h-4 w-4 mr-2" /> Duplicate {element.type === "text" ? "text" : "clip"} |
