diff options
author | Michael Foiani <sotech117@Michaels-MacBook-Pro-5.local> | 2022-06-09 18:15:36 -0400 |
---|---|---|
committer | Michael Foiani <sotech117@Michaels-MacBook-Pro-5.local> | 2022-06-09 18:15:36 -0400 |
commit | a2c3ed470c941b108aede045ac294e3b966990bc (patch) | |
tree | 3f16e451311e5ede6ae5654890ac240b58b2a50a /src | |
parent | 0badf084bed0f5337cbf9ad89f1fea924481c9b0 (diff) |
more comments + testing
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/nodes/RecordingBox/ProgressBar.tsx | 63 |
1 files changed, 37 insertions, 26 deletions
diff --git a/src/client/views/nodes/RecordingBox/ProgressBar.tsx b/src/client/views/nodes/RecordingBox/ProgressBar.tsx index 131d5c837..dfe57db3f 100644 --- a/src/client/views/nodes/RecordingBox/ProgressBar.tsx +++ b/src/client/views/nodes/RecordingBox/ProgressBar.tsx @@ -25,15 +25,17 @@ interface CurrentHover { } export function ProgressBar(props: ProgressBarProps) { - const progressBarRef = useRef<HTMLDivElement | null>(null) - // array for the order of video segments + // the actual list of JSX elements rendered as segments const [segments, setSegments] = useState<JSX.Element[]>([]); + // array for the order of video segments const [ordered, setOrdered] = useState<SegmentBox[]>([]); const [undoStack, setUndoStack] = useState<SegmentBox[]>([]); + // -1 if no segment is currently being dragged around; else, it is the id of that segment over + // NOTE: the id of a segment is its index in the ordered array const [dragged, setDragged] = useState<number>(-1); // length of the time removed from the video, in seconds*100 @@ -42,10 +44,11 @@ export function ProgressBar(props: ProgressBarProps) { // this holds the index of the videoc segment to be removed const [removed, setRemoved] = useState<number>(-1); + // update the canUndo props based on undo stack useEffect(() => props.setCanUndo?.(undoStack.length > 0), [undoStack.length]); - - // abstracted for other uses - brings back the most recently deleted segment + // useEffect for undo - brings back the most recently deleted segment + useEffect(() => handleUndo(), [props.doUndo]) const handleUndo = () => { // get the last element from the undo if it exists if (undoStack.length === 0) return; @@ -57,18 +60,20 @@ export function ProgressBar(props: ProgressBarProps) { setTotalRemovedTime(prevRemoved => prevRemoved - (last.endTime - last.startTime)); setOrdered(prevOrdered => [...prevOrdered, last]); } - useEffect(() => handleUndo(), [props.doUndo]) + // useEffect for recording changes - changes style to disabled and adds the "expanding-segment" useEffect(() => { // get segments segment's html using it's id -> make them appeared disabled (or enabled) segments.forEach((seg) => document.getElementById(seg.props.id)?.classList.toggle('segment-disabled', props.recording)); progressBarRef.current?.classList.toggle('progressbar-disabled', props.recording); if (props.recording) - setSegments(prevSegments => [...prevSegments, <div key='segment-expanding' id='segment-expanding' className='segment segment-expanding blink' style={{ width: 'min-content' }}>{props.videos.length + 1}</div>]); + setSegments(prevSegments => [...prevSegments, <div key='segment-expanding' id='segment-expanding' className='segment segment-expanding blink' style={{ width: '0px;' }}>{props.videos.length + 1}</div>]); }, [props.recording]) + // useEffect that updates the segmentsJSX, which is rendered + // only updated when ordered is updated or if the user is dragging around a segment useEffect(() => { const totalTime = props.progress * 1000 - totalRemovedTime; const segmentsJSX = ordered.map((seg, i) => @@ -77,12 +82,12 @@ export function ProgressBar(props: ProgressBarProps) { setSegments(segmentsJSX) }, [dragged, ordered]); - // update the cursor to be dragging while moving the floating segment + // useEffect for dragged - update the cursor to be grabbing while grabbing useEffect(() => { progressBarRef.current?.classList.toggle('progressbar-dragging', dragged !== -1); }, [dragged]); - // to imporve performance, we only want to update the width, not re-render the whole thing + // to imporve performance, only want to update the CSS width, not re-render the whole JSXList useEffect(() => { if (!props.recording) return const totalTime = props.progress * 1000 - totalRemovedTime; @@ -103,11 +108,9 @@ export function ProgressBar(props: ProgressBarProps) { const segExapandHtml = document.getElementById('segment-expanding'); if (segExapandHtml) segExapandHtml.style.width = ordered.length === 0 ? '100%' : `${(remainingTime / totalTime) * 100}%`; - }, [props.progress]); - - + // useEffect for props.videos - update the ordered array when a new video is added useEffect(() => { // this useEffect fired when the videos are being rearragned to the order // in this case, do nothing. @@ -128,10 +131,10 @@ export function ProgressBar(props: ProgressBarProps) { } }, [props.videos]); - useEffect(() => { - props.setVideos(vids => ordered.map((seg) => vids[seg.order])); - }, [props.orderVideos]); + // useEffect for props.orderVideos - matched the order array with the videos array before the export + useEffect(() => props.setVideos(vids => ordered.map((seg) => vids[seg.order])), [props.orderVideos]); + // useEffect for removed - handles logic for removing a segment useEffect(() => { if (removed === -1) return; // update total removed time @@ -145,6 +148,7 @@ export function ProgressBar(props: ProgressBarProps) { setRemoved(-1); }, [removed]); + // returns the new currentHover based on the new index const updateCurrentHover = (segId: number): CurrentHover | null => { // get the segId of the segment that will become the new bounding area const rect = progressBarRef.current?.children[segId].getBoundingClientRect() @@ -156,6 +160,7 @@ export function ProgressBar(props: ProgressBarProps) { } } + // pointerdown event for the progress bar const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => { // don't move the videobox element e.stopPropagation() @@ -174,16 +179,18 @@ export function ProgressBar(props: ProgressBarProps) { // if holding shift key, let's remove that segment if (e.shiftKey) { const segId = parseInt(clickedSegment.id.split('-')[1]); - console.log('removing segment shift', segId); setRemoved(segId); return } + // if holding ctrl key and click, let's undo that segment #hiddenfeature lol if (e.ctrlKey) { handleUndo(); return; } + // if we're here, the user is dragging a segment around + // let the progress bar capture all the pointer events until the user releases (pointerUp) const ptrId = e.pointerId; progressBar.setPointerCapture(ptrId) @@ -194,15 +201,15 @@ export function ProgressBar(props: ProgressBarProps) { // set the selected segment to be the one dragged setDragged(segId) - // this is the logic for storing the lower X bound and upper X bound - // to know whether a swap is needed between two segments + // this is the logic for storing the lower X bound and upper X bound to know + // whether a swap is needed between two segments let currentHover: CurrentHover = { index: segId, minX: rect.x, maxX: rect.x + rect.width, } - // create the div element that tracks the cursor + // create the floating segment that tracks the cursor const detchedSegment = document.createElement("div") initDeatchSegment(detchedSegment, rect); @@ -219,16 +226,19 @@ export function ProgressBar(props: ProgressBarProps) { followCursor(event, detchedSegment); const curX = event.clientX; + // handle the left bound if (curX < currentHover.minX && currentHover.index > 0) { swapSegments(currentHover.index, currentHover.index - 1) currentHover = updateCurrentHover(currentHover.index - 1) ?? currentHover } + // handle the right bound else if (curX > currentHover.maxX && currentHover.index < segments.length - 1) { swapSegments(currentHover.index, currentHover.index + 1) currentHover = updateCurrentHover(currentHover.index + 1) ?? currentHover } } + // handles when the user is done dragging the segment (pointerUp) const placeSegmentandCleanup = (event?: PointerEvent): void => { event?.stopPropagation(); event?.preventDefault(); @@ -245,22 +255,23 @@ export function ProgressBar(props: ProgressBarProps) { setDragged(-1); } + // event listeners that allow the user to drag and release the floating segment progressBar.addEventListener('pointermove', updateSegmentOrder); progressBar.addEventListener('pointerup', placeSegmentandCleanup, { once: true }); } const swapSegments = (oldIndex: number, newIndex: number) => { - if (newIndex == null) return + if (newIndex == null) return; setOrdered(prevOrdered => { - const cpy = [...prevOrdered] - cpy[oldIndex] = cpy[newIndex] - cpy[newIndex] = prevOrdered[oldIndex] - return cpy - }) - setDragged(newIndex) + const temp = { ...prevOrdered[oldIndex] } + prevOrdered[oldIndex] = prevOrdered[newIndex] + prevOrdered[newIndex] = temp + return prevOrdered + }); + // update visually where the segment is hovering over + setDragged(newIndex); } - // functions for the floating segment that tracks the cursor while grabbing it const initDeatchSegment = (dot: HTMLDivElement, rect: DOMRect) => { dot.classList.add("segment-selected"); |