feat: Improve mobile pull-to-refresh handling and prevent accidental triggers
- Add CSS rules to prevent native pull-to-refresh behavior on mobile browsers. - Update pull-to-refresh hook to increase the threshold for triggering refresh from 80px to 120px. - Enhance mobile gesture handling to only allow pull-to-refresh at the very top of scrollable areas and require more deliberate gestures to activate it. - Implement touch-action properties to improve user experience and prevent unwanted touch behaviors.
This commit is contained in:
@@ -789,6 +789,42 @@
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Prevent native pull-to-refresh on mobile browsers */
|
||||
html,
|
||||
body {
|
||||
overscroll-behavior-y: none;
|
||||
overscroll-behavior: none;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
/* Prevent pull-to-refresh on main content areas */
|
||||
main,
|
||||
#main-content {
|
||||
overscroll-behavior-y: none;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
/* Prevent unwanted touch behaviors that can trigger reloads */
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
touch-action: pan-y;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Allow text selection in content areas */
|
||||
main,
|
||||
article,
|
||||
section,
|
||||
p,
|
||||
span,
|
||||
div[contenteditable] {
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent zoom on input focus on iOS */
|
||||
@media screen and (max-width: 767px) {
|
||||
input[type="text"],
|
||||
|
||||
@@ -510,9 +510,10 @@ export default function GuestDashboard() {
|
||||
}, [isAttendingGuest]);
|
||||
|
||||
// Pull to refresh hook with safe destructuring
|
||||
// Increased threshold to prevent accidental triggers during normal scrolling
|
||||
const pullToRefreshResult = usePullToRefresh(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
}, { pullThreshold: 120 }); // Increased from default 80 to 120px
|
||||
const pullContainerRef = pullToRefreshResult?.containerRef ?? React.useRef<HTMLDivElement>(null);
|
||||
const isRefreshing = pullToRefreshResult?.isRefreshing ?? false;
|
||||
|
||||
|
||||
@@ -101,10 +101,13 @@ export function useMobileGestures(
|
||||
}
|
||||
|
||||
// Check for pull-to-refresh (only at top of scrollable area)
|
||||
// Only enable if we're at the very top (within 5px) to prevent accidental triggers
|
||||
if (handlers.onPullToRefresh && elementRef.current) {
|
||||
const scrollTop = getEffectiveScrollTop();
|
||||
if (scrollTop <= 0) {
|
||||
if (scrollTop <= 5) {
|
||||
isPullingRef.current = true;
|
||||
} else {
|
||||
isPullingRef.current = false;
|
||||
}
|
||||
}
|
||||
}, [handlers, longPressDelay, elementRef, shouldIgnoreTarget, getEffectiveScrollTop]);
|
||||
@@ -121,11 +124,34 @@ export function useMobileGestures(
|
||||
if (Math.abs(deltaX) > 10 || Math.abs(deltaY) > 10) {
|
||||
clearLongPress();
|
||||
}
|
||||
|
||||
// Prevent native pull-to-refresh when we're handling it
|
||||
if (isPullingRef.current && handlers.onPullToRefresh && deltaY > 0) {
|
||||
const currentScrollTop = getEffectiveScrollTop();
|
||||
if (currentScrollTop <= 10) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle pull-to-refresh
|
||||
if (isPullingRef.current && handlers.onPullToRefresh && deltaY > pullThreshold) {
|
||||
handlers.onPullToRefresh();
|
||||
isPullingRef.current = false;
|
||||
// Handle pull-to-refresh - require more deliberate gesture
|
||||
// Only trigger if:
|
||||
// 1. We're still at the top (within 10px)
|
||||
// 2. Vertical movement is significantly more than horizontal (to avoid diagonal swipes)
|
||||
// 3. Movement exceeds threshold
|
||||
if (isPullingRef.current && handlers.onPullToRefresh) {
|
||||
const currentScrollTop = getEffectiveScrollTop();
|
||||
const isVerticalGesture = Math.abs(deltaY) > Math.abs(deltaX) * 1.5; // Vertical must be 1.5x horizontal
|
||||
const isStillAtTop = currentScrollTop <= 10;
|
||||
|
||||
if (isStillAtTop && isVerticalGesture && deltaY > pullThreshold) {
|
||||
// Prevent default to stop native pull-to-refresh
|
||||
e.preventDefault();
|
||||
handlers.onPullToRefresh();
|
||||
isPullingRef.current = false;
|
||||
} else if (!isStillAtTop || Math.abs(deltaX) > 30) {
|
||||
// Cancel if we've scrolled away or moved horizontally too much
|
||||
isPullingRef.current = false;
|
||||
}
|
||||
}
|
||||
}, [handlers, pullThreshold, clearLongPress, shouldIgnoreTarget]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user