no-sleep-app
Version:
NoSleepApp is a lightweight JavaScript library that prevents devices from going to sleep during critical activities. It uses the Screen Wake Lock API or a fallback video playback method to keep the screen active, ensuring uninterrupted user experiences ac
206 lines (175 loc) • 7.23 kB
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: index.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: index.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
* @fileoverview NoSleepApp is a utility for preventing devices from sleeping
* by leveraging different strategies depending on platform capabilities.
*/
import VisibilityListener from './visibility-listener.js';
import NoSleepElement from './no-sleep-element.js';
import { isOldIOS } from './detect.js';
/**
* Determines if the native Wake Lock API is supported.
* @returns {boolean} True if Wake Lock API is supported.
*/
const isNativeWakeLockSupported = () => "wakeLock" in navigator;
/**
* NoSleepApp prevents devices from entering sleep mode.
* It uses the Wake Lock API, older iOS hacks, or video playback depending on device support.
*/
export default class NoSleepApp {
/**
* @param {Object} options Configuration options for NoSleepApp.
* @param {'wakeLock'|'video'|'legacy'} [options.strategy='wakeLock'] The strategy to use for preventing sleep.
* @param {number} [options.retryInterval=10000] Interval to retry enabling Wake Lock if it fails (in milliseconds).
* @param {boolean} [options.fallbackEnabled=true] Whether to enable fallback mechanisms if Wake Lock is not available.
*/
constructor(options = {}) {
const defaultOptions = {
strategy: 'wakeLock', // Default strategy is wakeLock
retryInterval: 10000, // Default retry interval is 10 seconds
fallbackEnabled: true, // Default fallback is enabled
};
this.options = { ...defaultOptions, ...options };
/**
* @type {boolean} Indicates whether NoSleepApp is currently enabled.
*/
this.enabled = false;
if (isNativeWakeLockSupported() && this.options.strategy === 'wakeLock') {
/** @type {WakeLockSentinel|null} The active Wake Lock instance. */
this._wakeLock = null;
/** @type {VisibilityListener|null} Listener for visibility changes to re-enable Wake Lock. */
this.visibilityListener = new VisibilityListener(this.enable.bind(this));
} else if (isOldIOS() && this.options.strategy === 'legacy') {
/** @type {number|null} Timer ID for the iOS hack to prevent sleep. */
this.noSleepTimer = null;
} else {
/** @type {NoSleepElement} Video element for non-iOS and non-Wake Lock devices. */
this.noSleepElement = new NoSleepElement();
this.noSleepElement.setMetadataListener();
}
}
/**
* Checks if NoSleepApp is enabled.
* @returns {boolean} True if NoSleepApp is enabled.
*/
get isEnabled() {
return this.enabled;
}
/**
* Enables the NoSleepApp functionality.
* Uses the Wake Lock API, older iOS hack, or video playback as appropriate.
* @returns {Promise<void>} Resolves when enabling is complete.
* @throws {Error} Throws an error if enabling fails.
*/
async enable() {
if (this.options.strategy === 'wakeLock' && isNativeWakeLockSupported()) {
try {
this._wakeLock = await navigator.wakeLock.request("screen");
this.enabled = true;
console.log("Wake Lock active.");
this._wakeLock.addEventListener("release", this._onWakeLockRelease);
} catch (err) {
this.enabled = false;
console.error(`${err.name}, ${err.message}`);
throw err;
}
} else if (this.options.strategy === 'legacy' && isOldIOS()) {
this._enableOldIOS();
} else if (this.options.strategy === 'video') {
await this._enableVideoPlayback();
}
}
/**
* Handles Wake Lock release events.
* @private
*/
_onWakeLockRelease() {
console.log("Wake Lock released.");
}
/**
* Enables the older iOS-specific hack to prevent sleep.
* This hack repeatedly refreshes the page.
* @private
*/
_enableOldIOS() {
this.disable();
console.warn("NoSleep enabled for older iOS devices. This can interrupt active network requests.");
this.noSleepTimer = setInterval(() => {
if (!document.hidden) {
window.location.href = window.location.href.split("#")[0];
setTimeout(window.stop, 0);
}
}, 15000);
this.enabled = true;
}
/**
* Enables video playback to prevent sleep on devices without Wake Lock or old iOS.
* @private
* @returns {Promise<void>} Resolves when video playback is successfully started.
* @throws {Error} Throws an error if video playback fails.
*/
async _enableVideoPlayback() {
try {
await this.noSleepElement.play();
this.enabled = true;
} catch (err) {
this.enabled = false;
console.error("Failed to start video playback:", err);
throw err;
}
}
/**
* Disables NoSleepApp functionality.
* Stops Wake Lock, iOS hack, or video playback depending on the platform.
*/
disable() {
if (this.options.strategy === 'wakeLock' && isNativeWakeLockSupported()) {
if (this._wakeLock) {
this._wakeLock.release();
}
this._wakeLock = null;
if (this.visibilityListener) {
this.visibilityListener.removeListeners();
}
} else if (this.options.strategy === 'legacy' && isOldIOS()) {
if (this.noSleepTimer) {
console.warn("NoSleep disabled for older iOS devices.");
clearInterval(this.noSleepTimer);
this.noSleepTimer = null;
}
} else if (this.options.strategy === 'video') {
this.noSleepElement.pause();
}
this.enabled = false;
}
}</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="module.exports.html">exports</a></li></ul><h3>Global</h3><ul><li><a href="global.html#disable">disable</a></li><li><a href="global.html#enable">enable</a></li><li><a href="global.html#handleFullscreenChange">handleFullscreenChange</a></li><li><a href="global.html#handleVisibilityChange">handleVisibilityChange</a></li><li><a href="global.html#isEnabled">isEnabled</a></li><li><a href="global.html#isNativeWakeLockSupported">isNativeWakeLockSupported</a></li><li><a href="global.html#isOldIOS">isOldIOS</a></li><li><a href="global.html#pause">pause</a></li><li><a href="global.html#play">play</a></li><li><a href="global.html#removeListeners">removeListeners</a></li><li><a href="global.html#setMetadataListener">setMetadataListener</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.4</a> on Fri Nov 22 2024 23:19:12 GMT+0000 (Greenwich Mean Time)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>