UNPKG

react-idle-timer

Version:
3 lines (2 loc) • 7 kB
import{Component as t,useRef as e,useEffect as n}from"react";import i from"prop-types";const r="object"==("undefined"==typeof window?"undefined":typeof window),s=r?document:{},o=["mousemove","keydown","wheel","DOMMouseScroll","mouseWheel","mousedown","touchstart","touchmove","MSPointerDown","MSPointerMove","visibilitychange"];function u(t,e){let n;return function(...i){n&&clearTimeout(n),n=setTimeout(()=>{t(...i),n=null},e)}}function l(t,e){let n=0;return function(...i){const r=(new Date).getTime();if(!(r-n<e))return n=r,t(...i)}}class c extends t{constructor(t){if(super(t),this.state={idle:!1,oldDate:+new Date,lastActive:+new Date,remaining:null,pageX:null,pageY:null},this.tId=null,this.eventsBound=!1,t.debounce>0&&t.throttle>0)throw new Error("onAction can either be throttled or debounced (not both)");t.debounce>0?this._onAction=u(t.onAction,t.debounce):t.throttle>0?this._onAction=l(t.onAction,t.throttle):t.onAction?this._onAction=t.onAction:this._onAction=()=>{},t.eventsThrottle>0?this._handleEvent=l(this._handleEvent.bind(this),t.eventsThrottle):this._handleEvent=this._handleEvent.bind(this),t.startOnMount||(this.state.idle=!0),this._toggleIdleState=this._toggleIdleState.bind(this),this.reset=this.reset.bind(this),this.pause=this.pause.bind(this),this.resume=this.resume.bind(this),this.getRemainingTime=this.getRemainingTime.bind(this),this.getElapsedTime=this.getElapsedTime.bind(this),this.getLastActiveTime=this.getLastActiveTime.bind(this),this.isIdle=this.isIdle.bind(this)}componentDidMount(){this._bindEvents();const{startOnMount:t}=this.props;t&&this.reset()}componentDidUpdate(t){t.debounce!==this.props.debounce&&(this._onAction=u(this._onAction,this.props.debounce)),t.throttle!==this.props.throttle&&(this._onAction=l(this._onAction,this.props.throttle)),t.eventsThrottle!==this.props.eventsThrottle&&(this._handleEvent=l(this._handleEvent,this.props.eventsThrottle))}componentWillUnmount(){clearTimeout(this.tId),this._unbindEvents(!0)}render(){const{children:t}=this.props;return t||null}_bindEvents(){if(!r)return;const{element:t,events:e,passive:n,capture:i}=this.props;this.eventsBound||(e.forEach(e=>{t.addEventListener(e,this._handleEvent,{capture:i,passive:n})}),this.eventsBound=!0)}_unbindEvents(t=!1){if(!r)return;const{element:e,events:n,passive:i,capture:s}=this.props;(this.eventsBound||t)&&(n.forEach(t=>{e.removeEventListener(t,this._handleEvent,{capture:s,passive:i})}),this.eventsBound=!1)}_toggleIdleState(t){this.setState(t=>({idle:!t.idle}),()=>{const{onActive:e,onIdle:n,stopOnIdle:i}=this.props,{idle:r}=this.state;r?(i&&(clearTimeout(this.tId),this.tId=null,this._unbindEvents()),n(t)):i||(this._bindEvents(),e(t))})}_handleEvent(t){const{remaining:e,pageX:n,pageY:i,idle:r}=this.state,{timeout:s,stopOnIdle:o}=this.props;if(this._onAction(t),e)return;if("mousemove"===t.type){if(t.pageX===n&&t.pageY===i)return;if(void 0===t.pageX&&void 0===t.pageY)return;if(this.getElapsedTime()<200)return}clearTimeout(this.tId),this.tId=null;const u=+new Date-this.getLastActiveTime();(r&&!o||!r&&u>s)&&this._toggleIdleState(t),this.setState({lastActive:+new Date,pageX:t.pageX,pageY:t.pageY}),r&&o||(this.tId=setTimeout(this._toggleIdleState,s))}reset(){clearTimeout(this.tId),this.tId=null,this._bindEvents(),this.setState({idle:!1,oldDate:+new Date,lastActive:+new Date,remaining:null});const{timeout:t}=this.props;this.tId=setTimeout(this._toggleIdleState,t)}pause(){const{remaining:t}=this.state;null===t&&(this._unbindEvents(),clearTimeout(this.tId),this.tId=null,this.setState({remaining:this.getRemainingTime()}))}resume(){const{remaining:t,idle:e}=this.state;null!==t&&(this._bindEvents(),e||(this.tId=setTimeout(this._toggleIdleState,t),this.setState({remaining:null,lastActive:+new Date})))}getRemainingTime(){const{remaining:t,lastActive:e}=this.state,{timeout:n}=this.props;if(null!==t)return t<0?0:t;const i=n-(+new Date-e);return i<0?0:i}getElapsedTime(){const{oldDate:t}=this.state;return+new Date-t}getLastActiveTime(){const{lastActive:t}=this.state;return t}isIdle(){const{idle:t}=this.state;return t}}function a({timeout:t=12e5,element:i=s,events:c=o,onIdle:a=(()=>{}),onActive:h=(()=>{}),onAction:d=(()=>{}),debounce:p=0,throttle:m=0,eventsThrottle:v=200,startOnMount:g=!0,stopOnIdle:b=!1,capture:T=!0,passive:f=!0}={}){const A=e(!1),I=e(!0),_=e(+new Date),E=e(+new Date),w=e(null),D=e(null),O=e(null),S=e(null),y=e(a),M=e(h),L=e(d),X=t=>{const e=!I.current;I.current=e,e?(b&&(clearTimeout(S.current),S.current=null,R()),y.current(t)):b||(B(),M.current(t))};let Y=e=>{if(L.current(e),w.current)return;if("mousemove"===e.type){if(e.pageX===D&&e.pageY===O)return;if(void 0===e.pageX&&void 0===e.pageY)return;if(j()<200)return}clearTimeout(S.current),S.current=null;const n=+new Date-x();(I.current&&!b||!I.current&&n>t)&&X(e),E.current=+new Date,D.current=e.pageX,O.current=e.pageY,I.current&&b||(S.current=setTimeout(X,t))};const B=()=>{r&&(A.current||(c.forEach(t=>{i.addEventListener(t,Y,{capture:T,passive:f})}),A.current=!0))},R=(t=!1)=>{r&&(A.current||t)&&(c.forEach(t=>{i.removeEventListener(t,Y,{capture:T,passive:f})}),A.current=!1)},P=()=>{if(null!==w.current)return w.current<0?0:w.current;const e=t-(+new Date-E.current);return e<0?0:e},j=()=>+new Date-_.current,x=()=>E.current,U=()=>{clearTimeout(S.current),S.current=null,B(),I.current=!1,_.current=+new Date,E.current=+new Date,w.current=null,S.current=setTimeout(X,t)};return n(()=>{if(p>0&&m>0)throw new Error("onAction can either be throttled or debounced (not both)");return v>0&&(Y=l(Y,v)),B(),g&&U(),()=>{clearTimeout(S.current),R(!0)}},[]),n(()=>{y.current=a},[a]),n(()=>{M.current=h},[h]),n(()=>{p>0&&(L.current=u(d,p)),m>0&&(L.current=l(d,m)),L.current=d},[d]),{isIdle:()=>I.current,pause:()=>{null===w.current&&(R(),clearTimeout(S.current),S.current=null,w.current=P())},reset:U,resume:()=>{null!==w.current&&(B(),I.current||(S.current=setTimeout(X,w.current),w.current=null,E.current=+new Date))},getLastActiveTime:x,getElapsedTime:j,getRemainingTime:P}}c.propTypes={timeout:i.number,events:i.arrayOf(i.string),onIdle:i.func,onActive:i.func,onAction:i.func,debounce:i.number,throttle:i.number,eventsThrottle:i.number,element:i.oneOfType([i.object,i.element]),startOnMount:i.bool,stopOnIdle:i.bool,passive:i.bool,capture:i.bool},c.defaultProps={timeout:12e5,element:s,events:o,onIdle:()=>{},onActive:()=>{},onAction:()=>{},debounce:0,throttle:0,eventsThrottle:200,startOnMount:!0,stopOnIdle:!1,capture:!0,passive:!0},a.propTypes={timeout:i.number,events:i.arrayOf(i.string),onIdle:i.func,onActive:i.func,onAction:i.func,debounce:i.number,throttle:i.number,eventsThrottle:i.number,element:i.oneOfType([i.object,i.element]),startOnMount:i.bool,stopOnIdle:i.bool,passive:i.bool,capture:i.bool},a.defaultProps={timeout:12e5,element:s,events:o,onIdle:()=>{},onActive:()=>{},onAction:()=>{},debounce:0,throttle:0,eventsThrottle:200,startOnMount:!0,stopOnIdle:!1,capture:!0,passive:!0};export default c;export{a as useIdleTimer}; //# sourceMappingURL=index.es.js.map