refactor: cleaned up code and improved readability

refactor/pull-to-refresh
OwsleyJr 7 months ago
parent be047427df
commit 54b1a9fa23

@ -4,17 +4,15 @@ import { useEffect, useRef, useState } from 'react';
const PullToRefresh = () => { const PullToRefresh = () => {
const router = useRouter(); const router = useRouter();
const [pullStartPoint, setPullStartPoint] = useState<number>(0);
const [pullStartPoint, setPullStartPoint] = useState(0); const [pullChange, setPullChange] = useState<number>(0);
const [pullChange, setPullChange] = useState(0); const [iconPlacement, setIconPlacement] = useState<number>(0);
const refreshDiv = useRef<HTMLDivElement>(null); const refreshDiv = useRef<HTMLDivElement>(null);
// Various pull down thresholds that determine icon location // If pull change is greater than 20, we have passed
const pullDownInitThreshold = pullChange > 20; // the initialization threshold of the pull to refresh
const pullDownStopThreshold = 120; // (the icon will start to show). If it hits 120,
const pullDownReloadThreshold = pullChange > 340; // the reload will start on release
const pullDownIconLocation = pullChange / 3;
useEffect(() => { useEffect(() => {
// Reload function that is called when reload threshold has been hit // Reload function that is called when reload threshold has been hit
// Add loading class to determine when to add spin animation // Add loading class to determine when to add spin animation
@ -37,8 +35,9 @@ const PullToRefresh = () => {
refreshDiv.current?.classList.remove('hidden'); refreshDiv.current?.classList.remove('hidden');
document.body.style.touchAction = 'none'; document.body.style.touchAction = 'none';
document.body.style.overscrollBehavior = 'none'; document.body.style.overscrollBehavior = 'none';
if (html) { if (html) {
html.style.overscrollBehaviorY = 'none'; html.style.overscrollBehavior = 'none';
} }
} else { } else {
refreshDiv.current?.classList.remove('block'); refreshDiv.current?.classList.remove('block');
@ -47,13 +46,17 @@ const PullToRefresh = () => {
}; };
// Tracks how far we have pulled down the refresh icon // Tracks how far we have pulled down the refresh icon
const pullDown = async (e: TouchEvent) => { const pullDown = (e: TouchEvent) => {
const screenY = e.targetTouches[0].screenY; const screenY = e.targetTouches[0].screenY;
const pullLength = const pullLength =
pullStartPoint < screenY ? Math.abs(screenY - pullStartPoint) : 0; pullStartPoint < screenY ? Math.abs(screenY - pullStartPoint) : 0;
setPullChange(pullLength); setPullChange(pullLength);
// Lock the body when the icon is shown
if (iconPlacement > 50) {
document.body.style.overflow = 'hidden';
}
}; };
// Will reload the page if we are past the threshold // Will reload the page if we are past the threshold
@ -61,16 +64,17 @@ const PullToRefresh = () => {
const pullFinish = () => { const pullFinish = () => {
setPullStartPoint(0); setPullStartPoint(0);
if (pullDownReloadThreshold) { if (pullChange > 340) {
forceReload(); forceReload();
} else { } else {
setPullChange(0); setPullChange(0);
} }
document.body.style.touchAction = 'auto'; document.body.style.touchAction = 'auto';
document.body.style.overscrollBehaviorY = 'auto'; document.body.style.overscrollBehavior = 'auto';
document.body.style.overflow = 'scroll';
if (html) { if (html) {
html.style.overscrollBehaviorY = 'auto'; html.style.overscrollBehavior = 'auto';
} }
}; };
@ -78,26 +82,28 @@ const PullToRefresh = () => {
window.addEventListener('touchmove', pullDown, { passive: false }); window.addEventListener('touchmove', pullDown, { passive: false });
window.addEventListener('touchend', pullFinish, { passive: false }); window.addEventListener('touchend', pullFinish, { passive: false });
// Determines the position of the icon based on
// the pull-down distance to touch
if (pullChange / 3 < 120 && pullChange > 20) {
setIconPlacement(pullChange / 3);
} else if (pullChange > 20) {
setIconPlacement(120);
} else {
setIconPlacement(0);
}
return () => { return () => {
window.removeEventListener('touchstart', pullStart); window.removeEventListener('touchstart', pullStart);
window.removeEventListener('touchmove', pullDown); window.removeEventListener('touchmove', pullDown);
window.removeEventListener('touchend', pullFinish); window.removeEventListener('touchend', pullFinish);
}; };
}, [pullDownInitThreshold, pullDownReloadThreshold, pullStartPoint, router]); }, [iconPlacement, pullChange, pullStartPoint, router]);
return ( return (
<div <div
ref={refreshDiv} ref={refreshDiv}
className="absolute left-0 right-0 top-0 z-50 m-auto w-fit transition-all ease-out" className="absolute left-0 right-0 z-50 m-auto w-fit transition-all ease-out"
id="refreshIcon" style={{ top: iconPlacement }}
style={{
top:
pullDownIconLocation < pullDownStopThreshold && pullDownInitThreshold
? pullDownIconLocation
: pullDownInitThreshold
? pullDownStopThreshold
: '',
}}
> >
<div <div
className={`${ className={`${
@ -107,7 +113,7 @@ const PullToRefresh = () => {
> >
<ArrowPathIcon <ArrowPathIcon
className={`rounded-full ${ className={`rounded-full ${
pullDownReloadThreshold && 'rotate-180' pullChange > 340 && 'rotate-180'
} text-indigo-500 transition-all duration-300`} } text-indigo-500 transition-all duration-300`}
/> />
</div> </div>

@ -524,22 +524,3 @@
height: calc(4rem + env(safe-area-inset-bottom)); height: calc(4rem + env(safe-area-inset-bottom));
} }
} }
.ptr--ptr {
box-shadow: initial !important;
position: absolute !important;
z-index: 30 !important;
}
.ptr--refresh {
overflow: visible !important;
z-index: 30 !important;
}
.ptr--pull {
z-index: 30 !important;
}
.ptr--box {
margin-bottom: -13px !important;
}

Loading…
Cancel
Save