Improve fullscreen and swipe handling

- Lock mobile body scroll when swipe controls are enabled
- Enhance Tetris fullscreen sizing to fill viewport and adjust 2P label glow
- Invert 2P glow styling for Tetris 2P label with secondary color glow

X-Lovable-Edit-ID: edt-c94fddac-d6de-42a5-b52b-a7c31abb2519
This commit is contained in:
gpt-engineer-app[bot]
2026-02-03 10:00:58 +00:00
2 changed files with 20 additions and 3 deletions
+9
View File
@@ -41,6 +41,12 @@ export const useSwipeControls = ({
useEffect(() => {
if (!enabled) return;
// Lock body scroll when swipe controls are enabled
const prevOverflow = document.body.style.overflow;
const prevTouchAction = document.body.style.touchAction;
document.body.style.overflow = 'hidden';
document.body.style.touchAction = 'none';
const handleTouchStart = (e: TouchEvent) => {
const touch = e.touches[0];
swipeStateRef.current = {
@@ -99,6 +105,9 @@ export const useSwipeControls = ({
document.removeEventListener('touchstart', handleTouchStart);
document.removeEventListener('touchend', handleTouchEnd);
document.removeEventListener('touchcancel', handleTouchCancel);
// Restore body scroll
document.body.style.overflow = prevOverflow;
document.body.style.touchAction = prevTouchAction;
};
}, [enabled, minSwipeDistance, fastSwipeThreshold]);
+11 -3
View File
@@ -132,8 +132,16 @@ const Tetris = () => {
const maxHeight = window.innerHeight - 320;
return Math.min(Math.floor(maxWidth / BOARD_WIDTH), Math.floor(maxHeight / BOARD_HEIGHT), 20);
}
if (gameMode === '2p') return isFullscreen ? 26 : 22;
return isFullscreen ? 34 : 28;
if (isFullscreen) {
// Dynamic sizing based on viewport - same as other games
const availableWidth = window.innerWidth - (gameMode === '2p' ? 400 : 280);
const availableHeight = window.innerHeight - 120;
const cellFromWidth = Math.floor(availableWidth / (gameMode === '2p' ? BOARD_WIDTH * 2 + 4 : BOARD_WIDTH));
const cellFromHeight = Math.floor(availableHeight / BOARD_HEIGHT);
return Math.min(cellFromWidth, cellFromHeight, gameMode === '2p' ? 32 : 40);
}
if (gameMode === '2p') return 22;
return 28;
}, [isFullscreen, gameMode]);
const [cellSize, setCellSize] = useState(getCellSize);
@@ -550,7 +558,7 @@ const Tetris = () => {
<div className="flex items-center gap-4">
<button onClick={() => { setGameMode(null); setGameStarted(false); }} className="font-pixel text-sm text-foreground/50 hover:text-primary transition-colors">{'<'} Back</button>
<h1 className="font-minecraft text-2xl md:text-3xl text-primary text-glow-strong">
Tetris {gameMode === '2p' && <span className="text-secondary">2P</span>}
Tetris {gameMode === '2p' && <span className="text-secondary" style={{ textShadow: '0 0 10px hsl(var(--secondary) / 0.8), 0 0 20px hsl(var(--secondary) / 0.4)' }}>2P</span>}
</h1>
</div>
<button onClick={toggleFullscreen} className="p-2 border border-primary/50 hover:bg-primary/20 transition-colors" title={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}>