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
@@ -361,4 +361,32 @@ body.fullscreen-active .main-wrapper {
animation: none !important; animation: none !important;
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);
} }
+135 -36
View File
@@ -50,23 +50,32 @@ 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)
if (container.requestFullscreen) { const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
container.requestFullscreen().catch(err => {
console.log('Native fullscreen not available, using CSS fullscreen'); // Only use native fullscreen API on non-touch devices
}); // This prevents swipe-down gesture from exiting fullscreen on iPad
} else if (container.webkitRequestFullscreen) { if (!isTouchDevice) {
container.webkitRequestFullscreen().catch(err => { // Try to use native fullscreen API for desktop browsers
console.log('Native fullscreen not available, using CSS fullscreen'); if (container.requestFullscreen) {
}); container.requestFullscreen().catch(err => {
} else if (container.mozRequestFullScreen) { console.log('Native fullscreen not available, using CSS fullscreen');
container.mozRequestFullScreen().catch(err => { });
console.log('Native fullscreen not available, using CSS fullscreen'); } else if (container.webkitRequestFullscreen) {
}); container.webkitRequestFullscreen().catch(err => {
} else if (container.msRequestFullscreen) { console.log('Native fullscreen not available, using CSS fullscreen');
container.msRequestFullscreen().catch(err => { });
console.log('Native fullscreen not available, using CSS fullscreen'); } else if (container.mozRequestFullScreen) {
}); container.mozRequestFullScreen().catch(err => {
console.log('Native fullscreen not available, using CSS fullscreen');
});
} else if (container.msRequestFullscreen) {
container.msRequestFullscreen().catch(err => {
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
@@ -74,6 +83,9 @@ function enterFullscreen(container, icon, body) {
// Save fullscreen preference // Save fullscreen preference
saveFullscreenPreference(true); saveFullscreenPreference(true);
// Prevent default touch behaviors that might interfere
preventSwipeGestures(container, true);
} }
/** /**
@@ -94,30 +106,111 @@ 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)
if (document.exitFullscreen) { const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
document.exitFullscreen().catch(err => {
console.log('Native fullscreen exit not needed'); if (!isTouchDevice) {
}); if (document.exitFullscreen) {
} else if (document.webkitExitFullscreen) { document.exitFullscreen().catch(err => {
document.webkitExitFullscreen().catch(err => { console.log('Native fullscreen exit not needed');
console.log('Native fullscreen exit not needed'); });
}); } else if (document.webkitExitFullscreen) {
} else if (document.mozCancelFullScreen) { document.webkitExitFullscreen().catch(err => {
document.mozCancelFullScreen().catch(err => { console.log('Native fullscreen exit not needed');
console.log('Native fullscreen exit not needed'); });
}); } else if (document.mozCancelFullScreen) {
} else if (document.msExitFullscreen) { document.mozCancelFullScreen().catch(err => {
document.msExitFullscreen().catch(err => { console.log('Native fullscreen exit not needed');
console.log('Native fullscreen exit not needed'); });
}); } else if (document.msExitFullscreen) {
document.msExitFullscreen().catch(err => {
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');