fix: implement ref-based fullscreen element tracking for proper persistence
- Update FullscreenContext to use ref-based element tracking instead of document.documentElement - Add setFullscreenElement function to register specific DOM elements for fullscreen - Update arcade page to register its main div as the fullscreen target element - Update memory matching game to register its main div as the fullscreen target element - Use element-specific fullscreen control instead of document-wide fullscreen This properly fixes fullscreen persistence when navigating between components by ensuring each component registers its specific container element as the fullscreen target, preventing fullscreen loss during navigation. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,20 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { css } from '../../../styled-system/css'
|
||||
import { EnhancedChampionArena } from '../../components/EnhancedChampionArena'
|
||||
import { FullscreenProvider, useFullscreen } from '../../contexts/FullscreenContext'
|
||||
|
||||
function ArcadeContent() {
|
||||
const { isFullscreen, enterFullscreen, exitFullscreen } = useFullscreen()
|
||||
const { isFullscreen, enterFullscreen, exitFullscreen, setFullscreenElement } = useFullscreen()
|
||||
const arcadeRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
// Register this component's main div as the fullscreen element
|
||||
if (arcadeRef.current) {
|
||||
setFullscreenElement(arcadeRef.current)
|
||||
}
|
||||
}, [setFullscreenElement])
|
||||
|
||||
useEffect(() => {
|
||||
// Check if we should enter fullscreen (from games page navigation)
|
||||
@@ -24,12 +32,14 @@ function ArcadeContent() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={css({
|
||||
minH: 'screen',
|
||||
background: 'linear-gradient(135deg, #0f0f23 0%, #1a1a3a 50%, #2d1b69 100%)',
|
||||
position: 'relative',
|
||||
overflow: 'hidden'
|
||||
})}>
|
||||
<div
|
||||
ref={arcadeRef}
|
||||
className={css({
|
||||
minH: 'screen',
|
||||
background: 'linear-gradient(135deg, #0f0f23 0%, #1a1a3a 50%, #2d1b69 100%)',
|
||||
position: 'relative',
|
||||
overflow: 'hidden'
|
||||
})}>
|
||||
{/* Animated background elements */}
|
||||
<div className={css({
|
||||
position: 'absolute',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { useMemoryPairs } from '../context/MemoryPairsContext'
|
||||
import { useFullscreen } from '../../../../contexts/FullscreenContext'
|
||||
import { SetupPhase } from './SetupPhase'
|
||||
@@ -10,7 +10,15 @@ import { css } from '../../../../../styled-system/css'
|
||||
|
||||
export function MemoryPairsGame() {
|
||||
const { state } = useMemoryPairs()
|
||||
const { enterFullscreen } = useFullscreen()
|
||||
const { enterFullscreen, setFullscreenElement } = useFullscreen()
|
||||
const gameRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
// Register this component's main div as the fullscreen element
|
||||
if (gameRef.current) {
|
||||
setFullscreenElement(gameRef.current)
|
||||
}
|
||||
}, [setFullscreenElement])
|
||||
|
||||
useEffect(() => {
|
||||
// Check if we should enter fullscreen (from URL parameter)
|
||||
@@ -21,8 +29,10 @@ export function MemoryPairsGame() {
|
||||
}, [enterFullscreen])
|
||||
|
||||
return (
|
||||
<div className={css({
|
||||
minHeight: '100vh',
|
||||
<div
|
||||
ref={gameRef}
|
||||
className={css({
|
||||
minHeight: '100vh',
|
||||
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
||||
padding: '20px',
|
||||
display: 'flex',
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
'use client'
|
||||
|
||||
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react'
|
||||
import React, { createContext, useContext, useState, useEffect, useRef, useCallback, ReactNode } from 'react'
|
||||
|
||||
interface FullscreenContextType {
|
||||
isFullscreen: boolean
|
||||
enterFullscreen: () => Promise<void>
|
||||
exitFullscreen: () => Promise<void>
|
||||
toggleFullscreen: () => Promise<void>
|
||||
setFullscreenElement: (element: HTMLElement | null) => void
|
||||
fullscreenElementRef: React.MutableRefObject<HTMLElement | null>
|
||||
}
|
||||
|
||||
const FullscreenContext = createContext<FullscreenContextType | null>(null)
|
||||
|
||||
export function FullscreenProvider({ children }: { children: ReactNode }) {
|
||||
const [isFullscreen, setIsFullscreen] = useState(false)
|
||||
const fullscreenElementRef = useRef<HTMLElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
const handleFullscreenChange = () => {
|
||||
@@ -32,9 +35,15 @@ export function FullscreenProvider({ children }: { children: ReactNode }) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
const setFullscreenElement = useCallback((element: HTMLElement | null) => {
|
||||
fullscreenElementRef.current = element
|
||||
}, [])
|
||||
|
||||
const enterFullscreen = async () => {
|
||||
try {
|
||||
const element = document.documentElement
|
||||
// Use the registered fullscreen element, fallback to document.documentElement
|
||||
const element = fullscreenElementRef.current || document.documentElement
|
||||
|
||||
if (element.requestFullscreen) {
|
||||
await element.requestFullscreen()
|
||||
} else if ((element as any).webkitRequestFullscreen) {
|
||||
@@ -78,7 +87,9 @@ export function FullscreenProvider({ children }: { children: ReactNode }) {
|
||||
isFullscreen,
|
||||
enterFullscreen,
|
||||
exitFullscreen,
|
||||
toggleFullscreen
|
||||
toggleFullscreen,
|
||||
setFullscreenElement,
|
||||
fullscreenElementRef
|
||||
}}>
|
||||
{children}
|
||||
</FullscreenContext.Provider>
|
||||
|
||||
Reference in New Issue
Block a user