mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-19 07:33:18 +02:00
Fix right-swipe still triggering browser back navigation
Non-passive touchmove listener with preventDefault() blocks Chromium's compositor-level back/forward swipe gesture. Once horizontal movement is detected, the gesture is locked and all further touchmove events are prevented for that swipe. Removed touch-action: pan-y which was insufficient on its own.
This commit is contained in:
@@ -142,15 +142,20 @@ export function SpoolBuddyLayout() {
|
||||
|
||||
// Swipe left/right to cycle through online printers
|
||||
const touchStartRef = useRef<{ x: number; y: number } | null>(null);
|
||||
const swipeLockedRef = useRef(false);
|
||||
const SWIPE_THRESHOLD = 50;
|
||||
const rootRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const handleTouchStart = useCallback((e: React.TouchEvent) => {
|
||||
touchStartRef.current = { x: e.touches[0].clientX, y: e.touches[0].clientY };
|
||||
swipeLockedRef.current = false;
|
||||
}, []);
|
||||
const handleTouchEnd = useCallback((e: React.TouchEvent) => {
|
||||
if (!touchStartRef.current || onlinePrinters.length < 2) return;
|
||||
const dx = e.changedTouches[0].clientX - touchStartRef.current.x;
|
||||
const dy = e.changedTouches[0].clientY - touchStartRef.current.y;
|
||||
touchStartRef.current = null;
|
||||
swipeLockedRef.current = false;
|
||||
if (Math.abs(dx) < SWIPE_THRESHOLD || Math.abs(dy) > Math.abs(dx)) return;
|
||||
const currentIdx = onlinePrinters.findIndex((p: Printer) => p.id === selectedPrinterId);
|
||||
const nextIdx = dx < 0
|
||||
@@ -159,6 +164,22 @@ export function SpoolBuddyLayout() {
|
||||
setSelectedPrinterId(onlinePrinters[nextIdx].id);
|
||||
}, [onlinePrinters, selectedPrinterId, setSelectedPrinterId]);
|
||||
|
||||
// Block browser back/forward swipe gesture with non-passive touchmove listener
|
||||
useEffect(() => {
|
||||
const el = rootRef.current;
|
||||
if (!el) return;
|
||||
const onTouchMove = (e: TouchEvent) => {
|
||||
if (!touchStartRef.current) return;
|
||||
const dx = Math.abs(e.touches[0].clientX - touchStartRef.current.x);
|
||||
const dy = Math.abs(e.touches[0].clientY - touchStartRef.current.y);
|
||||
// Once locked as horizontal, prevent default for the rest of this gesture
|
||||
if (swipeLockedRef.current) { e.preventDefault(); return; }
|
||||
if (dx > 10 && dx > dy) { swipeLockedRef.current = true; e.preventDefault(); }
|
||||
};
|
||||
el.addEventListener('touchmove', onTouchMove, { passive: false });
|
||||
return () => el.removeEventListener('touchmove', onTouchMove);
|
||||
}, []);
|
||||
|
||||
// CSS brightness filter (software dimming)
|
||||
const brightnessStyle = displayBrightness < 100
|
||||
? { filter: `brightness(${displayBrightness / 100})` } as const
|
||||
@@ -167,8 +188,9 @@ export function SpoolBuddyLayout() {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
ref={rootRef}
|
||||
className="w-screen h-screen bg-bambu-dark text-white flex flex-col overflow-hidden"
|
||||
style={{ ...brightnessStyle, overscrollBehaviorX: 'none', touchAction: 'pan-y' }}
|
||||
style={{ ...brightnessStyle, overscrollBehaviorX: 'none' }}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
>
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -23,7 +23,7 @@
|
||||
|
||||
<!-- Splash screens for iOS -->
|
||||
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
|
||||
<script type="module" crossorigin src="/assets/index-DIWh1_Mq.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-B2-uBp6-.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CZLTApPU.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user