1import { CodedError, Platform, Subscription } from 'expo-modules-core'; 2 3import { KeepAwakeEventState, KeepAwakeListener } from './KeepAwake.types'; 4 5const wakeLockMap: Record<string, WakeLockSentinel> = {}; 6 7type WakeLockSentinel = { 8 onrelease: null | ((event: any) => void); 9 released: boolean; 10 type: 'screen'; 11 release?: Function; 12 13 addEventListener?: (event: string, listener: (event: any) => void) => void; 14 removeEventListener?: (event: string, listener: (event: any) => void) => void; 15}; 16 17declare const navigator: { 18 wakeLock: { 19 request(type: 'screen'): Promise<WakeLockSentinel>; 20 }; 21}; 22 23/** Wraps the webWakeLock API https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API */ 24export default { 25 async isAvailableAsync() { 26 if (Platform.isDOMAvailable) { 27 return 'wakeLock' in navigator; 28 } 29 return false; 30 }, 31 async activate(tag: string) { 32 if (!Platform.isDOMAvailable) { 33 return; 34 } 35 const wakeLock = await navigator.wakeLock.request('screen'); 36 wakeLockMap[tag] = wakeLock; 37 }, 38 async deactivate(tag: string) { 39 if (!Platform.isDOMAvailable) { 40 return; 41 } 42 if (wakeLockMap[tag]) { 43 wakeLockMap[tag].release?.(); 44 delete wakeLockMap[tag]; 45 } else { 46 throw new CodedError( 47 'ERR_KEEP_AWAKE_TAG_INVALID', 48 `The wake lock with tag ${tag} has not activated yet` 49 ); 50 } 51 }, 52 addListenerForTag(tag: string, listener: KeepAwakeListener): Subscription { 53 const eventListener = () => { 54 listener({ state: KeepAwakeEventState.RELEASE }); 55 }; 56 const sentinel = wakeLockMap[tag]; 57 if (sentinel) { 58 if ('addEventListener' in sentinel) { 59 sentinel.addEventListener?.('release', eventListener); 60 } else { 61 sentinel.onrelease = eventListener; 62 } 63 } 64 return { 65 remove: () => { 66 const sentinel = wakeLockMap[tag]; 67 if (sentinel) { 68 if (sentinel.removeEventListener) { 69 sentinel.removeEventListener('release', eventListener); 70 } else { 71 sentinel.onrelease = null; 72 } 73 } 74 }, 75 }; 76 }, 77}; 78