Add wake lock toggle to prevent screen sleep on player display
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+40
-2
@@ -7,7 +7,7 @@ import {
|
|||||||
UserCheck, UserX, HeartCrack, HeartPulse, Zap, EyeOff, ExternalLink, AlertTriangle,
|
UserCheck, UserX, HeartCrack, HeartPulse, Zap, EyeOff, ExternalLink, AlertTriangle,
|
||||||
Play as PlayIcon, Pause as PauseIcon, SkipForward as SkipForwardIcon,
|
Play as PlayIcon, Pause as PauseIcon, SkipForward as SkipForwardIcon,
|
||||||
StopCircle as StopCircleIcon, Users2, Dices, ChevronUp, ChevronDown, ScrollText,
|
StopCircle as StopCircleIcon, Users2, Dices, ChevronUp, ChevronDown, ScrollText,
|
||||||
Maximize2, Minimize2
|
Maximize2, Minimize2, Moon, Coffee
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
// Custom CSS for death animation (player view only)
|
// Custom CSS for death animation (player view only)
|
||||||
@@ -2311,6 +2311,8 @@ function DisplayView() {
|
|||||||
const [campaignBackgroundUrl, setCampaignBackgroundUrl] = useState('');
|
const [campaignBackgroundUrl, setCampaignBackgroundUrl] = useState('');
|
||||||
const [isPlayerDisplayActive, setIsPlayerDisplayActive] = useState(false);
|
const [isPlayerDisplayActive, setIsPlayerDisplayActive] = useState(false);
|
||||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||||
|
const [wakeLockEnabled, setWakeLockEnabled] = useState(false);
|
||||||
|
const wakeLockRef = useRef(null);
|
||||||
const currentParticipantRef = useRef(null);
|
const currentParticipantRef = useRef(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -2327,6 +2329,33 @@ function DisplayView() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!wakeLockEnabled) {
|
||||||
|
wakeLockRef.current?.release();
|
||||||
|
wakeLockRef.current = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const acquire = async () => {
|
||||||
|
try {
|
||||||
|
wakeLockRef.current = await navigator.wakeLock.request('screen');
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Wake lock failed:', e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
acquire();
|
||||||
|
|
||||||
|
// Re-acquire after tab becomes visible again (browser auto-releases on hide)
|
||||||
|
const onVisChange = () => { if (document.visibilityState === 'visible') acquire(); };
|
||||||
|
document.addEventListener('visibilitychange', onVisChange);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('visibilitychange', onVisChange);
|
||||||
|
wakeLockRef.current?.release();
|
||||||
|
wakeLockRef.current = null;
|
||||||
|
};
|
||||||
|
}, [wakeLockEnabled]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!db) {
|
if (!db) {
|
||||||
setEncounterError("Firestore not available.");
|
setEncounterError("Firestore not available.");
|
||||||
@@ -2450,13 +2479,22 @@ function DisplayView() {
|
|||||||
className={`p-4 md:p-8 rounded-xl shadow-2xl ${!campaignBackgroundUrl ? 'bg-stone-950' : ''}`}
|
className={`p-4 md:p-8 rounded-xl shadow-2xl ${!campaignBackgroundUrl ? 'bg-stone-950' : ''}`}
|
||||||
style={displayStyles}
|
style={displayStyles}
|
||||||
>
|
>
|
||||||
|
<div className="fixed top-3 right-3 z-50 flex gap-2">
|
||||||
|
<button
|
||||||
|
onClick={() => setWakeLockEnabled(v => !v)}
|
||||||
|
title={wakeLockEnabled ? 'Allow sleep' : 'Prevent sleep'}
|
||||||
|
className={`p-2 rounded-lg transition-all ${wakeLockEnabled ? 'bg-amber-600 hover:bg-amber-700 text-white' : 'bg-stone-800 bg-opacity-80 hover:bg-opacity-100 text-stone-300 hover:text-white'}`}
|
||||||
|
>
|
||||||
|
{wakeLockEnabled ? <Coffee size={20} /> : <Moon size={20} />}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={toggleFullscreen}
|
onClick={toggleFullscreen}
|
||||||
title={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}
|
title={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}
|
||||||
className="fixed top-3 right-3 z-50 bg-stone-800 bg-opacity-80 hover:bg-opacity-100 text-stone-300 hover:text-white p-2 rounded-lg transition-all"
|
className="bg-stone-800 bg-opacity-80 hover:bg-opacity-100 text-stone-300 hover:text-white p-2 rounded-lg transition-all"
|
||||||
>
|
>
|
||||||
{isFullscreen ? <Minimize2 size={20} /> : <Maximize2 size={20} />}
|
{isFullscreen ? <Minimize2 size={20} /> : <Maximize2 size={20} />}
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
<div className={campaignBackgroundUrl ? 'bg-stone-950 bg-opacity-75 p-4 md:p-6 rounded-lg' : ''}>
|
<div className={campaignBackgroundUrl ? 'bg-stone-950 bg-opacity-75 p-4 md:p-6 rounded-lg' : ''}>
|
||||||
<h2 className="text-4xl md:text-5xl font-bold text-center text-amber-400 mb-2 font-cinzel tracking-wide">{name}</h2>
|
<h2 className="text-4xl md:text-5xl font-bold text-center text-amber-400 mb-2 font-cinzel tracking-wide">{name}</h2>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user