From 5a359feeedaae261ffd01791181f38ca81e1fa81 Mon Sep 17 00:00:00 2001 From: Soxasora Date: Sun, 17 Nov 2024 21:58:40 +0100 Subject: [PATCH] test: togglable Android's native PTR --- components/layout.js | 2 +- components/pull-to-refresh.js | 39 ++++++++++++++++----------- components/pull-to-refresh.module.css | 4 +++ 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/components/layout.js b/components/layout.js index 15619e02..dc174dc2 100644 --- a/components/layout.js +++ b/components/layout.js @@ -15,7 +15,7 @@ export default function Layout ({ return ( <> {seo && } - + {/* android prop if true disables its native PTR */} {contain ? ( diff --git a/components/pull-to-refresh.js b/components/pull-to-refresh.js index 8b67012e..4eec92b8 100644 --- a/components/pull-to-refresh.js +++ b/components/pull-to-refresh.js @@ -2,26 +2,34 @@ import { useRouter } from 'next/router' import { useState, useRef, useEffect, useCallback } from 'react' import styles from './pull-to-refresh.module.css' -export default function PullToRefresh ({ children }) { +const PULL_THRESHOLD = 300 +const REFRESH_TIMEOUT = 500 + +export default function PullToRefresh ({ children, android }) { const router = useRouter() const [isRefreshing, setIsRefreshing] = useState(false) const [pullDistance, setPullDistance] = useState(0) const [isPWA, setIsPWA] = useState(false) + const [isAndroid, setIsAndroid] = useState(false) const touchStartY = useRef(0) const touchEndY = useRef(0) + const checkPWA = () => { + const androidPWA = window.matchMedia('(display-mode: standalone)').matches + const iosPWA = window.navigator.standalone === true + setIsAndroid(androidPWA) // we need to know if the user is on Android to enable toggling its native PTR + setIsPWA(androidPWA || iosPWA) + } + useEffect(() => { - const checkPWA = () => { - // android/general || ios - return window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone === true - } - setIsPWA(checkPWA()) + checkPWA() }, []) const handleTouchStart = useCallback((e) => { - if (!isPWA || window.scrollY > 0) return // don't handle if the user is not scrolling from the top of the page + // don't handle if the user is not scrolling from the top of the page, is not on a PWA or if we want Android's native PTR + if (!isPWA || (isAndroid && !android) || window.scrollY > 0) return touchStartY.current = e.touches[0].clientY - }, [isPWA]) + }, [isPWA, isAndroid, android]) const handleTouchMove = useCallback((e) => { if (touchStartY.current === 0) return @@ -31,12 +39,12 @@ export default function PullToRefresh ({ children }) { const handleTouchEnd = useCallback(() => { if (touchStartY.current === 0 || touchEndY.current === 0) return - if (touchEndY.current - touchStartY.current > 300) { // current threshold is 300, subject to change + if (touchEndY.current - touchStartY.current > PULL_THRESHOLD) { setIsRefreshing(true) - router.push(router.asPath) + router.push(router.asPath) // reload the same path setTimeout(() => { setIsRefreshing(false) - }, 500) // simulate loading time + }, REFRESH_TIMEOUT) // simulate loading time } setPullDistance(0) // using this to reset the message behavior touchStartY.current = 0 // avoid random refreshes by resetting touch @@ -44,7 +52,8 @@ export default function PullToRefresh ({ children }) { }, [router]) useEffect(() => { - if (!isPWA) return + // don't handle if the user is not on a PWA or if we want Android's native PTR + if (!isPWA || (isAndroid && !android)) return document.addEventListener('touchstart', handleTouchStart) document.addEventListener('touchmove', handleTouchMove) document.addEventListener('touchend', handleTouchEnd) @@ -53,17 +62,17 @@ export default function PullToRefresh ({ children }) { document.removeEventListener('touchmove', handleTouchMove) document.removeEventListener('touchend', handleTouchEnd) } - }, [isPWA, handleTouchStart, handleTouchMove, handleTouchEnd]) + }, [isPWA, isAndroid, android, handleTouchStart, handleTouchMove, handleTouchEnd]) const getPullMessage = () => { if (isRefreshing) return 'refreshing...' - if (pullDistance > 300) return 'release to refresh' + if (pullDistance > PULL_THRESHOLD) return 'release to refresh' if (pullDistance > 0) return 'pull down to refresh' return '' } return ( -
+
{/* android prop if true disables its native PTR */}