housekeeping, fix scrubber width math

This commit is contained in:
wil committed 2024-03-07 23:34:45 -05:00
1 parent 894514961c
commit b17f868db2
8 files changed
+109 -113

No files matched your search

@@ -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(({
<div className="playbar-bg" />
<TrimScrubber
// key={trimReset}
boundingWidth={playbarWidth-scrubberWidth}
boundingWidth={playbarWidth}
scrubberWidth={scrubberWidth}
trimStart={trimStartSeconds}
trimStartSeconds={trimStartSeconds}
trimDuration={trimDuration}
duration={videoDuration}
videoDuration={videoDuration}
onChange={(val: QuickTrimData)=>{
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,
@@ -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<TrimScrubberPropsI>(() => {
return(
<div className="trim-scrubber">
<FontAwesomeIcon icon={faGripDots} />
</div>
);
}), []);
const TrimScrubberWithScrubbing = withScrubbing<TrimScrubberPropsI>(() => {
return(
<div className="trim-scrubber">
<FontAwesomeIcon icon={faGripDots} />
</div>
);
});
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 (
<TrimScrubberWithScrubbing
styleOverride={{
top: '-1rem',
}}
initialLeftOffsetPercent={trimStart/trimDuration}
initialLeftOffsetPercent={trimStartSeconds/videoDuration}
onScrubEnds={handleOnChange}
{...rest}
/>
@@ -1,8 +1,9 @@
import React,{
// useEffect,
useRef,
useState,
useLayoutEffect,
useCallback,
// useCallback,
} from 'react';
export interface withScrubbingPropsI {
@@ -34,14 +35,17 @@ export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.Co
onScrubChanges,
...rest
}: withScrubbingPropsI) => {
console.log(`withScrubbing reRender!! ${Date.now()}`);
// console.log(`withScrubbing reRender!! ${Date.now()}`);
const refEl = useRef<HTMLDivElement| null>(null);
const refListener = useRef<number>(Date.now());
const initialLeftOffset =
initialLeftOffsetPercent > 0 ? boundingWidth * initialLeftOffsetPercent
: initialLeftOffsetProps;
// const initialLeftOffset = 0;
const [{
key, currLeftOffset, pointerStartPos
// key,
currLeftOffset, pointerStartPos,
// prevLeftOffset,
}, setStates] = useState<withSrcubbingStates>({
key: Date.now(),
@@ -50,67 +54,64 @@ export const withScrubbing = <P extends withScrubbingPropsI>(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(
<div
className="scrubber-wrapper"
@@ -1,5 +1,5 @@
import {VideoQuickTrim} from './VideoQuickTrim'
import { QuickTrimData } from './types';
import { QuickTrimData } from './utilities';
export type { QuickTrimData };
export default VideoQuickTrim;
@@ -1,4 +1,4 @@
import { TRIM_OPTIONS } from "./utilities";
import { MIN_VID_DURATION, TIME_CURSOR_WIDTH, TRIM_OPTIONS } from "./utilities";
export enum STATE_STATUSES {
INIT = "init",
@@ -62,6 +62,7 @@ export enum ACTION_TYPES {
SET_PLAYPUASE = "set_playpause",
SET_PLAYBAR_LAYOUT = "set_playbar_layout",
SET_TRIM_DURATION = "set_trim_duration",
MOVE_TRIM = "move_trim"
}
export type Action =
@@ -73,13 +74,16 @@ 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.MOVE_TRIM, payload:{
trimStartSeconds: number,
trimEndSeconds: number,
}}
;
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};
@@ -91,7 +95,7 @@ export function reducer(state: State, action: Action): State {
return {...state, isMuted: !state.isMuted}
}
case ACTION_TYPES.ON_LOADED_METADATA:{
if(action.payload.videoDuration >= 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,
@@ -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;
}
@@ -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;
@@ -23,13 +23,13 @@ export default function ComponentSandbox(
/>
</div>
<br/>
<br/>
{/* <br/>
<div className="m-4">
<VideoQuickTrim
onSelect={handleCallback}
mediaToken='m_h21nykes0j3ph23y5z7w9axtjjn2rr'
/>
</div>
</div> */}
</Panel>
</Container>);
}