disable screen lock
This commit is contained in:
@@ -17,6 +17,7 @@ Game enthusiasts who play turn-based games (board games, tabletop RPGs, card gam
|
||||
* **JavaScript:** For application logic, timer functionality, and event handling.
|
||||
* **Web Audio API:** For audio feedback (ticking sounds, alerts).
|
||||
* **Browser API:** For capturing Players' photo.
|
||||
* **Screen Wake Lock API:** For preventing of the screen lock in a PWA.
|
||||
* **Local Storage/IndexedDB:** For persistent storage of player data, timer states, and settings.
|
||||
* **Service Worker:** Essential for PWA functionality (offline access, push notifications - potential future feature).
|
||||
* **Manifest File:** Defines the PWA's metadata (name, icons, theme color).
|
||||
@@ -125,7 +126,7 @@ For an enhanced tactile experience, Nexus Timer supports Smart Buttons based on
|
||||
}
|
||||
```
|
||||
## Building for the production
|
||||
Navigate to your project directory on the server
|
||||
Navigate to the projects' directory on the server
|
||||
```bash
|
||||
cd /virt
|
||||
```
|
||||
@@ -154,7 +155,7 @@ Use the editor to create or overwrite the service:
|
||||
```bash
|
||||
sudo systemctl edit --force --full virt-nexus-timer.service
|
||||
```
|
||||
Paste the contents from virt-nexus-timer.service, then save and exit.
|
||||
Paste the content from `systemd/virt-nexus-timer.service`, then save and exit.
|
||||
|
||||
Enable on system boot and start the service
|
||||
```bash
|
||||
|
||||
@@ -41,14 +41,13 @@
|
||||
"Pass Turn / My Pause" Hotkey:
|
||||
</label>
|
||||
<div class="flex items-center">
|
||||
<!-- Display field - not an input anymore, triggers overlay -->
|
||||
<button
|
||||
type="button"
|
||||
id="playerHotkeyDisplay"
|
||||
@click="startCapturePlayerHotkey"
|
||||
class="input-base w-12 h-8 text-center font-mono text-lg p-0 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700"
|
||||
class="input-base w-12 h-8 font-mono text-lg p-0 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 flex items-center justify-center"
|
||||
>
|
||||
{{ editablePlayer.hotkey ? editablePlayer.hotkey.toUpperCase() : '-' }}
|
||||
<span>{{ editablePlayer.hotkey ? editablePlayer.hotkey.toUpperCase() : '-' }}</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
66
src/services/WakeLockService.js
Normal file
66
src/services/WakeLockService.js
Normal file
@@ -0,0 +1,66 @@
|
||||
// src/services/WakeLockService.js
|
||||
let wakeLock = null;
|
||||
let wakeLockActive = false;
|
||||
|
||||
const requestWakeLock = async () => {
|
||||
if ('wakeLock' in navigator && !wakeLockActive) {
|
||||
try {
|
||||
wakeLock = await navigator.wakeLock.request('screen');
|
||||
wakeLockActive = true;
|
||||
console.log('Screen Wake Lock activated.');
|
||||
|
||||
wakeLock.addEventListener('release', () => {
|
||||
console.log('Screen Wake Lock was released.');
|
||||
wakeLockActive = false;
|
||||
wakeLock = null; // Clear the reference
|
||||
// Optionally, re-request if it was released unexpectedly and should be active
|
||||
// For now, we'll let it be re-requested manually by the app logic
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`Failed to acquire Screen Wake Lock: ${err.name}, ${err.message}`);
|
||||
wakeLock = null;
|
||||
wakeLockActive = false;
|
||||
}
|
||||
} else {
|
||||
console.warn('Screen Wake Lock API not supported or already active.');
|
||||
}
|
||||
};
|
||||
|
||||
const releaseWakeLock = async () => {
|
||||
if (wakeLock && wakeLockActive) {
|
||||
try {
|
||||
await wakeLock.release();
|
||||
// The 'release' event listener on wakeLock itself will set wakeLockActive = false and wakeLock = null
|
||||
} catch (err) {
|
||||
console.error(`Failed to release Screen Wake Lock: ${err.name}, ${err.message}`);
|
||||
// Even if release fails, mark as inactive to allow re-request
|
||||
wakeLock = null;
|
||||
wakeLockActive = false;
|
||||
}
|
||||
} else {
|
||||
// console.log('No active Screen Wake Lock to release or already released.');
|
||||
}
|
||||
};
|
||||
|
||||
// Handle visibility changes to re-acquire lock if necessary
|
||||
const handleVisibilityChange = () => {
|
||||
if (wakeLock !== null && document.visibilityState === 'visible') {
|
||||
// If we had a wake lock and the page became visible again,
|
||||
// it might have been released by the browser. Try to re-acquire.
|
||||
// This behavior is usually handled automatically by the browser with the 'release' event
|
||||
// but can be a fallback. For now, we rely on manual re-request.
|
||||
// console.log('Page visible, checking wake lock status.');
|
||||
} else if (document.visibilityState === 'hidden' && wakeLockActive) {
|
||||
// The browser usually releases the wake lock when tab is hidden.
|
||||
// Our 'release' event listener should handle this.
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('visibilitychange', handleVisibilityChange);
|
||||
// document.addEventListener('fullscreenchange', handleVisibilityChange); // Also useful for fullscreen
|
||||
|
||||
export const WakeLockService = {
|
||||
request: requestWakeLock,
|
||||
release: releaseWakeLock,
|
||||
isActive: () => wakeLockActive,
|
||||
};
|
||||
@@ -83,6 +83,7 @@ import { useRouter } from 'vue-router';
|
||||
import PlayerDisplay from '../components/PlayerDisplay.vue';
|
||||
import PlayerListItem from '../components/PlayerListItem.vue';
|
||||
import { AudioService } from '../services/AudioService';
|
||||
import { WakeLockService } from '../services/WakeLockService';
|
||||
|
||||
const store = useStore();
|
||||
const router = useRouter();
|
||||
@@ -93,7 +94,7 @@ const currentPlayer = computed(() => store.getters.currentPlayer);
|
||||
const nextPlayer = computed(() => store.getters.nextPlayer);
|
||||
const gameMode = computed(() => store.getters.gameMode);
|
||||
const isMuted = computed(() => store.getters.isMuted);
|
||||
// const gameRunning = computed(() => store.getters.gameRunning);
|
||||
const gameRunning = computed(() => store.getters.gameRunning);
|
||||
|
||||
let timerInterval = null;
|
||||
|
||||
@@ -130,12 +131,42 @@ onMounted(() => {
|
||||
timerInterval = setInterval(() => {
|
||||
store.dispatch('tick');
|
||||
}, 1000);
|
||||
|
||||
// Attempt to acquire wake lock if game is already running (e.g., page refresh)
|
||||
if (gameRunning.value) {
|
||||
WakeLockService.request();
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
onUnmounted(async () => {
|
||||
clearInterval(timerInterval);
|
||||
AudioService.stopContinuousTick();
|
||||
AudioService.cancelPassTurnSound();
|
||||
await WakeLockService.release(); // Release wake lock when leaving the game view
|
||||
});
|
||||
|
||||
// Watch gameRunning state to acquire/release wake lock
|
||||
watch(gameRunning, async (isRunning) => {
|
||||
if (isRunning) {
|
||||
await WakeLockService.request();
|
||||
} else {
|
||||
// Don't release immediately on pause, only if all timers stop and stay stopped.
|
||||
// For simplicity, we'll rely on onUnmounted for now or if explicitly navigating away.
|
||||
// If you want to release on extended pause, you'd need more logic here.
|
||||
// Perhaps only release if gameMode is normal and current player is paused,
|
||||
// or if allTimers mode and ALL are paused.
|
||||
// For now, aggressive release on any gameRunning=false might be too much.
|
||||
// Let's only release it when navigating away or explicitly stopped.
|
||||
// The browser will also release it if the tab is hidden.
|
||||
// Let's make it simpler: release if game isn't running
|
||||
if (!WakeLockService.isActive()) return; // Avoid releasing if not active
|
||||
// A short delay before releasing to avoid flickering if quickly pausing/resuming
|
||||
setTimeout(async () => {
|
||||
if (!store.getters.gameRunning && WakeLockService.isActive()) { // Check again before releasing
|
||||
await WakeLockService.release();
|
||||
}
|
||||
}, 3000); // e.g., release after 3 seconds of no activity
|
||||
}
|
||||
});
|
||||
|
||||
watch(gameMode, (newMode) => {
|
||||
@@ -180,7 +211,8 @@ watch(() => currentPlayer.value?.isTimerRunning, (isRunning, wasRunning) => {
|
||||
});
|
||||
|
||||
|
||||
const navigateToSetup = () => {
|
||||
const navigateToSetup = async () => {
|
||||
await WakeLockService.release(); // Release before navigating
|
||||
const isAnyTimerActive = store.getters.gameRunning;
|
||||
if (isAnyTimerActive) {
|
||||
if (window.confirm('Game is active. Going to Setup will pause all timers. Continue?')) {
|
||||
@@ -192,9 +224,10 @@ const navigateToSetup = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const navigateToInfo = () => {
|
||||
const navigateToInfo = async () => {
|
||||
await WakeLockService.release(); // Release before navigating
|
||||
if (store.getters.gameRunning) {
|
||||
store.commit('PAUSE_ALL_TIMERS');
|
||||
store.commit('PAUSE_ALL_TIMERS'); // Good practice to pause if navigating away
|
||||
}
|
||||
router.push({ name: 'Info' });
|
||||
};
|
||||
|
||||
@@ -72,9 +72,9 @@
|
||||
type="button"
|
||||
id="globalHotkeyStopPauseDisplay"
|
||||
@click="startCaptureGlobalHotkey('stopPause')"
|
||||
class="input-base w-12 h-8 text-center font-mono text-lg p-0 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700"
|
||||
class="input-base w-12 h-8 font-mono text-lg p-0 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 flex items-center justify-center"
|
||||
>
|
||||
{{ globalHotkeyStopPauseDisplay || '-' }}
|
||||
<span>{{ globalHotkeyStopPauseDisplay || '-' }}</span>
|
||||
</button>
|
||||
<button type="button" @click="clearGlobalHotkey('stopPause')" class="text-xs text-blue-500 hover:underline ml-2 px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-600">
|
||||
Clear
|
||||
@@ -91,9 +91,9 @@
|
||||
type="button"
|
||||
id="globalHotkeyRunAllDisplay"
|
||||
@click="startCaptureGlobalHotkey('runAll')"
|
||||
class="input-base w-12 h-8 text-center font-mono text-lg p-0 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700"
|
||||
class="input-base w-12 h-8 font-mono text-lg p-0 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 flex items-center justify-center"
|
||||
>
|
||||
{{ globalHotkeyRunAllDisplay || '-' }}
|
||||
<span>{{ globalHotkeyRunAllDisplay || '-' }}</span>
|
||||
</button>
|
||||
<button type="button" @click="clearGlobalHotkey('runAll')" class="text-xs text-blue-500 hover:underline ml-2 px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-600">
|
||||
Clear
|
||||
|
||||
Reference in New Issue
Block a user