Fixed iPad swipe down gesture to exit fullscreen

This commit is contained in:
2025-11-07 16:35:39 -05:00
parent e08833e71c
commit 5c77376272
2 changed files with 163 additions and 36 deletions
+28
View File
@@ -362,3 +362,31 @@ body.fullscreen-active .main-wrapper {
transition: none !important; transition: none !important;
} }
} }
/* Prevent pull-to-refresh and overscroll on touch devices in fullscreen */
.fullscreen-mode {
overscroll-behavior: none;
-webkit-overflow-scrolling: touch;
}
body.fullscreen-active {
overscroll-behavior: none;
position: fixed;
width: 100%;
height: 100%;
overflow: hidden;
}
/* Ensure content is scrollable within fullscreen container */
.fullscreen-mode {
overflow-y: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
}
/* Prevent iOS Safari bounce effect */
.fullscreen-mode,
.fullscreen-mode * {
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
+103 -4
View File
@@ -50,7 +50,13 @@ function enterFullscreen(container, icon, body) {
button.setAttribute('title', 'Exit Fullscreen'); button.setAttribute('title', 'Exit Fullscreen');
} }
// Try to use native fullscreen API if available // Detect if device is touch-enabled (iPad/tablet)
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
// Only use native fullscreen API on non-touch devices
// This prevents swipe-down gesture from exiting fullscreen on iPad
if (!isTouchDevice) {
// Try to use native fullscreen API for desktop browsers
if (container.requestFullscreen) { if (container.requestFullscreen) {
container.requestFullscreen().catch(err => { container.requestFullscreen().catch(err => {
console.log('Native fullscreen not available, using CSS fullscreen'); console.log('Native fullscreen not available, using CSS fullscreen');
@@ -68,12 +74,18 @@ function enterFullscreen(container, icon, body) {
console.log('Native fullscreen not available, using CSS fullscreen'); console.log('Native fullscreen not available, using CSS fullscreen');
}); });
} }
} else {
console.log('Touch device detected - using CSS-only fullscreen to prevent swipe-down exit');
}
// Adjust table layout for better viewing // Adjust table layout for better viewing
adjustTableForFullscreen(true); adjustTableForFullscreen(true);
// Save fullscreen preference // Save fullscreen preference
saveFullscreenPreference(true); saveFullscreenPreference(true);
// Prevent default touch behaviors that might interfere
preventSwipeGestures(container, true);
} }
/** /**
@@ -94,7 +106,10 @@ function exitFullscreen(container, icon, body) {
button.setAttribute('title', 'Toggle Fullscreen'); button.setAttribute('title', 'Toggle Fullscreen');
} }
// Exit native fullscreen if active // Exit native fullscreen if active (only for desktop)
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
if (!isTouchDevice) {
if (document.exitFullscreen) { if (document.exitFullscreen) {
document.exitFullscreen().catch(err => { document.exitFullscreen().catch(err => {
console.log('Native fullscreen exit not needed'); console.log('Native fullscreen exit not needed');
@@ -112,12 +127,90 @@ function exitFullscreen(container, icon, body) {
console.log('Native fullscreen exit not needed'); console.log('Native fullscreen exit not needed');
}); });
} }
}
/**
* Prevent swipe gestures from interfering with fullscreen on touch devices
*/
function preventSwipeGestures(container, enable) {
if (enable) {
// Prevent pull-to-refresh and other touch gestures
container.addEventListener('touchstart', handleTouchStart, { passive: false });
container.addEventListener('touchmove', handleTouchMove, { passive: false });
container.addEventListener('touchend', handleTouchEnd, { passive: false });
// Prevent overscroll
document.body.style.overscrollBehavior = 'none';
container.style.overscrollBehavior = 'none';
console.log('Swipe gestures prevented for fullscreen mode');
} else {
// Re-enable normal touch behavior
container.removeEventListener('touchstart', handleTouchStart);
container.removeEventListener('touchmove', handleTouchMove);
container.removeEventListener('touchend', handleTouchEnd);
// Restore overscroll
document.body.style.overscrollBehavior = '';
container.style.overscrollBehavior = '';
console.log('Swipe gestures re-enabled');
}
}
// Touch event handlers
let touchStartY = 0;
let touchStartX = 0;
function handleTouchStart(e) {
touchStartY = e.touches[0].clientY;
touchStartX = e.touches[0].clientX;
}
function handleTouchMove(e) {
if (!isFullscreen) return;
const touchY = e.touches[0].clientY;
const touchX = e.touches[0].clientX;
const deltaY = touchY - touchStartY;
const deltaX = touchX - touchStartX;
const container = document.getElementById('attendanceReportContainer');
const scrollTop = container.scrollTop;
const scrollHeight = container.scrollHeight;
const clientHeight = container.clientHeight;
const isAtTop = scrollTop === 0;
const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1;
// Prevent pull-down-to-refresh when at top
if (isAtTop && deltaY > 0) {
e.preventDefault();
return false;
}
// Prevent overscroll at bottom
if (isAtBottom && deltaY < 0) {
e.preventDefault();
return false;
}
// Allow normal scrolling within the container
// Don't prevent default for vertical scrolling when not at boundaries
}
function handleTouchEnd(e) {
touchStartY = 0;
touchStartX = 0;
}
// Restore table layout // Restore table layout
adjustTableForFullscreen(false); adjustTableForFullscreen(false);
// Save fullscreen preference // Save fullscreen preference
saveFullscreenPreference(false); saveFullscreenPreference(false);
// Re-enable default touch behaviors
preventSwipeGestures(container, false);
} }
/** /**
@@ -194,9 +287,15 @@ function logFullscreenAction(action) {
} }
/** /**
* Handle native fullscreen change events * Handle native fullscreen change events (only for desktop)
*/ */
function handleFullscreenChange() { function handleFullscreenChange() {
// Skip handling on touch devices since we're not using native fullscreen there
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
if (isTouchDevice) {
return;
}
const isNativeFullscreen = !!( const isNativeFullscreen = !!(
document.fullscreenElement || document.fullscreenElement ||
document.webkitFullscreenElement || document.webkitFullscreenElement ||
@@ -204,7 +303,7 @@ function handleFullscreenChange() {
document.msFullscreenElement document.msFullscreenElement
); );
// Sync our state with native fullscreen // Sync our state with native fullscreen (desktop only)
if (!isNativeFullscreen && isFullscreen) { if (!isNativeFullscreen && isFullscreen) {
// User exited native fullscreen, update our state // User exited native fullscreen, update our state
const container = document.getElementById('attendanceReportContainer'); const container = document.getElementById('attendanceReportContainer');