UNPKG

react-video-seek-slider

Version:

A lightweight, dependency-free React video seek slider component with YouTube-like functionality, time codes, and video preview support

3 lines (2 loc) 5.17 kB
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react/jsx-runtime"),k=require("react");function V(t,e){const n=t||-1;return e*100/n}const M=(t,e,n)=>t>=e&&t<=n;function R(t,e,n,r){const s=M(t,e,n),c=n-e,l=t-e,d=s?l/c:0;return r?1:d}const F=k.memo(({label:t="",startTime:e,maxTime:n,endTime:r,currentTime:s,seekHoverTime:c,bufferTime:l,isTimePassed:d=!1,isBufferPassed:f=!1,isHoverPassed:S=!1,onHover:j=()=>{},withGap:i})=>{const h=V(n,e),a=(r-e)/n*100,P=`main${i?" with-gap":""}`,w=R(s,e,r,d),T=R(c,e,r,S),v=R(l,e,r,f),$=()=>j(t);return u.jsxs("div",{className:P,onMouseMove:$,style:{width:`${a}%`,left:`${h}%`},children:[u.jsx("div",{className:"inner-seek-block buffered","data-test-id":"test-buffered",style:{transform:`scaleX(${v})`}}),u.jsx("div",{className:"inner-seek-block seek-hover","data-test-id":"test-seek-hover",style:{transform:`scaleX(${T})`}}),u.jsx("div",{className:"inner-seek-block connect",style:{transform:`scaleX(${w})`}})]})});function O(t,e,n){const r=e*100/n;return Math.floor(+(r*(t/100)))}const L=(t,e,n)=>e+1<t.length?t[e+1].fromMs:n,q=({max:t=1e3,currentTime:e=0,bufferTime:n=0,seekHoverPosition:r=0,timeCodes:s,trackWidth:c,mobileSeeking:l,label:d,setLabel:f})=>{const S=O(t,r,c),j=k.useCallback(i=>{d!==i&&f(i)},[d]);return k.useEffect(()=>{if(!l)return;const i=s?.find(({fromMs:h},g)=>{const a=L(s,g,t);return M(e,h,a)});i?.description!==d&&f(i?.description||"")},[e,d,t,s]),u.jsx(u.Fragment,{children:s?.map(({fromMs:i,description:h},g)=>{const a=L(s,g,t),P=a<=e,w=a<=n,T=a<=S;let v=M(e,i,a);const $=P||!v?0:e;v=M(n,i,a);const N=w||!v?0:n;v=M(S,i,a);const E=T||!v?0:S;return u.jsx(F,{label:h,maxTime:t,startTime:i,endTime:a,isTimePassed:P,isBufferPassed:w,isHoverPassed:T,currentTime:$,bufferTime:N,seekHoverTime:E,onHover:j,withGap:!0},i)})})};function A(t,e,n,r){let s=0;return e&&(s=t-e.offsetWidth/2,r&&(s<0?s=0:s+e.offsetWidth>n&&(s=n-e.offsetWidth))),{transform:`translateX(${s}px)`}}function G(t,e=0){const n=Math.round(t/1e3+e),r=Math.floor(n/3600),s=n%3600,c=Math.floor(s/60),l=Math.ceil(s%60);return{hh:r.toString(),mm:c<10?`0${c}`:c.toString(),ss:l<10?`0${l}`:l.toString()}}function z(t,e,n=0,r="",s=""){const c=G(e,n);return t+n<60*1e3?s+c.ss:t+n<3600*1e3?`${r+c.mm}:${c.ss}`:`${c.hh}:${c.mm}:${c.ss}`}const J=({max:t,hoverTimeValue:e,offset:n,trackWidth:r,seekHoverPosition:s,isThumbActive:c,limitTimeTooltipBySides:l,label:d,minutesPrefix:f,secondsPrefix:S,getPreviewScreenUrl:j})=>{const i=k.useRef(null),h=c?"hover-time active":"hover-time",g=A(s,i?.current,r,l),a=z(t,e,n,f,S);return u.jsxs("div",{className:h,style:g,ref:i,"data-testid":"hover-time",children:[c&&j&&u.jsx("div",{className:"preview-screen",style:{backgroundImage:`url(${j(e)})`}}),d&&u.jsx("div",{children:d}),a]})},K=({max:t,currentTime:e,isThumbActive:n})=>{const r=()=>({left:`calc(${e/t*100}% + -6px)`});return u.jsx("div",{className:"thumb active","data-testid":"testThumb",style:r(),children:u.jsx("div",{className:"handler"})})},Q=({max:t=1e3,currentTime:e=0,bufferTime:n=0,hideThumbTooltip:r=!1,offset:s=0,secondsPrefix:c="",minutesPrefix:l="",limitTimeTooltipBySides:d=!0,timeCodes:f,onChange:S=()=>{},getPreviewScreenUrl:j})=>{const[i,h]=k.useState(0),[g,a]=k.useState(""),P=k.useRef(!1),w=k.useRef(!1),T=k.useRef(null),v=T.current?.offsetWidth||0,$=i>0||P.current,N=O(t,i,v),E=o=>{const m=T.current?.getBoundingClientRect(),p=m?.left||0,H=m?.width||0;let b=o-p;b=b<0?0:b,b=b>H?H:b;const I=+(b*100/H*(t/100)).toFixed(0);h(b),S(I,I+s)},x=o=>{if(o.preventDefault(),o.stopPropagation(),!w.current)return;const{changedTouches:m}=o;let p=m?.[m.length-1]?.pageX||0;p=p<0?0:p,E(p)},y=o=>{P.current&&E(o.pageX)},X=(o,m)=>{const p=T.current?.getBoundingClientRect().left||0,H=o?0:m.pageX-p;h(H)},D=(o=!0)=>{w.current=o,h(o?i:0)},B=(o,m)=>{m.preventDefault(),y(m),P.current=o,h(o?i:0)},W=o=>{B(!1,o)},C=()=>{D(!1)};return k.useEffect(()=>{if(!w.current)return;const o=f?.find(({fromMs:m},p)=>{const H=L(f,p,t);return M(e,m,H)});o?.description!==g&&a(o?.description||"")},[e,g,t,f]),k.useEffect(()=>(window.addEventListener("mousemove",y),window.addEventListener("mouseup",W),window.addEventListener("touchmove",x),window.addEventListener("touchend",C),()=>{window.removeEventListener("mousemove",y),window.removeEventListener("mouseup",W),window.removeEventListener("touchmove",x),window.removeEventListener("touchend",C)}),[t,s,v]),u.jsxs("div",{className:"ui-video-seek-slider",children:[u.jsxs("div",{className:$?"track active":"track",ref:T,onMouseMove:o=>X(!1,o),onMouseLeave:o=>X(!0,o),onMouseDown:o=>B(!0,o),onTouchStart:()=>D(!0),"data-testid":"main-track",children:[!!f?.length&&u.jsx(q,{currentTime:e,max:t,bufferTime:n,seekHoverPosition:i,timeCodes:f,mobileSeeking:w.current,trackWidth:v,label:g,setLabel:a}),!f&&u.jsx(F,{maxTime:t,startTime:0,endTime:t,currentTime:e,bufferTime:n,seekHoverTime:N})]}),!r&&u.jsx(J,{max:t,hoverTimeValue:N,isThumbActive:$,label:g,limitTimeTooltipBySides:d,offset:s,seekHoverPosition:i,trackWidth:v,getPreviewScreenUrl:j,minutesPrefix:l,secondsPrefix:c}),u.jsx(K,{max:t,currentTime:e,isThumbActive:$})]})};exports.VideoSeekSlider=Q; //# sourceMappingURL=index.js.map