From bfeb6d391f35a6600a58fe76afc6b365e1faf5a0 Mon Sep 17 00:00:00 2001 From: wil Date: Wed, 6 Mar 2024 13:22:00 -0500 Subject: [PATCH 01/13] scrubber is now an HOC --- .../common/VideoQuickTrim/TrimScrubber.tsx | 115 ++++-------------- .../common/VideoQuickTrim/VideoQuickTrim.tsx | 6 +- .../common/VideoQuickTrim/styles.scss | 3 - .../common/VideoQuickTrim/withScrubbing.tsx | 93 ++++++++++++++ 4 files changed, 121 insertions(+), 96 deletions(-) create mode 100644 packages/fakeyou.com/src/components/common/VideoQuickTrim/withScrubbing.tsx diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx index b5fb2672af..78c93d6d92 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx @@ -1,101 +1,36 @@ -import React, { - useRef, - useState, - PointerEvent -} from 'react'; +import React from 'react'; import { faGripDots } from "@fortawesome/pro-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { QuickTrimData } from './types'; +import {withScrubbing, withScrubbingPropsI} from './withScrubbing'; -export default function TrimScrubber({ - trimStart, - trimDuration, - duration, - width, - boundingWidth, - onChange -}:{ +interface TrimScrubberPropsI extends withScrubbingPropsI { trimStart:number; trimDuration: number; duration: number; - boundingWidth: number; - width:number; onChange:(val:QuickTrimData)=>void -}){ - const [{ - left, - leftOffset, - pointerStart - }, setState] = useState<{ - left: number, - leftOffset:number - pointerStart:number - }>({ - left: trimStart/duration*boundingWidth, - leftOffset: trimStart/duration*boundingWidth, - pointerStart: -1 - }); - const ref = useRef(null); - - if(ref.current){ - ref.current.style.cursor = pointerStart >= 0 - ? 'grabbing' : 'grab'; - } - - function handleScrubStart(e: PointerEvent){ - e.persist(); - // console.log(`start: ${pointerStart}` ); - setState((curr)=>({ - ...curr, - pointerStart: e.clientX - })); - } - function handleScrubEnd(e: PointerEvent){ - e.persist(); - // console.log(`end` ); - setState((curr)=>({ - ...curr, - pointerStart: -1, - leftOffset: left, - })); - console.log(`${duration} * ${left} / ${boundingWidth} = ${duration * left / boundingWidth}`) - onChange(({ - trimStartSeconds: duration * left / boundingWidth, - trimEndSeconds: duration * left / boundingWidth + trimDuration, - })) - } - function handleScrubMove(e: PointerEvent){ - e.persist(); - if(pointerStart >= 0 && pointerStart!==null && ref.current){ - // console.log(`${e.clientX} - ${pointerStart} = ${e.clientX-pointerStart}`) - let newLeft = leftOffset + e.clientX - pointerStart; - // console.log(`${newLeft} + ${boundingWidth * widthPercent/100} > ${boundingWidth}`) - if (newLeft + width > boundingWidth) { - newLeft = boundingWidth - width; - }else if(newLeft < 0) { - newLeft = 0; - } - setState((curr)=>({ - ...curr, - left: newLeft - })); - } - } - return( -
- -
- ); } +export const TrimScrubber = (props:TrimScrubberPropsI)=>{ + + const TrimScrubberWithScrubbing = + withScrubbing(() => { + return( +
+ +
+ ); + }); + + return ( + + ) +} + + diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx index 6f62433ba3..1658d91220 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx @@ -18,7 +18,7 @@ import { VideoFakeyouProps } from "../VideoFakeyou/VideoFakeyou"; import { QuickTrimData, TrimStates, PlaybarStates } from "./types"; import { formatSecondsToHHMMSSCS } from "./helpers"; -import TrimScrbber from "./TrimScrubber"; +import {TrimScrubber} from "./TrimScrubber"; import './styles.scss' interface VideoQuickTrimProps extends VideoFakeyouProps { @@ -225,10 +225,10 @@ export default memo(function VideoQuickTrim({ {trimScrubberWidth > 0 && playbarWidth > 0 && maxDuration > 0 && - number; //return scrubber location as % + onScrubChanges?: ()=>number; //return scrubber location as % +} +type withSrcubbingStates = { + currLeftOffset: number, + prevLeftOffset: number; + pointerStartPos: number; +} + +export const withScrubbing =

(Component: React.ComponentType

) => ({ + boundingWidth, + scrubberWidth, + styleOverride = {}, + onScrubEnds, + onScrubChanges, + ...rest +}: withScrubbingPropsI) => { + // return (props: Omit)=>{ + const ref = useRef(null) + const [{ + currLeftOffset, prevLeftOffset, pointerStartPos + }, setStates] = useState({ + currLeftOffset: 0, // in pixels + prevLeftOffset: 0, //in pixels + pointerStartPos: -1 // negative denotes pointer not engaged + }); + + function handleScrubStart(e: PointerEvent){ + e.persist(); + console.log(`start: ${pointerStartPos} -> ${e.clientX}` ); + setStates((curr)=>({ + ...curr, + pointerStartPos: e.clientX + })); + } + function handleScrubEnd(e: PointerEvent){ + e.persist(); + console.log(`end` ); + setStates((curr)=>({ + ...curr, + pointerStartPos: -1, + prevLeftOffset: currLeftOffset, + })); + } + function handleScrubMove(e: PointerEvent){ + e.persist(); + if(pointerStartPos >= 0 && pointerStartPos!==null){ + let newLeftOffset = prevLeftOffset + e.clientX - pointerStartPos; + if (newLeftOffset + scrubberWidth > boundingWidth) { + newLeftOffset = boundingWidth - scrubberWidth; + }else if(newLeftOffset < 0) { + newLeftOffset = 0; + } + setStates((curr)=>({ + ...curr, + currLeftOffset: newLeftOffset + })); + } + } + return( +

=0 ? 'grabbing': 'grab', + ...styleOverride + }} + onPointerDown={handleScrubStart} + onPointerUp={handleScrubEnd} + onPointerLeave={handleScrubEnd} + onPointerMove={handleScrubMove} + > + +
+ ); +// } +}; From 2702ff838d0a783b446d6a3ccb52aa058934a493 Mon Sep 17 00:00:00 2001 From: wil Date: Wed, 6 Mar 2024 15:41:33 -0500 Subject: [PATCH 02/13] events now bind to window --- .../common/VideoQuickTrim/TrimScrubber.tsx | 28 +++-- .../common/VideoQuickTrim/VideoQuickTrim.tsx | 4 +- .../common/VideoQuickTrim/withScrubbing.tsx | 100 ++++++++++++------ 3 files changed, 91 insertions(+), 41 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx index 78c93d6d92..129485514b 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx @@ -1,4 +1,7 @@ -import React from 'react'; +import React, { + memo, + useCallback +} from 'react'; import { faGripDots } from "@fortawesome/pro-solid-svg-icons"; @@ -12,8 +15,13 @@ interface TrimScrubberPropsI extends withScrubbingPropsI { duration: number; onChange:(val:QuickTrimData)=>void } -export const TrimScrubber = (props:TrimScrubberPropsI)=>{ - +export const TrimScrubber = memo(({ + trimStart, + trimDuration, + duration, + onChange, + ...rest +}:TrimScrubberPropsI)=>{ const TrimScrubberWithScrubbing = withScrubbing(() => { return( @@ -22,15 +30,23 @@ export const TrimScrubber = (props:TrimScrubberPropsI)=>{ ); }); - + + const handleOnChange = useCallback((posPercent:number)=>{ + onChange({ + trimStartSeconds: duration * posPercent, + trimEndSeconds: duration * posPercent + trimDuration, + }); + }, [onChange]) return ( ) -} +}); diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx index 1658d91220..f4bde41c1b 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx @@ -226,8 +226,8 @@ export default memo(function VideoQuickTrim({ playbarWidth > 0 && maxDuration > 0 && number; //return scrubber location as % - onScrubChanges?: ()=>number; //return scrubber location as % + onScrubEnds?: (posPercent: number)=>void; + //return scrubber location as %, where 0 < % < 1 + onScrubChanges?: (posPercent:number)=>void; + //return scrubber location as %, where 0 < % < 1 } + type withSrcubbingStates = { + key: Date, currLeftOffset: number, prevLeftOffset: number; pointerStartPos: number; @@ -20,56 +27,87 @@ type withSrcubbingStates = { export const withScrubbing =

(Component: React.ComponentType

) => ({ boundingWidth, scrubberWidth, + initialLeftOffset : initialLeftOffsetProps = 0, + initialLeftOffsetPercent = 0, styleOverride = {}, onScrubEnds, onScrubChanges, ...rest }: withScrubbingPropsI) => { - // return (props: Omit)=>{ - const ref = useRef(null) + console.log('withScrubbing reRender'); + // const initialLeftOffset = + // initialLeftOffsetPercent > 0 ? boundingWidth * initialLeftOffsetPercent + // : initialLeftOffsetProps; + const initialLeftOffset = 0; const [{ - currLeftOffset, prevLeftOffset, pointerStartPos + key, currLeftOffset, pointerStartPos + // prevLeftOffset, }, setStates] = useState({ - currLeftOffset: 0, // in pixels - prevLeftOffset: 0, //in pixels + key: new Date(), + currLeftOffset: initialLeftOffset, // in pixels + prevLeftOffset: initialLeftOffset, //in pixels pointerStartPos: -1 // negative denotes pointer not engaged }); - function handleScrubStart(e: PointerEvent){ - e.persist(); + function handleScrubStart (e: PointerEvent){ + // e.persist(); + e.preventDefault(); + e.stopPropagation(); console.log(`start: ${pointerStartPos} -> ${e.clientX}` ); setStates((curr)=>({ ...curr, pointerStartPos: e.clientX })); } - function handleScrubEnd(e: PointerEvent){ - e.persist(); - console.log(`end` ); + const handleScrubEnd = useCallback((e: MouseEvent)=>{ + // e.persist(); + e.preventDefault(); + e.stopPropagation(); setStates((curr)=>({ ...curr, pointerStartPos: -1, - prevLeftOffset: currLeftOffset, + prevLeftOffset: curr.currLeftOffset, })); - } - function handleScrubMove(e: PointerEvent){ - e.persist(); - if(pointerStartPos >= 0 && pointerStartPos!==null){ - let newLeftOffset = prevLeftOffset + e.clientX - pointerStartPos; - if (newLeftOffset + scrubberWidth > boundingWidth) { - newLeftOffset = boundingWidth - scrubberWidth; - }else if(newLeftOffset < 0) { - newLeftOffset = 0; + // if (onScrubEnds) onScrubEnds(currLeftOffset/boundingWidth); + }, []); + const handleScrubMove = useCallback ((e: MouseEvent)=>{ + // e.persist(); + e.preventDefault(); + e.stopPropagation(); + setStates((curr)=>{ + if(curr.pointerStartPos >= 0 && curr.pointerStartPos!==null){ + let newLeftOffset = curr.prevLeftOffset + e.clientX - curr.pointerStartPos; + if (newLeftOffset + scrubberWidth > boundingWidth) { + newLeftOffset = boundingWidth - scrubberWidth; + }else if(newLeftOffset < 0) { + newLeftOffset = 0; + } + if(newLeftOffset !== curr.currLeftOffset){ + return{ + ...curr, + currLeftOffset: newLeftOffset + } + } } - setStates((curr)=>({ - ...curr, - currLeftOffset: newLeftOffset - })); + return curr; + }); + // if (onScrubChanges) onScrubChanges(newLeftOffset/boundingWidth); + },[scrubberWidth, boundingWidth]); + + useLayoutEffect(() => { + if(!(window as any)[`${key}listenders`]){ + (window as any)[`${key}listenders`] = true; + window.addEventListener("pointerup", handleScrubEnd); + window.addEventListener("pointermove", handleScrubMove); + return () => { + (window as any)[`${key}listenders`] = false; + window.removeEventListener("pointerup", handleScrubEnd); + window.removeEventListener("pointermove", handleScrubMove); + }; } - } + }, [handleScrubEnd, handleScrubMove, key]); return(

(Component: React.Co ...styleOverride }} onPointerDown={handleScrubStart} - onPointerUp={handleScrubEnd} - onPointerLeave={handleScrubEnd} - onPointerMove={handleScrubMove} >
); -// } }; From b6cfce44058c86d4e7c1ea79934f1ef56236c253 Mon Sep 17 00:00:00 2001 From: wil Date: Wed, 6 Mar 2024 16:03:39 -0500 Subject: [PATCH 03/13] smoothest scrubbing by far --- .../common/VideoQuickTrim/withScrubbing.tsx | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/withScrubbing.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/withScrubbing.tsx index 7e30152aab..4ccd831953 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/withScrubbing.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/withScrubbing.tsx @@ -1,8 +1,8 @@ import React,{ + useRef, useState, useLayoutEffect, useCallback, - PointerEvent, } from 'react'; export interface withScrubbingPropsI { @@ -35,6 +35,7 @@ export const withScrubbing =

(Component: React.Co ...rest }: withScrubbingPropsI) => { console.log('withScrubbing reRender'); + const refEl = useRef(null); // const initialLeftOffset = // initialLeftOffsetPercent > 0 ? boundingWidth * initialLeftOffsetPercent // : initialLeftOffsetProps; @@ -49,16 +50,18 @@ export const withScrubbing =

(Component: React.Co pointerStartPos: -1 // negative denotes pointer not engaged }); - function handleScrubStart (e: PointerEvent){ - // e.persist(); - e.preventDefault(); - e.stopPropagation(); - console.log(`start: ${pointerStartPos} -> ${e.clientX}` ); - setStates((curr)=>({ - ...curr, - pointerStartPos: e.clientX - })); - } + const handleScrubStart = useCallback( (e: MouseEvent) => { + if(refEl.current){ + console.log(`start: ${e.clientX}` ); + if(refEl.current.contains(e.target as Node)){ + setStates((curr)=>({ + ...curr, + pointerStartPos: e.clientX + })); + return true; + } + } + },[]); const handleScrubEnd = useCallback((e: MouseEvent)=>{ // e.persist(); e.preventDefault(); @@ -97,18 +100,21 @@ export const withScrubbing =

(Component: React.Co useLayoutEffect(() => { if(!(window as any)[`${key}listenders`]){ (window as any)[`${key}listenders`] = true; - window.addEventListener("pointerup", handleScrubEnd); - window.addEventListener("pointermove", handleScrubMove); + window.addEventListener("mousedown", handleScrubStart); + window.addEventListener("mouseup", handleScrubEnd); + window.addEventListener("mousemove", handleScrubMove); return () => { (window as any)[`${key}listenders`] = false; - window.removeEventListener("pointerup", handleScrubEnd); - window.removeEventListener("pointermove", handleScrubMove); + window.removeEventListener("mousedown", handleScrubStart); + window.removeEventListener("mouseup", handleScrubEnd); + window.removeEventListener("mousemove", handleScrubMove); }; } }, [handleScrubEnd, handleScrubMove, key]); return(

(Component: React.Co cursor: pointerStartPos >=0 ? 'grabbing': 'grab', ...styleOverride }} - onPointerDown={handleScrubStart} > Date: Wed, 6 Mar 2024 16:22:43 -0500 Subject: [PATCH 04/13] fixed reset ids --- .../common/VideoQuickTrim/TrimScrubber.tsx | 6 ++---- .../common/VideoQuickTrim/VideoQuickTrim.tsx | 6 +++--- .../common/VideoQuickTrim/types.tsx | 2 +- .../common/VideoQuickTrim/withScrubbing.tsx | 20 +++++++++---------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx index 129485514b..8b7c795fcd 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx @@ -36,17 +36,15 @@ export const TrimScrubber = memo(({ trimStartSeconds: duration * posPercent, trimEndSeconds: duration * posPercent + trimDuration, }); - }, [onChange]) + }, [onChange, duration, trimDuration]) return ( ) }); - - diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx index f4bde41c1b..cc11257590 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx @@ -35,7 +35,7 @@ const trimOptions: { [key: string]: number } = { const initialTrimState: TrimStates = { canNotTrim: true, trimDuration: 0, - trimReset: new Date(), + trimReset: Date.now(), trimStart: 0, trimEnd: 0, maxDuration: 0, @@ -153,7 +153,7 @@ export default memo(function VideoQuickTrim({ } setTrimState((curr)=>({ ...curr, - trimReset: new Date(), + trimReset: Date.now(), trimDuration: trimOptions[selected], trimStart: newTrimStart, trimEnd: newTrimEnd, @@ -226,7 +226,7 @@ export default memo(function VideoQuickTrim({ playbarWidth > 0 && maxDuration > 0 && (Component: React.Co }: withScrubbingPropsI) => { console.log('withScrubbing reRender'); const refEl = useRef(null); - // const initialLeftOffset = - // initialLeftOffsetPercent > 0 ? boundingWidth * initialLeftOffsetPercent - // : initialLeftOffsetProps; - const initialLeftOffset = 0; + const initialLeftOffset = + initialLeftOffsetPercent > 0 ? boundingWidth * initialLeftOffsetPercent + : initialLeftOffsetProps; + // const initialLeftOffset = 0; const [{ key, currLeftOffset, pointerStartPos // prevLeftOffset, }, setStates] = useState({ - key: new Date(), + key: Date.now(), currLeftOffset: initialLeftOffset, // in pixels prevLeftOffset: initialLeftOffset, //in pixels pointerStartPos: -1 // negative denotes pointer not engaged @@ -98,19 +98,19 @@ export const withScrubbing =

(Component: React.Co },[scrubberWidth, boundingWidth]); useLayoutEffect(() => { - if(!(window as any)[`${key}listenders`]){ - (window as any)[`${key}listenders`] = true; + if(!(window as any)[`listener-id-${key}`]){ + (window as any)[`listender-id-${key}`] = true; window.addEventListener("mousedown", handleScrubStart); window.addEventListener("mouseup", handleScrubEnd); window.addEventListener("mousemove", handleScrubMove); return () => { - (window as any)[`${key}listenders`] = false; + (window as any)[`${key}listeners`] = false; window.removeEventListener("mousedown", handleScrubStart); window.removeEventListener("mouseup", handleScrubEnd); window.removeEventListener("mousemove", handleScrubMove); }; } - }, [handleScrubEnd, handleScrubMove, key]); + }, [handleScrubStart, handleScrubEnd, handleScrubMove, key]); return(

Date: Thu, 7 Mar 2024 22:00:59 -0500 Subject: [PATCH 05/13] reducer approach is promising --- .../common/VideoQuickTrim/VideoQuickTrim.tsx | 347 ++++++------------ .../VideoQuickTrim/components/ControlBar.tsx | 95 +++++ .../VideoQuickTrim/components/ProgressBar.tsx | 137 +++++++ .../{ => components}/TrimScrubber.tsx | 11 +- .../{ => components}/withScrubbing.tsx | 2 +- .../components/common/VideoQuickTrim/index.ts | 2 +- .../common/VideoQuickTrim/reducer.tsx | 195 ++++++++++ .../common/VideoQuickTrim/styles.scss | 14 +- .../{helpers.tsx => utilities.tsx} | 15 +- 9 files changed, 572 insertions(+), 246 deletions(-) create mode 100644 packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ControlBar.tsx create mode 100644 packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx rename packages/fakeyou.com/src/components/common/VideoQuickTrim/{ => components}/TrimScrubber.tsx (83%) rename packages/fakeyou.com/src/components/common/VideoQuickTrim/{ => components}/withScrubbing.tsx (98%) create mode 100644 packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx rename packages/fakeyou.com/src/components/common/VideoQuickTrim/{helpers.tsx => utilities.tsx} (69%) diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx index e8ffcbea92..6ced329507 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx @@ -1,296 +1,173 @@ import React, { memo, useCallback, - useLayoutEffect, - useState, + useReducer, useRef, } from "react"; import { - faArrowsRepeat, faPlay, faPause, - faVolume, - faVolumeSlash, } from "@fortawesome/pro-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Button, SelectionBubbles, VideoFakeyou } from "components/common"; + +import { useLocalize } from "hooks"; +import { VideoFakeyou } from "components/common"; import { VideoFakeyouProps } from "../VideoFakeyou/VideoFakeyou"; -import { QuickTrimData, TrimStates, PlaybarStates } from "./types"; -import { formatSecondsToHHMMSSCS } from "./helpers"; -import {TrimScrubber} from "./TrimScrubber"; +import { + reducer, + initialState, + ACTION_TYPES, + PLAYPUASE_STATES, + STATE_STATUSES, +} from "./reducer"; + +import { QuickTrimData } from "./utilities"; + +import { ProgressBar } from "./components/ProgressBar"; +import { ControlBar } from "./components/ControlBar"; import './styles.scss' interface VideoQuickTrimProps extends VideoFakeyouProps { onSelect: (values: QuickTrimData) => void; } -const trimOptions: { [key: string]: number } = { - "3s": 3, - "5s": 5, - "10s": 10, - "15s": 15, -}; - -const initialTrimState: TrimStates = { - canNotTrim: true, - trimDuration: 0, - trimReset: Date.now(), - trimStart: 0, - trimEnd: 0, - maxDuration: 0, -}; - -const initialPlaybarState: PlaybarStates = { - playbarWidth: 0, - timeCursorOffset: 0, -}; - -export default memo(function VideoQuickTrim({ +export const VideoQuickTrim = memo(({ onSelect, ...rest -}: VideoQuickTrimProps) { - // console.log("VideoQuickTrim Rerender!!"); - +}: VideoQuickTrimProps) => { + const { t } = useLocalize("VideoPlayerQuickTrim"); const videoRef = useRef(null); - const playbarRef = useRef(null); - - const [{ - playbarWidth, - timeCursorOffset - }, setPlaybarState] = useState(initialPlaybarState); - const [playpause, setPlaypause] = useState<'playing'|'paused'|'ended'>('paused'); - const [isMuted, setIsMuted] = useState(false); - const [isRepeatOn, setIsRepatOn] = useState(true); - const [{ - canNotTrim, - trimReset, - trimStart, - trimEnd, - trimDuration, - maxDuration - }, setTrimState] = useState(initialTrimState); + const [compState, dispatchCompState] = useReducer(reducer, initialState); + if(compState.status === STATE_STATUSES.LOAD_ORDER_ERROR){ + console.log(`${compState.errorMessage[compState.errorMessage.length -1]}`); + } const videoRefCallback = useCallback(node => { - //console.log("videoRefCallback"); + function setPlaypause(newState: PLAYPUASE_STATES){ + dispatchCompState({ + type: ACTION_TYPES.SET_PLAYPUASE, + payload: { playpause: newState} + }) + } if (node !== null) { // DOM node referenced by ref has changed and exists videoRef.current = node; - node.onloadedmetadata = ()=>{ - if (node.duration >= 3){ - setTrimState((curr)=>({ - ...curr, - canNotTrim: false, - trimDuration: 3, - trimEnd: 3, - maxDuration: node.duration - })); + dispatchCompState({ + type: ACTION_TYPES.ON_LOADED_METADATA, + payload:{ videoDuration: node.duration,} + }); //TODO: this sbould be set in USEEFFECT //IFF USEEFFECT starts working again - onSelect({ - trimStartSeconds: 0, - trimEndSeconds: 3, - }) - } + // onSelect({ + // trimStartSeconds: 0, + // trimEndSeconds: 3, + // }) }; - + node.ontimeupdate = ()=>{ - if(isRepeatOn && - (node.currentTime >= trimEnd || node.currentTime <= trimStart) + if(compState.trimStartSeconds !== undefined && + compState.trimEndSeconds !== undefined && + compState.playbarWidth !== undefined){ + // reset current time when on repeat + if(compState.isRepeatOn && + (node.currentTime >= compState.trimEndSeconds || node.currentTime <= compState.trimStartSeconds) ){ - node.currentTime = trimStart; + node.currentTime = compState.trimStartSeconds; + console.log('play looped'); + } + + dispatchCompState({ + type: ACTION_TYPES.MOVE_TIMECURSOR, + payload: { + timeCursorOffset: (node.currentTime / node.duration) * (compState.playbarWidth-8) + } + }); + }else{ + console.log('ontimeupdate failed'); } - setPlaybarState((curr)=>({ - ...curr, - timeCursorOffset: (node.currentTime / node.duration) * (playbarWidth-8) - })); - }; - node.onplay = ()=>{ setPlaypause("playing");}; - node.onpause = ()=>{setPlaypause("paused");}; - node.onended = ()=>{setPlaypause("ended");}; - + node.onplay = ()=>setPlaypause(PLAYPUASE_STATES.PLAYING); + node.onpause = ()=>setPlaypause(PLAYPUASE_STATES.PAUSED); + node.onended = ()=>setPlaypause(PLAYPUASE_STATES.ENDED); } // else{} DOM node referenced by ref has been unmounted - }, [playbarWidth, onSelect, isRepeatOn, trimStart, trimEnd]); //END videoRefCallback + }, [compState.trimStartSeconds, compState.trimEndSeconds, compState.playbarWidth]); //END videoRefCallback\ - function handleWindowResize() { - if (playbarRef.current !== null) { - const newWidth = playbarRef.current.getBoundingClientRect().width; - setPlaybarState(curr => ({ - playbarWidth: newWidth, - timeCursorOffset: - (curr.timeCursorOffset / (curr.playbarWidth - 8)) * (newWidth - 8), - })); - } + function videoCanPlay(){ + return (compState.playpause === PLAYPUASE_STATES.PAUSED + || compState.playpause === PLAYPUASE_STATES.ENDED + || compState.playpause === PLAYPUASE_STATES.READY + ); } - const playbarRefCallback = useCallback(node => { - if (node !== null) { - playbarRef.current = node; - setPlaybarState(curr => ({ - ...curr, - playbarWidth: node.getBoundingClientRect().width, - })); - } - }, []); - useLayoutEffect(() => { - window.addEventListener("resize", handleWindowResize); - return () => { - window.removeEventListener("resize", handleWindowResize); - }; - }, []); - - const handleChangeTrimDuration = (selected: string) =>{ - if(!canNotTrim && maxDuration > 0 && trimOptions[selected] <= maxDuration){ - let newTrimStart = trimStart; - let newTrimEnd = trimStart+ trimOptions[selected]; - if (newTrimEnd > maxDuration){ - newTrimEnd = maxDuration; - newTrimStart = maxDuration - trimOptions[selected]; - } - setTrimState((curr)=>({ - ...curr, - trimReset: Date.now(), - trimDuration: trimOptions[selected], - trimStart: newTrimStart, - trimEnd: newTrimEnd, - })) - onSelect({ - trimStartSeconds: newTrimStart, - trimEndSeconds: newTrimEnd, - }); - if (isRepeatOn - && videoRef.current - && videoRef.current.currentTime > newTrimEnd - ){ - videoRef.current.currentTime = newTrimStart; - } - } - } - - const handlePlaypause = ()=>{ - if (playpause === 'paused' || playpause === 'ended'){ + function handlePlaypause(){ + if (videoCanPlay()){ videoRef.current?.play(); - }else{ + }else if (compState.playpause === PLAYPUASE_STATES.PLAYING){ videoRef.current?.pause(); + }else { + console.log('Playpause is triggered while it is NOT_READY'); } }; - const trimScrubberWidth = videoRef.current && playbarWidth > 0 - ? trimDuration > 0 && trimDuration < videoRef.current.duration - ? (trimDuration / videoRef.current.duration * playbarWidth) - : playbarWidth - : 0; - return (
- -
- {playpause === "paused" && ( - - )} - {playpause === "playing" && ( - - )} -
- {videoRef.current && canNotTrim && ( + {compState.playpause !== PLAYPUASE_STATES.NOT_READY && +
+ {videoCanPlay() && ( + + )} + {compState.playpause === PLAYPUASE_STATES.PLAYING && ( + + )} +
+ } + { compState.canNotTrim === true &&
-

Warning: Sorry Your Video is TOO Short

+

{t('error.videoTooShort')}

- )} -
- {/* END of Video Wrapper */} -
-
- {trimScrubberWidth > 0 && - playbarWidth > 0 && - maxDuration > 0 && - { - //console.log(val); - setTrimState((curr)=>({ - ...curr, - trimStart: val.trimStartSeconds, - trimEnd: val.trimEndSeconds - })) - onSelect({ - trimStartSeconds: val.trimStartSeconds, - trimEndSeconds: val.trimEndSeconds, - }); - }} - /> } -
-
{/* END of Playbar */} - -
-
-
- -
+
{/* END of Video Wrapper */} + +
); }); diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ControlBar.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ControlBar.tsx new file mode 100644 index 0000000000..2b5af5031b --- /dev/null +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ControlBar.tsx @@ -0,0 +1,95 @@ +import React,{ + memo +} from 'react' +import { + faArrowsRepeat, + faPlay, + faPause, + faVolume, + faVolumeSlash, +} from "@fortawesome/pro-solid-svg-icons"; +import { + Action, + ACTION_TYPES, + PLAYPUASE_STATES +} from '../reducer'; +import { Button, SelectionBubbles } from "components/common"; +import { TRIM_OPTIONS, formatSecondsToHHMMSSCS } from "../utilities"; + +export const ControlBar = memo(({ + videoCurrentTime, + videoDuration, + isRepeatOn, + isMuted, + playpause, + handlePlaypause, + dispatchCompState +}:{ + videoCurrentTime: number | undefined; + videoDuration: number | undefined; + isMuted: boolean, + isRepeatOn: boolean; + playpause: string; + handlePlaypause: ()=>void; + dispatchCompState: (action: Action) => void; +})=>{ + function handleSetTrimDuration(selected: string){ + dispatchCompState({ + type: ACTION_TYPES.SET_TRIM_DURATION, + payload: { + trimDurationString: selected + } + }); + // onSelect({ + // trimStartSeconds: newTrimStart, + // trimEndSeconds: newTrimEnd, + // }); + }; + + return( +
+
+
+ +
+ ); +}); \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx new file mode 100644 index 0000000000..98e0d249a1 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx @@ -0,0 +1,137 @@ +import React, { + memo, + useCallback, + useLayoutEffect, + useRef +} from 'react'; +import { + Action, + ACTION_TYPES, +} from '../reducer'; +import { QuickTrimData } from '../types'; +import { TrimScrubber } from './TrimScrubber'; + +export const ProgressBar = memo(({ + readyToMount, + timeCursorOffset, + trimReset, + trimStartSeconds, + trimDuration, + playbarWidth, + scrubberWidth, + videoDuration, + dispatchCompState +}:{ + readyToMount: boolean; + timeCursorOffset: number; + trimReset: number; + trimStartSeconds: number; + trimDuration: number; + playbarWidth: number; + scrubberWidth: number; + videoDuration: number; + dispatchCompState: (action: Action) => void; +})=>{ + const playbarRef = useRef(null); + + function setPlaybarLayout(playbarWidth: number){ + if(readyToMount) { + dispatchCompState({ + type: ACTION_TYPES.SET_PLAYBAR_LAYOUT, + payload: { + playbarWidth: playbarWidth, + } + }) + }else{ + console.log('set playbar layout but not ready to mount') + } + } + const playbarRefCallback = useCallback(node => { + console.log('playbar usecallback fired'); + if (node !== null) { + playbarRef.current = node; + // setPlaybarLayout(node.getBoundingClientRect().width); + dispatchCompState({ + type: ACTION_TYPES.SET_PLAYBAR_LAYOUT, + payload: { + playbarWidth: node.getBoundingClientRect().width, + } + }) + }else{ + console.log(node); + } + }, []); + + function handleWindowResize() { + if (playbarRef.current !== null ){ + setPlaybarLayout(playbarRef.current.getBoundingClientRect().width); + } + } + useLayoutEffect(() => { + window.addEventListener("resize", handleWindowResize); + return () => { + window.removeEventListener("resize", handleWindowResize); + }; + }, []); + + if(readyToMount){ + console.log('progress bar rendering'); + return( +
+
+ { + console.log(val); + // setTrimState((curr)=>({ + // ...curr, + // trimStart: val.trimStartSeconds, + // trimEnd: val.trimEndSeconds + // })) + // onSelect({ + // trimStartSeconds: val.trimStartSeconds, + // trimEndSeconds: val.trimEndSeconds, + // }); + }} + /> +
+ {/* END of Playbar */}
+ ); + }else{ + console.log('progress bar rendering null'); + return null; + } + + /*trimScrubberWidth > 0 && + playbarWidth > 0 && + maxDuration > 0 && + { + //console.log(val); + setTrimState((curr)=>({ + ...curr, + trimStart: val.trimStartSeconds, + trimEnd: val.trimEndSeconds + })) + onSelect({ + trimStartSeconds: val.trimStartSeconds, + trimEndSeconds: val.trimEndSeconds, + }); + }} + /> + } */ + + + +}); \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx similarity index 83% rename from packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx rename to packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx index 8b7c795fcd..3f3fd60aff 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/TrimScrubber.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx @@ -1,12 +1,13 @@ import React, { memo, + useMemo, useCallback } from 'react'; import { faGripDots } from "@fortawesome/pro-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { QuickTrimData } from './types'; +import { QuickTrimData } from '../types'; import {withScrubbing, withScrubbingPropsI} from './withScrubbing'; interface TrimScrubberPropsI extends withScrubbingPropsI { @@ -22,21 +23,23 @@ export const TrimScrubber = memo(({ onChange, ...rest }:TrimScrubberPropsI)=>{ + console.log(`TrimsSrubber reRender!! ${Date.now()}`); const TrimScrubberWithScrubbing = - withScrubbing(() => { + useMemo(()=>withScrubbing(() => { return(
); - }); + }), []); const handleOnChange = useCallback((posPercent:number)=>{ onChange({ trimStartSeconds: duration * posPercent, trimEndSeconds: duration * posPercent + trimDuration, }); - }, [onChange, duration, trimDuration]) + }, [onChange, duration, trimDuration]); + return ( (Component: React.Co onScrubChanges, ...rest }: withScrubbingPropsI) => { - console.log('withScrubbing reRender'); + console.log(`withScrubbing reRender!! ${Date.now()}`); const refEl = useRef(null); const initialLeftOffset = initialLeftOffsetPercent > 0 ? boundingWidth * initialLeftOffsetPercent diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/index.ts b/packages/fakeyou.com/src/components/common/VideoQuickTrim/index.ts index 7e49b01a6f..0cc8a0b6f7 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/index.ts +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/index.ts @@ -1,4 +1,4 @@ -import VideoQuickTrim from './VideoQuickTrim' +import {VideoQuickTrim} from './VideoQuickTrim' import { QuickTrimData } from './types'; export type { QuickTrimData }; diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx new file mode 100644 index 0000000000..6ca6b85eaa --- /dev/null +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx @@ -0,0 +1,195 @@ +import { TRIM_OPTIONS } from "./utilities"; + +export enum STATE_STATUSES { + INIT = "init", + VIDEO_METADATA_LOADED = "video_metadata_loaded", + LOAD_ORDER_ERROR = "load_order_error", + ACTION_TYPE_ERROR = "no_such_action_type" +}; + +export enum PLAYPUASE_STATES{ + NOT_READY = "not_ready", + READY = "ready", + PLAYING = "playing", + PAUSED = "paused", + ENDED = "ended", +} + +export type State = { + status: string; + errorMessage: string[]; + + playpause: string; + + canNotTrim: boolean | undefined; + trimReset: number; + trimDuration: number | undefined; + trimStartSeconds: number | undefined; + trimEndSeconds: number | undefined; + videoDuration: number | undefined; + + playbarWidth: number | undefined; + scrubberWidth: number | undefined; + timeCursorOffset: number | undefined; + + isMuted: boolean; + isRepeatOn: boolean; +}; + +export const initialState = { + status: STATE_STATUSES.INIT, + errorMessage : [], + playpause: PLAYPUASE_STATES.NOT_READY, + canNotTrim: undefined, + trimReset: Date.now(), + trimDuration: undefined, + trimStartSeconds: undefined, + trimEndSeconds: undefined, + videoDuration: undefined, + playbarWidth: undefined, + scrubberWidth: undefined, + timeCursorOffset: undefined, + isMuted: false, + isRepeatOn: true, +} + +export enum ACTION_TYPES { + RESET = "reset", + TOGGLE_REPEAT = "toggle_repeat", + TOGGLE_MUTE = "toggle_mute", + ON_LOADED_METADATA = "on_loaded_metadata", + MOVE_TIMECURSOR = "move_timecursor", + SET_PLAYPUASE = "set_playpause", + SET_PLAYBAR_LAYOUT = "set_playbar_layout", + SET_TRIM_DURATION = "set_trim_duration", +} + +export type Action = + | {type: ACTION_TYPES.RESET} + | {type: ACTION_TYPES.TOGGLE_REPEAT} + | {type: ACTION_TYPES.TOGGLE_MUTE} + | {type: ACTION_TYPES.ON_LOADED_METADATA, payload: {videoDuration: number}} + | {type: ACTION_TYPES.MOVE_TIMECURSOR, payload:{ timeCursorOffset: number}} + | {type: ACTION_TYPES.SET_PLAYPUASE, payload:{ playpause: string}} + | {type: ACTION_TYPES.SET_PLAYBAR_LAYOUT, payload:{ playbarWidth: number}} + | {type: ACTION_TYPES.SET_TRIM_DURATION, payload:{ trimDurationString: string}} +; + +function isReadyToSetTrim(selectedTrim:string, state:State){ + return ( + state.canNotTrim !== undefined + && state.canNotTrim === false + && state.videoDuration !== undefined + && TRIM_OPTIONS[selectedTrim] <= state.videoDuration + ) +} + +export function reducer(state: State, action: Action): State { + console.log("VideoQuickTrim State Dispatch"); + console.log(action); + const timeCursorWidth = 8; + const minVideoDuration = 3; + switch(action.type){ + case ACTION_TYPES.SET_PLAYPUASE:{ + return {...state, ...action.payload}; + } + case ACTION_TYPES.TOGGLE_REPEAT:{ + return {...state, isRepeatOn: !state.isRepeatOn} + } + case ACTION_TYPES.TOGGLE_MUTE:{ + return {...state, isMuted: !state.isMuted} + } + case ACTION_TYPES.ON_LOADED_METADATA:{ + if(action.payload.videoDuration >= minVideoDuration){ + return{ + ...state, + status: STATE_STATUSES.VIDEO_METADATA_LOADED, + videoDuration: action.payload.videoDuration, + canNotTrim: false, + trimDuration: 3, + trimStartSeconds: 0, + trimEndSeconds: 3, + } + }else{ + return { + ...state, + // status: STATE_STATUSES.VIDEO_METADATA_LOADED, + videoDuration: action.payload.videoDuration, + canNotTrim: true + } + } + } + case ACTION_TYPES.SET_PLAYBAR_LAYOUT:{ + const newWidth = action.payload.playbarWidth; + const prevOffset = state.timeCursorOffset || 0; + if(state.trimDuration && state.videoDuration){ + return { + ...state, + playpause: PLAYPUASE_STATES.READY, + playbarWidth: newWidth, + scrubberWidth: newWidth * (state.trimDuration / state.videoDuration), + timeCursorOffset: (newWidth-timeCursorWidth)*(prevOffset/ state.videoDuration) + }; + }else{ + return{ + ...state, + status: STATE_STATUSES.LOAD_ORDER_ERROR, + errorMessage: [...state.errorMessage, 'Setting playbar layout before video and trim are loaded'] + } + } + } + case ACTION_TYPES.SET_TRIM_DURATION:{ + const selected = action.payload.trimDurationString; + if( isReadyToSetTrim(selected, state) && state.trimStartSeconds && state.videoDuration ){ + let newTrimStart = state.trimStartSeconds; + let newTrimEnd = state.trimStartSeconds + TRIM_OPTIONS[selected]; + if (newTrimEnd > state.videoDuration){ + newTrimEnd = state.videoDuration; + if (state.videoDuration - TRIM_OPTIONS[selected] >=0) { + newTrimStart = state.videoDuration - TRIM_OPTIONS[selected]; + }else{ + newTrimStart = 0; + } + } + return{ + ...state, + trimReset: Date.now(), + trimDuration: TRIM_OPTIONS[selected], + trimStartSeconds: newTrimStart, + trimEndSeconds: newTrimEnd, + } + }else{ + return { + ...state, + status: STATE_STATUSES.LOAD_ORDER_ERROR, + errorMessage: [...state.errorMessage, 'Setting trim duration before video and trim are loaded'] + } + } + } + case ACTION_TYPES.MOVE_TIMECURSOR:{ + return { + ...state, + timeCursorOffset: action.payload.timeCursorOffset + } + } + case ACTION_TYPES.RESET:{ + return initialState + } + default:{ + return { + ...state, + status: STATE_STATUSES.ACTION_TYPE_ERROR, + errorMessage: [...state.errorMessage, "Reducer Action switch's default case is reached"] + } + } + } +}; + +/* + const trimScrubberWidth = videoRef.current && playbarWidth > 0 + ? trimDuration > 0 && trimDuration < videoRef.current.duration + ? (trimDuration / videoRef.current.duration * playbarWidth) + : playbarWidth + : 0; +*/ + diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/styles.scss b/packages/fakeyou.com/src/components/common/VideoQuickTrim/styles.scss index 5974a5c853..433235cb1b 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/styles.scss +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/styles.scss @@ -60,11 +60,11 @@ $playbar-height: 2rem; background-color: #e66462; opacity: 70%; } - p { + h1 { position: absolute; - margin-top: 230px; - width: 100%; - top: 0; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); } } .playbar { @@ -81,6 +81,9 @@ $playbar-height: 2rem; background-color: $panel-inner-border; border-radius: 0 0 0.5rem 0.5rem; } + .scrubber-wrapper{ + box-shadow: 1px 1px 4px 0px rgba(0,0,0,1); + } .trim-scrubber{ height: 3rem; background-color: #e66462; @@ -88,6 +91,7 @@ $playbar-height: 2rem; outline: 0.125rem $white solid; border-top: 1rem $white solid; border-radius: 0.25rem 0.25rem 0.125rem 0.125rem; + display: flex; justify-content: center; @@ -103,6 +107,8 @@ $playbar-height: 2rem; width: 0.5rem; height: $playbar-height; background-color: $white; + border-radius: 1px; + box-shadow: 1px 1px 4px 0px rgba(0,0,0,0.2); } .playpause-external { diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/helpers.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/utilities.tsx similarity index 69% rename from packages/fakeyou.com/src/components/common/VideoQuickTrim/helpers.tsx rename to packages/fakeyou.com/src/components/common/VideoQuickTrim/utilities.tsx index cbe19a389a..25593c7708 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/helpers.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/utilities.tsx @@ -1,3 +1,9 @@ +//For integration into other components +export type QuickTrimData = { + trimStartSeconds: number; + trimEndSeconds: number; +} + export function roundTo2Dec(floaty:number){ return Math.round(floaty*100)/100; } @@ -11,4 +17,11 @@ export function formatSecondsToHHMMSSCS(seconds:number){ return isoString.substring(11, 19) + "." + isoString.substring(20, 22) else return isoString.substring(14, 19) + "." + isoString.substring(20, 22); -} \ No newline at end of file +} + +export const TRIM_OPTIONS:{[key: string]: number } = { + "3s": 3, + "5s": 5, + "10s":10, + "15s":15 +}; \ No newline at end of file From 894514961c92bc44867b043053940dc351d97ef4 Mon Sep 17 00:00:00 2001 From: wil Date: Thu, 7 Mar 2024 22:27:28 -0500 Subject: [PATCH 06/13] housekeeping and fix trim duration reducter --- .../common/VideoQuickTrim/VideoQuickTrim.tsx | 11 +- .../VideoQuickTrim/components/ControlBar.tsx | 105 ++++++++++-------- .../VideoQuickTrim/components/ProgressBar.tsx | 63 +++-------- .../components/TrimScrubber.tsx | 2 +- .../components/withScrubbing.tsx | 2 +- .../common/VideoQuickTrim/reducer.tsx | 20 ++-- 6 files changed, 88 insertions(+), 115 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx index 6ced329507..826ff67dff 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx @@ -40,7 +40,6 @@ export const VideoQuickTrim = memo(({ const videoRef = useRef(null); const [compState, dispatchCompState] = useReducer(reducer, initialState); - if(compState.status === STATE_STATUSES.LOAD_ORDER_ERROR){ console.log(`${compState.errorMessage[compState.errorMessage.length -1]}`); } @@ -95,7 +94,12 @@ export const VideoQuickTrim = memo(({ node.onpause = ()=>setPlaypause(PLAYPUASE_STATES.PAUSED); node.onended = ()=>setPlaypause(PLAYPUASE_STATES.ENDED); } // else{} DOM node referenced by ref has been unmounted - }, [compState.trimStartSeconds, compState.trimEndSeconds, compState.playbarWidth]); //END videoRefCallback\ + }, [ + compState.trimStartSeconds, + compState.trimEndSeconds, + compState.playbarWidth, + compState.isRepeatOn + ]); //END videoRefCallback\ function videoCanPlay(){ return (compState.playpause === PLAYPUASE_STATES.PAUSED @@ -151,7 +155,7 @@ export const VideoQuickTrim = memo(({ -
-
+
- -
- ); + ); + }else{ + console.log('TODO: ControlBar should rendering loading state instead of null'); + return null; + } + }); \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx index 98e0d249a1..37ffffd3be 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx @@ -14,7 +14,7 @@ import { TrimScrubber } from './TrimScrubber'; export const ProgressBar = memo(({ readyToMount, timeCursorOffset, - trimReset, + // trimReset, trimStartSeconds, trimDuration, playbarWidth, @@ -24,7 +24,7 @@ export const ProgressBar = memo(({ }:{ readyToMount: boolean; timeCursorOffset: number; - trimReset: number; + // trimReset: number; trimStartSeconds: number; trimDuration: number; playbarWidth: number; @@ -34,23 +34,9 @@ export const ProgressBar = memo(({ })=>{ const playbarRef = useRef(null); - function setPlaybarLayout(playbarWidth: number){ - if(readyToMount) { - dispatchCompState({ - type: ACTION_TYPES.SET_PLAYBAR_LAYOUT, - payload: { - playbarWidth: playbarWidth, - } - }) - }else{ - console.log('set playbar layout but not ready to mount') - } - } const playbarRefCallback = useCallback(node => { - console.log('playbar usecallback fired'); if (node !== null) { playbarRef.current = node; - // setPlaybarLayout(node.getBoundingClientRect().width); dispatchCompState({ type: ACTION_TYPES.SET_PLAYBAR_LAYOUT, payload: { @@ -58,13 +44,18 @@ export const ProgressBar = memo(({ } }) }else{ - console.log(node); + // console.log(node); } }, []); function handleWindowResize() { - if (playbarRef.current !== null ){ - setPlaybarLayout(playbarRef.current.getBoundingClientRect().width); + if (playbarRef.current !== null && readyToMount){ + dispatchCompState({ + type: ACTION_TYPES.SET_PLAYBAR_LAYOUT, + payload: { + playbarWidth: playbarRef.current.getBoundingClientRect().width, + } + }); } } useLayoutEffect(() => { @@ -75,12 +66,12 @@ export const ProgressBar = memo(({ }, []); if(readyToMount){ - console.log('progress bar rendering'); + // console.log('progress bar rendering'); return(
); }else{ - console.log('progress bar rendering null'); + console.log('TODO: ProgressBar should rendering loading state instead of null'); return null; } - - /*trimScrubberWidth > 0 && - playbarWidth > 0 && - maxDuration > 0 && - { - //console.log(val); - setTrimState((curr)=>({ - ...curr, - trimStart: val.trimStartSeconds, - trimEnd: val.trimEndSeconds - })) - onSelect({ - trimStartSeconds: val.trimStartSeconds, - trimEndSeconds: val.trimEndSeconds, - }); - }} - /> - } */ - - - }); \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx index 3f3fd60aff..96fb661f59 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx @@ -23,7 +23,7 @@ export const TrimScrubber = memo(({ onChange, ...rest }:TrimScrubberPropsI)=>{ - console.log(`TrimsSrubber reRender!! ${Date.now()}`); + // console.log(`TrimsSrubber reRender!! ${Date.now()}`); const TrimScrubberWithScrubbing = useMemo(()=>withScrubbing(() => { return( diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx index b3104531b0..7fbaec770d 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx @@ -119,7 +119,7 @@ export const withScrubbing =

(Component: React.Co position: 'absolute', top:0, width: scrubberWidth + 'px', - left: currLeftOffset, + left: currLeftOffset + 'px', cursor: pointerStartPos >=0 ? 'grabbing': 'grab', ...styleOverride }} diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx index 6ca6b85eaa..67ebe103a7 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx @@ -75,15 +75,6 @@ export type Action = | {type: ACTION_TYPES.SET_TRIM_DURATION, payload:{ trimDurationString: string}} ; -function isReadyToSetTrim(selectedTrim:string, state:State){ - return ( - state.canNotTrim !== undefined - && state.canNotTrim === false - && state.videoDuration !== undefined - && TRIM_OPTIONS[selectedTrim] <= state.videoDuration - ) -} - export function reducer(state: State, action: Action): State { console.log("VideoQuickTrim State Dispatch"); console.log(action); @@ -140,7 +131,13 @@ export function reducer(state: State, action: Action): State { } case ACTION_TYPES.SET_TRIM_DURATION:{ const selected = action.payload.trimDurationString; - if( isReadyToSetTrim(selected, state) && state.trimStartSeconds && state.videoDuration ){ + if( state.canNotTrim !== undefined + && state.canNotTrim === false + && state.playbarWidth !==undefined + && state.videoDuration !== undefined + && TRIM_OPTIONS[selected] <= state.videoDuration + && state.trimStartSeconds !== undefined + ){ let newTrimStart = state.trimStartSeconds; let newTrimEnd = state.trimStartSeconds + TRIM_OPTIONS[selected]; if (newTrimEnd > state.videoDuration){ @@ -153,10 +150,11 @@ export function reducer(state: State, action: Action): State { } return{ ...state, - trimReset: Date.now(), + // trimReset: Date.now(), trimDuration: TRIM_OPTIONS[selected], trimStartSeconds: newTrimStart, trimEndSeconds: newTrimEnd, + scrubberWidth: state.playbarWidth * (newTrimEnd-newTrimStart)/state.videoDuration } }else{ return { From b17f868db28748d8053cd7c67b5d16ccb93e63b1 Mon Sep 17 00:00:00 2001 From: wil Date: Thu, 7 Mar 2024 23:34:45 -0500 Subject: [PATCH 07/13] housekeeping, fix scrubber width math --- .../VideoQuickTrim/components/ProgressBar.tsx | 30 ++--- .../components/TrimScrubber.tsx | 37 +++--- .../components/withScrubbing.tsx | 105 +++++++++--------- .../components/common/VideoQuickTrim/index.ts | 2 +- .../common/VideoQuickTrim/reducer.tsx | 21 +++- .../common/VideoQuickTrim/types.tsx | 20 ---- .../common/VideoQuickTrim/utilities.tsx | 3 + .../view/pages/components_library/sandbox.tsx | 4 +- 8 files changed, 109 insertions(+), 113 deletions(-) delete mode 100644 packages/fakeyou.com/src/components/common/VideoQuickTrim/types.tsx diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx index 37ffffd3be..1e32249c07 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx @@ -8,7 +8,7 @@ import { Action, ACTION_TYPES, } from '../reducer'; -import { QuickTrimData } from '../types'; +import { QuickTrimData } from '../utilities'; import { TrimScrubber } from './TrimScrubber'; export const ProgressBar = memo(({ @@ -46,9 +46,9 @@ export const ProgressBar = memo(({ }else{ // console.log(node); } - }, []); + }, [dispatchCompState]); - function handleWindowResize() { + const handleWindowResize = useCallback(()=> { if (playbarRef.current !== null && readyToMount){ dispatchCompState({ type: ACTION_TYPES.SET_PLAYBAR_LAYOUT, @@ -57,13 +57,13 @@ export const ProgressBar = memo(({ } }); } - } + },[dispatchCompState, readyToMount]); useLayoutEffect(() => { window.addEventListener("resize", handleWindowResize); return () => { window.removeEventListener("resize", handleWindowResize); }; - }, []); + }, [handleWindowResize]); if(readyToMount){ // console.log('progress bar rendering'); @@ -72,18 +72,20 @@ export const ProgressBar = memo(({

{ - console.log(val); - // setTrimState((curr)=>({ - // ...curr, - // trimStart: val.trimStartSeconds, - // trimEnd: val.trimEndSeconds - // })) + + dispatchCompState({ + type: ACTION_TYPES.MOVE_TRIM, + payload: { + trimStartSeconds: val.trimStartSeconds, + trimEndSeconds: val.trimEndSeconds + } + }); // onSelect({ // trimStartSeconds: val.trimStartSeconds, // trimEndSeconds: val.trimEndSeconds, diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx index 96fb661f59..714e778230 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx @@ -1,51 +1,50 @@ import React, { memo, - useMemo, useCallback } from 'react'; import { faGripDots } from "@fortawesome/pro-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { QuickTrimData } from '../types'; +import { QuickTrimData } from '../utilities'; import {withScrubbing, withScrubbingPropsI} from './withScrubbing'; interface TrimScrubberPropsI extends withScrubbingPropsI { - trimStart:number; + trimStartSeconds:number; trimDuration: number; - duration: number; + videoDuration: number; onChange:(val:QuickTrimData)=>void } export const TrimScrubber = memo(({ - trimStart, + trimStartSeconds, trimDuration, - duration, + videoDuration, onChange, ...rest }:TrimScrubberPropsI)=>{ - // console.log(`TrimsSrubber reRender!! ${Date.now()}`); - const TrimScrubberWithScrubbing = - useMemo(()=>withScrubbing(() => { - return( -
- -
- ); - }), []); + + const TrimScrubberWithScrubbing = withScrubbing(() => { + return( +
+ +
+ ); + }); const handleOnChange = useCallback((posPercent:number)=>{ + console.log(`handle on moving trim scrubber, pos%=${posPercent}`); onChange({ - trimStartSeconds: duration * posPercent, - trimEndSeconds: duration * posPercent + trimDuration, + trimStartSeconds: videoDuration * posPercent, + trimEndSeconds: videoDuration * posPercent + trimDuration, }); - }, [onChange, duration, trimDuration]); + }, [onChange, videoDuration, trimDuration]); return ( diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx index 7fbaec770d..7bc3925761 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx @@ -1,8 +1,9 @@ import React,{ + // useEffect, useRef, useState, useLayoutEffect, - useCallback, + // useCallback, } from 'react'; export interface withScrubbingPropsI { @@ -34,14 +35,17 @@ export const withScrubbing =

(Component: React.Co onScrubChanges, ...rest }: withScrubbingPropsI) => { - console.log(`withScrubbing reRender!! ${Date.now()}`); + // console.log(`withScrubbing reRender!! ${Date.now()}`); const refEl = useRef(null); + const refListener = useRef(Date.now()); + const initialLeftOffset = initialLeftOffsetPercent > 0 ? boundingWidth * initialLeftOffsetPercent : initialLeftOffsetProps; // const initialLeftOffset = 0; const [{ - key, currLeftOffset, pointerStartPos + // key, + currLeftOffset, pointerStartPos, // prevLeftOffset, }, setStates] = useState({ key: Date.now(), @@ -50,67 +54,64 @@ export const withScrubbing =

(Component: React.Co pointerStartPos: -1 // negative denotes pointer not engaged }); - const handleScrubStart = useCallback( (e: MouseEvent) => { - if(refEl.current){ - console.log(`start: ${e.clientX}` ); - if(refEl.current.contains(e.target as Node)){ - setStates((curr)=>({ - ...curr, - pointerStartPos: e.clientX - })); - return true; - } - } - },[]); - const handleScrubEnd = useCallback((e: MouseEvent)=>{ - // e.persist(); - e.preventDefault(); - e.stopPropagation(); - setStates((curr)=>({ - ...curr, - pointerStartPos: -1, - prevLeftOffset: curr.currLeftOffset, - })); - // if (onScrubEnds) onScrubEnds(currLeftOffset/boundingWidth); - }, []); - const handleScrubMove = useCallback ((e: MouseEvent)=>{ - // e.persist(); - e.preventDefault(); - e.stopPropagation(); - setStates((curr)=>{ - if(curr.pointerStartPos >= 0 && curr.pointerStartPos!==null){ - let newLeftOffset = curr.prevLeftOffset + e.clientX - curr.pointerStartPos; - if (newLeftOffset + scrubberWidth > boundingWidth) { - newLeftOffset = boundingWidth - scrubberWidth; - }else if(newLeftOffset < 0) { - newLeftOffset = 0; - } - if(newLeftOffset !== curr.currLeftOffset){ - return{ + useLayoutEffect(() => { + function handleScrubStart (e: MouseEvent) { + if(refEl.current){ + if(refEl.current.contains(e.target as Node)){ + setStates((curr)=>({ ...curr, - currLeftOffset: newLeftOffset + pointerStartPos: e.clientX + })); + return true; + } + } + }; + function handleScrubEnd (e: MouseEvent){ + e.preventDefault(); + e.stopPropagation(); + setStates((curr)=>({ + ...curr, + pointerStartPos: -1, + prevLeftOffset: curr.currLeftOffset, + })); + }; + function handleScrubMove (e: MouseEvent){ + e.preventDefault(); + e.stopPropagation(); + setStates((curr)=>{ + if(curr.pointerStartPos >= 0 && curr.pointerStartPos!==null){ + let newLeftOffset = curr.prevLeftOffset + e.clientX - curr.pointerStartPos; + if (newLeftOffset + scrubberWidth > boundingWidth) { + newLeftOffset = boundingWidth - scrubberWidth; + }else if(newLeftOffset < 0) { + newLeftOffset = 0; + } + if(newLeftOffset !== curr.currLeftOffset){ + return{ + ...curr, + currLeftOffset: newLeftOffset + } } } - } - return curr; - }); - // if (onScrubChanges) onScrubChanges(newLeftOffset/boundingWidth); - },[scrubberWidth, boundingWidth]); - - useLayoutEffect(() => { - if(!(window as any)[`listener-id-${key}`]){ - (window as any)[`listender-id-${key}`] = true; + return curr; + }); + }; + if(!(window as any)[`listener-id-${refListener}`]){ + (window as any)[`listender-id-${refListener}`] = true; window.addEventListener("mousedown", handleScrubStart); window.addEventListener("mouseup", handleScrubEnd); window.addEventListener("mousemove", handleScrubMove); return () => { - (window as any)[`${key}listeners`] = false; + (window as any)[`listener-id-${refListener}`] = false; window.removeEventListener("mousedown", handleScrubStart); window.removeEventListener("mouseup", handleScrubEnd); window.removeEventListener("mousemove", handleScrubMove); }; } - }, [handleScrubStart, handleScrubEnd, handleScrubMove, key]); + }, []); + // useEffect(()=>{ + // if(onScrubEnds)onScrubEnds(prevLeftOffset/boundingWidth); + // },[prevLeftOffset, boundingWidth, onScrubEnds]); return(

= minVideoDuration){ + if(action.payload.videoDuration >= MIN_VID_DURATION){ return{ ...state, status: STATE_STATUSES.VIDEO_METADATA_LOADED, @@ -119,7 +123,7 @@ export function reducer(state: State, action: Action): State { playpause: PLAYPUASE_STATES.READY, playbarWidth: newWidth, scrubberWidth: newWidth * (state.trimDuration / state.videoDuration), - timeCursorOffset: (newWidth-timeCursorWidth)*(prevOffset/ state.videoDuration) + timeCursorOffset: (newWidth-TIME_CURSOR_WIDTH)*(prevOffset/ state.videoDuration) }; }else{ return{ @@ -164,6 +168,13 @@ export function reducer(state: State, action: Action): State { } } } + case ACTION_TYPES.MOVE_TRIM:{ + return{ + ...state, + trimStartSeconds: action.payload.trimStartSeconds, + trimEndSeconds: action.payload.trimEndSeconds, + } + } case ACTION_TYPES.MOVE_TIMECURSOR:{ return { ...state, diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/types.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/types.tsx deleted file mode 100644 index ad93df2aff..0000000000 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/types.tsx +++ /dev/null @@ -1,20 +0,0 @@ -//For integration into other components -export type QuickTrimData = { - trimStartSeconds: number; - trimEndSeconds: number; -} - -// INTERNALS -export type TrimStates = { - canNotTrim: boolean; - trimReset: number; - trimDuration: number; - trimStart: number; - trimEnd: number; - maxDuration: number; -} - -export type PlaybarStates = { - playbarWidth: number; - timeCursorOffset: number; -} diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/utilities.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/utilities.tsx index 25593c7708..62f1f741fd 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/utilities.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/utilities.tsx @@ -1,4 +1,7 @@ //For integration into other components +export const TIME_CURSOR_WIDTH = 8; +export const MIN_VID_DURATION = 3; + export type QuickTrimData = { trimStartSeconds: number; trimEndSeconds: number; diff --git a/packages/fakeyou.com/src/v2/view/pages/components_library/sandbox.tsx b/packages/fakeyou.com/src/v2/view/pages/components_library/sandbox.tsx index f979b431bb..a7600a9c6e 100644 --- a/packages/fakeyou.com/src/v2/view/pages/components_library/sandbox.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/components_library/sandbox.tsx @@ -23,13 +23,13 @@ export default function ComponentSandbox( />

-
+ {/*
-
+
*/} ); } \ No newline at end of file From 827f5453ec9953fd069ffb8a962f75580b415e8b Mon Sep 17 00:00:00 2001 From: wil Date: Fri, 8 Mar 2024 00:25:15 -0500 Subject: [PATCH 08/13] scrub returning trim move perfectly in sandbox --- .../components/withScrubbing.tsx | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx index 7bc3925761..2ad8a29b66 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx @@ -1,5 +1,5 @@ import React,{ - // useEffect, + useEffect, useRef, useState, useLayoutEffect, @@ -14,8 +14,6 @@ export interface withScrubbingPropsI { styleOverride?: {[key: string]: string|number }; onScrubEnds?: (posPercent: number)=>void; //return scrubber location as %, where 0 < % < 1 - onScrubChanges?: (posPercent:number)=>void; - //return scrubber location as %, where 0 < % < 1 } type withSrcubbingStates = { @@ -32,10 +30,9 @@ export const withScrubbing =

(Component: React.Co initialLeftOffsetPercent = 0, styleOverride = {}, onScrubEnds, - onScrubChanges, ...rest }: withScrubbingPropsI) => { - // console.log(`withScrubbing reRender!! ${Date.now()}`); + console.log(`withSCRUBBING reRender!! `); const refEl = useRef(null); const refListener = useRef(Date.now()); @@ -46,7 +43,7 @@ export const withScrubbing =

(Component: React.Co const [{ // key, currLeftOffset, pointerStartPos, - // prevLeftOffset, + prevLeftOffset, }, setStates] = useState({ key: Date.now(), currLeftOffset: initialLeftOffset, // in pixels @@ -108,10 +105,12 @@ export const withScrubbing =

(Component: React.Co window.removeEventListener("mousemove", handleScrubMove); }; } - }, []); - // useEffect(()=>{ - // if(onScrubEnds)onScrubEnds(prevLeftOffset/boundingWidth); - // },[prevLeftOffset, boundingWidth, onScrubEnds]); + }, [scrubberWidth, boundingWidth]); + + useEffect(()=>{ + if(onScrubEnds)onScrubEnds(prevLeftOffset/boundingWidth); + },[prevLeftOffset, boundingWidth, onScrubEnds]); + return(

Date: Mon, 11 Mar 2024 12:21:40 -0400 Subject: [PATCH 09/13] fix trim width initiation --- .../components/TrimScrubber.tsx | 2 +- .../components/withScrubbing.tsx | 25 +++++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx index 714e778230..816353a088 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx @@ -45,7 +45,7 @@ export const TrimScrubber = memo(({ top: '-1rem', }} initialLeftOffsetPercent={trimStartSeconds/videoDuration} - onScrubEnds={handleOnChange} + onScrubChanged={handleOnChange} {...rest} /> ) diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx index 2ad8a29b66..13832ac933 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx @@ -1,4 +1,5 @@ import React,{ + memo, useEffect, useRef, useState, @@ -12,7 +13,7 @@ export interface withScrubbingPropsI { initialLeftOffset?: number; //in pixels initialLeftOffsetPercent?: number; // in %, 0 < % < 1 styleOverride?: {[key: string]: string|number }; - onScrubEnds?: (posPercent: number)=>void; + onScrubChanged?: (posPercent: number)=>void; //return scrubber location as %, where 0 < % < 1 } @@ -23,23 +24,23 @@ type withSrcubbingStates = { pointerStartPos: number; } -export const withScrubbing =

(Component: React.ComponentType

) => ({ +export const withScrubbing =

(Component: React.ComponentType

) => memo(({ boundingWidth, scrubberWidth, initialLeftOffset : initialLeftOffsetProps = 0, initialLeftOffsetPercent = 0, styleOverride = {}, - onScrubEnds, + onScrubChanged, ...rest }: withScrubbingPropsI) => { - console.log(`withSCRUBBING reRender!! `); + console.log(`withSCRUBBING reRENDERING!! `); const refEl = useRef(null); const refListener = useRef(Date.now()); const initialLeftOffset = initialLeftOffsetPercent > 0 ? boundingWidth * initialLeftOffsetPercent : initialLeftOffsetProps; - // const initialLeftOffset = 0; + const [{ // key, currLeftOffset, pointerStartPos, @@ -52,6 +53,7 @@ export const withScrubbing =

(Component: React.Co }); useLayoutEffect(() => { + console.log(`withSCRUBBING useLAYOUTeffect!! `); function handleScrubStart (e: MouseEvent) { if(refEl.current){ if(refEl.current.contains(e.target as Node)){ @@ -108,8 +110,15 @@ export const withScrubbing =

(Component: React.Co }, [scrubberWidth, boundingWidth]); useEffect(()=>{ - if(onScrubEnds)onScrubEnds(prevLeftOffset/boundingWidth); - },[prevLeftOffset, boundingWidth, onScrubEnds]); + console.log(`withSCRUBBING useEFFECT!! `); + const positionInPercentage = prevLeftOffset/boundingWidth; + if(onScrubChanged + && typeof positionInPercentage === "number" + && positionInPercentage >= 0 + ){ + onScrubChanged(prevLeftOffset/boundingWidth); + } + },[prevLeftOffset, boundingWidth, onScrubChanged]); return(

(Component: React.Co />
); -}; +}); From 01a5d5dcd770274d2fe413f8641a86a047b8123d Mon Sep 17 00:00:00 2001 From: wil Date: Mon, 11 Mar 2024 15:04:17 -0400 Subject: [PATCH 10/13] double scrubbing player, both trim and playcursor can be scrubbed --- .../VideoQuickTrim/components/PlayCursor.tsx | 27 +++++++++ .../VideoQuickTrim/components/ProgressBar.tsx | 24 ++++---- .../components/TrimScrubber.tsx | 21 ++----- .../components/withScrubbing.tsx | 55 +++++++++++-------- .../common/VideoQuickTrim/styles.scss | 3 +- 5 files changed, 78 insertions(+), 52 deletions(-) create mode 100644 packages/fakeyou.com/src/components/common/VideoQuickTrim/components/PlayCursor.tsx diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/PlayCursor.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/PlayCursor.tsx new file mode 100644 index 0000000000..96b82c60c2 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/PlayCursor.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { withScrubbing, withScrubbingPropsI } from './withScrubbing'; + +interface PlayCursorPropsI extends withScrubbingPropsI{ + // timeCursorOffset: number; + onChanged: (posPercent: number)=>void; + +} + +export const PlayCursor = ({ + // timeCursorOffset, + onChanged, + ...rest +}:PlayCursorPropsI)=>{ + const PlayCursorWithScrubbing = withScrubbing(()=>{ + return( +
+ ); + }); + + return( + + ); +}; diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx index 1e32249c07..8510513750 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx @@ -8,13 +8,12 @@ import { Action, ACTION_TYPES, } from '../reducer'; -import { QuickTrimData } from '../utilities'; import { TrimScrubber } from './TrimScrubber'; +import { PlayCursor } from './PlayCursor'; export const ProgressBar = memo(({ readyToMount, timeCursorOffset, - // trimReset, trimStartSeconds, trimDuration, playbarWidth, @@ -24,7 +23,6 @@ export const ProgressBar = memo(({ }:{ readyToMount: boolean; timeCursorOffset: number; - // trimReset: number; trimStartSeconds: number; trimDuration: number; playbarWidth: number; @@ -71,28 +69,28 @@ export const ProgressBar = memo(({
{ - + onChange={(newPos: number)=>{ + const newTrimStartSeconds = newPos / (playbarWidth - scrubberWidth) * videoDuration; dispatchCompState({ type: ACTION_TYPES.MOVE_TRIM, payload: { - trimStartSeconds: val.trimStartSeconds, - trimEndSeconds: val.trimEndSeconds + trimStartSeconds: newTrimStartSeconds, + trimEndSeconds: newTrimStartSeconds + trimDuration } }); - // onSelect({ - // trimStartSeconds: val.trimStartSeconds, - // trimEndSeconds: val.trimEndSeconds, - // }); }} /> -
+ {console.log(onChangedVal)}} + boundingWidth={playbarWidth} + scrubberWidth={8} + /> {/* END of Playbar */}
); }else{ diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx index 816353a088..dc69e12e25 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx @@ -1,19 +1,18 @@ import React, { memo, - useCallback } from 'react'; import { faGripDots } from "@fortawesome/pro-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { QuickTrimData } from '../utilities'; -import {withScrubbing, withScrubbingPropsI} from './withScrubbing'; +import { withScrubbing, withScrubbingPropsI } from './withScrubbing'; interface TrimScrubberPropsI extends withScrubbingPropsI { trimStartSeconds:number; trimDuration: number; videoDuration: number; - onChange:(val:QuickTrimData)=>void + // onChange:(val:QuickTrimData)=>void + onChange:(newPos:number)=>void } export const TrimScrubber = memo(({ trimStartSeconds, @@ -30,23 +29,15 @@ export const TrimScrubber = memo(({
); }); - - const handleOnChange = useCallback((posPercent:number)=>{ - console.log(`handle on moving trim scrubber, pos%=${posPercent}`); - onChange({ - trimStartSeconds: videoDuration * posPercent, - trimEndSeconds: videoDuration * posPercent + trimDuration, - }); - }, [onChange, videoDuration, trimDuration]); return ( - ) + ); }); diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx index 13832ac933..dd0ca70421 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx @@ -4,31 +4,29 @@ import React,{ useRef, useState, useLayoutEffect, - // useCallback, } from 'react'; export interface withScrubbingPropsI { boundingWidth: number; scrubberWidth: number; - initialLeftOffset?: number; //in pixels - initialLeftOffsetPercent?: number; // in %, 0 < % < 1 + scrubPosition?: number; + // scrubber location as px styleOverride?: {[key: string]: string|number }; - onScrubChanged?: (posPercent: number)=>void; - //return scrubber location as %, where 0 < % < 1 + onScrubChanged?: (newPos: number)=>void; + //return scrubber location as px } type withSrcubbingStates = { - key: number, currLeftOffset: number, prevLeftOffset: number; + prevPropsLeftOffset: number; pointerStartPos: number; } export const withScrubbing =

(Component: React.ComponentType

) => memo(({ boundingWidth, scrubberWidth, - initialLeftOffset : initialLeftOffsetProps = 0, - initialLeftOffsetPercent = 0, + scrubPosition: propsLeftOffset = 0, styleOverride = {}, onScrubChanged, ...rest @@ -37,18 +35,14 @@ export const withScrubbing =

(Component: React.Co const refEl = useRef(null); const refListener = useRef(Date.now()); - const initialLeftOffset = - initialLeftOffsetPercent > 0 ? boundingWidth * initialLeftOffsetPercent - : initialLeftOffsetProps; const [{ - // key, currLeftOffset, pointerStartPos, - prevLeftOffset, + prevLeftOffset }, setStates] = useState({ - key: Date.now(), - currLeftOffset: initialLeftOffset, // in pixels - prevLeftOffset: initialLeftOffset, //in pixels + currLeftOffset: propsLeftOffset, + prevLeftOffset: propsLeftOffset, + prevPropsLeftOffset: propsLeftOffset, pointerStartPos: -1 // negative denotes pointer not engaged }); @@ -72,6 +66,7 @@ export const withScrubbing =

(Component: React.Co ...curr, pointerStartPos: -1, prevLeftOffset: curr.currLeftOffset, + setBySelf: Date.now(), })); }; function handleScrubMove (e: MouseEvent){ @@ -88,7 +83,7 @@ export const withScrubbing =

(Component: React.Co if(newLeftOffset !== curr.currLeftOffset){ return{ ...curr, - currLeftOffset: newLeftOffset + currLeftOffset: newLeftOffset, } } } @@ -111,15 +106,29 @@ export const withScrubbing =

(Component: React.Co useEffect(()=>{ console.log(`withSCRUBBING useEFFECT!! `); - const positionInPercentage = prevLeftOffset/boundingWidth; - if(onScrubChanged - && typeof positionInPercentage === "number" - && positionInPercentage >= 0 - ){ - onScrubChanged(prevLeftOffset/boundingWidth); + if(onScrubChanged && boundingWidth > 0 && prevLeftOffset >= 0 ){ + onScrubChanged(prevLeftOffset); } },[prevLeftOffset, boundingWidth, onScrubChanged]); + useEffect(()=>{ + // this takes a forced reset on leftoffset + setStates((curr)=>{ + if(curr.prevLeftOffset === curr.currLeftOffset + && propsLeftOffset !== curr.prevLeftOffset + && propsLeftOffset !== curr.prevLeftOffset + ){ + return { + ...curr, + currLeftOffset: propsLeftOffset, // in pixels + prevLeftOffset: propsLeftOffset, //in pixels + } + }else{ + return curr + } + }); + }, [propsLeftOffset]) + return(

Date: Mon, 11 Mar 2024 15:42:35 -0400 Subject: [PATCH 11/13] cleaning --- .../src/components/common/VideoQuickTrim/VideoQuickTrim.tsx | 3 +-- .../common/VideoQuickTrim/components/PlayCursor.tsx | 3 --- .../common/VideoQuickTrim/components/TrimScrubber.tsx | 1 - .../common/VideoQuickTrim/components/withScrubbing.tsx | 5 +---- .../src/components/common/VideoQuickTrim/reducer.tsx | 5 ++--- 5 files changed, 4 insertions(+), 13 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx index 826ff67dff..02f7e92d21 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx @@ -154,8 +154,7 @@ export const VideoQuickTrim = memo(({
{/* END of Video Wrapper */} void; - } export const PlayCursor = ({ - // timeCursorOffset, onChanged, ...rest }:PlayCursorPropsI)=>{ diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx index dc69e12e25..bc50c81869 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx @@ -11,7 +11,6 @@ interface TrimScrubberPropsI extends withScrubbingPropsI { trimStartSeconds:number; trimDuration: number; videoDuration: number; - // onChange:(val:QuickTrimData)=>void onChange:(newPos:number)=>void } export const TrimScrubber = memo(({ diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx index dd0ca70421..21f8ebd26b 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx @@ -9,8 +9,7 @@ import React,{ export interface withScrubbingPropsI { boundingWidth: number; scrubberWidth: number; - scrubPosition?: number; - // scrubber location as px + scrubPosition?: number; // scrubber location as px styleOverride?: {[key: string]: string|number }; onScrubChanged?: (newPos: number)=>void; //return scrubber location as px @@ -19,7 +18,6 @@ export interface withScrubbingPropsI { type withSrcubbingStates = { currLeftOffset: number, prevLeftOffset: number; - prevPropsLeftOffset: number; pointerStartPos: number; } @@ -42,7 +40,6 @@ export const withScrubbing =

(Component: React.Co }, setStates] = useState({ currLeftOffset: propsLeftOffset, prevLeftOffset: propsLeftOffset, - prevPropsLeftOffset: propsLeftOffset, pointerStartPos: -1 // negative denotes pointer not engaged }); diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx index e068856d09..f020e74d6f 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx @@ -154,11 +154,10 @@ export function reducer(state: State, action: Action): State { } return{ ...state, - // trimReset: Date.now(), - trimDuration: TRIM_OPTIONS[selected], + trimDuration: newTrimEnd-newTrimStart, trimStartSeconds: newTrimStart, trimEndSeconds: newTrimEnd, - scrubberWidth: state.playbarWidth * (newTrimEnd-newTrimStart)/state.videoDuration + scrubberWidth: (newTrimEnd-newTrimStart)/state.videoDuration * state.playbarWidth, } }else{ return { From 5adc572fcf2069b35faa6c81662084a38b935677 Mon Sep 17 00:00:00 2001 From: wil Date: Mon, 11 Mar 2024 19:44:17 -0400 Subject: [PATCH 12/13] fix scrubber geometry problem --- .../common/VideoQuickTrim/VideoQuickTrim.tsx | 3 ++- .../VideoQuickTrim/components/ProgressBar.tsx | 13 ++++++++++--- .../VideoQuickTrim/components/TrimScrubber.tsx | 2 +- .../VideoQuickTrim/components/withScrubbing.tsx | 2 +- .../components/common/VideoQuickTrim/reducer.tsx | 14 +++++++++++++- .../components/common/VideoQuickTrim/styles.scss | 16 ++++++++++++++++ 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx index 02f7e92d21..46b972f984 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx @@ -82,7 +82,7 @@ export const VideoQuickTrim = memo(({ dispatchCompState({ type: ACTION_TYPES.MOVE_TIMECURSOR, payload: { - timeCursorOffset: (node.currentTime / node.duration) * (compState.playbarWidth-8) + timeCursorOffset: (node.currentTime / node.duration) * (compState.playbarWidth) } }); }else{ @@ -159,6 +159,7 @@ export const VideoQuickTrim = memo(({ trimDuration={compState.trimDuration ||0} playbarWidth={compState.playbarWidth ||0} scrubberWidth={compState.scrubberWidth ||0} + videoBuffered={videoRef.current?.buffered} videoDuration={compState.videoDuration ||0} dispatchCompState={dispatchCompState} /> diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx index 8510513750..acce160c61 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/ProgressBar.tsx @@ -19,6 +19,7 @@ export const ProgressBar = memo(({ playbarWidth, scrubberWidth, videoDuration, + videoBuffered, dispatchCompState }:{ readyToMount: boolean; @@ -28,6 +29,7 @@ export const ProgressBar = memo(({ playbarWidth: number; scrubberWidth: number; videoDuration: number; + videoBuffered:TimeRanges | undefined; dispatchCompState: (action: Action) => void; })=>{ const playbarRef = useRef(null); @@ -67,7 +69,12 @@ export const ProgressBar = memo(({ // console.log('progress bar rendering'); return(

-
+
+ {videoBuffered !== undefined && + + } + +
{ - const newTrimStartSeconds = newPos / (playbarWidth - scrubberWidth) * videoDuration; + const newTrimStartSeconds = newPos / (playbarWidth) * videoDuration; dispatchCompState({ type: ACTION_TYPES.MOVE_TRIM, payload: { @@ -91,7 +98,7 @@ export const ProgressBar = memo(({ boundingWidth={playbarWidth} scrubberWidth={8} /> - {/* END of Playbar */}
+ {/* END of Playbar */}
); }else{ console.log('TODO: ProgressBar should rendering loading state instead of null'); diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx index bc50c81869..787861a47e 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/TrimScrubber.tsx @@ -34,7 +34,7 @@ export const TrimScrubber = memo(({ styleOverride={{ top: '-1rem', }} - scrubPosition={trimStartSeconds/videoDuration*(rest.boundingWidth-rest.scrubberWidth)} + scrubPosition={trimStartSeconds/videoDuration*(rest.boundingWidth)} onScrubChanged={onChange} {...rest} /> diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx index 21f8ebd26b..9869f67c39 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx @@ -103,7 +103,7 @@ export const withScrubbing =

(Component: React.Co useEffect(()=>{ console.log(`withSCRUBBING useEFFECT!! `); - if(onScrubChanged && boundingWidth > 0 && prevLeftOffset >= 0 ){ + if(onScrubChanged && boundingWidth > 0 && prevLeftOffset >= 0 && propsLeftOffset !== prevLeftOffset){ onScrubChanged(prevLeftOffset); } },[prevLeftOffset, boundingWidth, onScrubChanged]); diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx index f020e74d6f..8e769823b2 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/reducer.tsx @@ -26,8 +26,10 @@ export type State = { trimDuration: number | undefined; trimStartSeconds: number | undefined; trimEndSeconds: number | undefined; + videoLoadProgress: number | undefined; videoDuration: number | undefined; + playbarWidth: number | undefined; scrubberWidth: number | undefined; timeCursorOffset: number | undefined; @@ -45,6 +47,7 @@ export const initialState = { trimDuration: undefined, trimStartSeconds: undefined, trimEndSeconds: undefined, + videoLoadProgress: undefined, videoDuration: undefined, playbarWidth: undefined, scrubberWidth: undefined, @@ -62,6 +65,7 @@ export enum ACTION_TYPES { SET_PLAYPUASE = "set_playpause", SET_PLAYBAR_LAYOUT = "set_playbar_layout", SET_TRIM_DURATION = "set_trim_duration", + SET_VIDEO_LOAD_PROGRESS = "set_video_load_progress", MOVE_TRIM = "move_trim" } @@ -74,6 +78,9 @@ export type Action = | {type: ACTION_TYPES.SET_PLAYPUASE, payload:{ playpause: string}} | {type: ACTION_TYPES.SET_PLAYBAR_LAYOUT, payload:{ playbarWidth: number}} | {type: ACTION_TYPES.SET_TRIM_DURATION, payload:{ trimDurationString: string}} + | {type: ACTION_TYPES.SET_VIDEO_LOAD_PROGRESS, payload: { + videoLoadProgress: number + }} | {type: ACTION_TYPES.MOVE_TRIM, payload:{ trimStartSeconds: number, trimEndSeconds: number, @@ -108,12 +115,17 @@ export function reducer(state: State, action: Action): State { }else{ return { ...state, - // status: STATE_STATUSES.VIDEO_METADATA_LOADED, videoDuration: action.payload.videoDuration, canNotTrim: true } } } + case ACTION_TYPES.SET_VIDEO_LOAD_PROGRESS:{ + return{ + ...state, + videoLoadProgress: action.payload.videoLoadProgress + }; + } case ACTION_TYPES.SET_PLAYBAR_LAYOUT:{ const newWidth = action.payload.playbarWidth; const prevOffset = state.timeCursorOffset || 0; diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/styles.scss b/packages/fakeyou.com/src/components/common/VideoQuickTrim/styles.scss index 2f84656633..0dc6db8a49 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/styles.scss +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/styles.scss @@ -80,7 +80,23 @@ $playbar-height: 2rem; left: 0; background-color: $panel-inner-border; border-radius: 0 0 0.5rem 0.5rem; + overflow: hidden; + + .played, .loaded{ + position: absolute; + height: 100%; + top: 0; + left: 0; + opacity: 0.5; + } + .played{ + background-color: $primary-dark; + } + .loaded{ + background-color: $gray-600; + } } + .scrubber-wrapper{ box-shadow: 1px 1px 4px 0px rgba(0,0,0,1); } From 5ecf1ca00d880048659643976b230ccc0a2eff14 Mon Sep 17 00:00:00 2001 From: wil Date: Mon, 11 Mar 2024 20:18:05 -0400 Subject: [PATCH 13/13] playtime cursor also works --- .../common/VideoQuickTrim/VideoQuickTrim.tsx | 32 +++++++++++++++---- .../VideoQuickTrim/components/ProgressBar.tsx | 4 ++- .../components/withScrubbing.tsx | 2 +- .../view/pages/components_library/sandbox.tsx | 10 +++++- .../StudioVST/StudioVSTPage.tsx | 2 ++ .../components/pageVSTApp/pageVSTApp.tsx | 2 ++ 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx index 46b972f984..8a11af6729 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/VideoQuickTrim.tsx @@ -1,6 +1,7 @@ import React, { memo, useCallback, + useEffect, useReducer, useRef, } from "react"; @@ -30,10 +31,14 @@ import './styles.scss' interface VideoQuickTrimProps extends VideoFakeyouProps { onSelect: (values: QuickTrimData) => void; + trimStartSeconds: number; + trimEndSeconds: number; } export const VideoQuickTrim = memo(({ onSelect, + trimStartSeconds: propsTrimStartSeconds, + trimEndSeconds : propsTrimEndSeconds, ...rest }: VideoQuickTrimProps) => { const { t } = useLocalize("VideoPlayerQuickTrim"); @@ -59,12 +64,6 @@ export const VideoQuickTrim = memo(({ type: ACTION_TYPES.ON_LOADED_METADATA, payload:{ videoDuration: node.duration,} }); - //TODO: this sbould be set in USEEFFECT - //IFF USEEFFECT starts working again - // onSelect({ - // trimStartSeconds: 0, - // trimEndSeconds: 3, - // }) }; node.ontimeupdate = ()=>{ @@ -101,6 +100,21 @@ export const VideoQuickTrim = memo(({ compState.isRepeatOn ]); //END videoRefCallback\ + useEffect(()=>{ + if( compState.trimStartSeconds + && compState.trimEndSeconds + && ( + compState.trimStartSeconds !== propsTrimStartSeconds + || compState.trimEndSeconds !== propsTrimEndSeconds + ) + ){ + onSelect({ + trimStartSeconds: compState.trimStartSeconds, + trimEndSeconds: compState.trimEndSeconds, + }); + } + }, [onSelect, compState.trimStartSeconds, compState.trimEndSeconds, propsTrimStartSeconds, propsTrimEndSeconds]) + function videoCanPlay(){ return (compState.playpause === PLAYPUASE_STATES.PAUSED || compState.playpause === PLAYPUASE_STATES.ENDED @@ -162,6 +176,12 @@ export const VideoQuickTrim = memo(({ videoBuffered={videoRef.current?.buffered} videoDuration={compState.videoDuration ||0} dispatchCompState={dispatchCompState} + onPlayCursorChanged={(newPos: number)=>{ + if(videoRef.current !== null && videoRef.current.currentTime + && compState.playbarWidth && compState.videoDuration){ + videoRef.current.currentTime = newPos / compState.playbarWidth * compState.videoDuration; + } + }} /> void; dispatchCompState: (action: Action) => void; })=>{ const playbarRef = useRef(null); @@ -94,7 +96,7 @@ export const ProgressBar = memo(({ /> {console.log(onChangedVal)}} + onChanged={onPlayCursorChanged} boundingWidth={playbarWidth} scrubberWidth={8} /> diff --git a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx index 9869f67c39..92ba05d760 100644 --- a/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx +++ b/packages/fakeyou.com/src/components/common/VideoQuickTrim/components/withScrubbing.tsx @@ -106,7 +106,7 @@ export const withScrubbing =

(Component: React.Co if(onScrubChanged && boundingWidth > 0 && prevLeftOffset >= 0 && propsLeftOffset !== prevLeftOffset){ onScrubChanged(prevLeftOffset); } - },[prevLeftOffset, boundingWidth, onScrubChanged]); + },[propsLeftOffset, prevLeftOffset, boundingWidth, onScrubChanged]); useEffect(()=>{ // this takes a forced reset on leftoffset diff --git a/packages/fakeyou.com/src/v2/view/pages/components_library/sandbox.tsx b/packages/fakeyou.com/src/v2/view/pages/components_library/sandbox.tsx index a7600a9c6e..6b5ea067f6 100644 --- a/packages/fakeyou.com/src/v2/view/pages/components_library/sandbox.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/components_library/sandbox.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import VideoQuickTrim from 'components/common/VideoQuickTrim'; import { NavLink } from 'react-router-dom'; @@ -7,9 +7,13 @@ import {Container, Panel} from 'components/common'; export default function ComponentSandbox( {parentPath}:{parentPath:string} ){ + const [state1, setState1] = useState(undefined); + const [state2, setState2] = useState(undefined); const handleCallback = (val:any)=>{ console.log('onChange is triggered') console.log(val); + setState1(val.trimStartSeconds); + setState2(val.trimEndSeconds); } return ( ← Back @@ -18,11 +22,15 @@ export default function ComponentSandbox(


+

{`Start Seconds: ${state1}`}

+

{`Start Seconds: ${state2}`}

{/*
{job.isSuccessful && job.maybe_result ? ( handleOnChange({ diff --git a/packages/fakeyou.com/src/v2/view/pages/video_styletransfer/components/pageVSTApp/pageVSTApp.tsx b/packages/fakeyou.com/src/v2/view/pages/video_styletransfer/components/pageVSTApp/pageVSTApp.tsx index 1fbe3b2d29..3d081a2290 100644 --- a/packages/fakeyou.com/src/v2/view/pages/video_styletransfer/components/pageVSTApp/pageVSTApp.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/video_styletransfer/components/pageVSTApp/pageVSTApp.tsx @@ -70,6 +70,8 @@ export default function PageVSTApp({
handleOnChange({