Skip to content

Commit

Permalink
Revamped the no_sleep.js script to use a Promise-based Completer so t…
Browse files Browse the repository at this point in the history
…hat it awaits asynchronous calls from the various wakelock related callbacks. As a result, the Dart layer no longer needs to manually await before calling WakelockPlus.enabled.
  • Loading branch information
diegotori committed Dec 3, 2024
1 parent bd3e7a7 commit 4900aaf
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 47 deletions.
129 changes: 90 additions & 39 deletions wakelock_plus/lib/assets/no_sleep.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
class PromiseCompleter {
_promise;
_resolve;
_reject;
constructor() {
this._promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
}

isCompleted = false;

get future() {
return this._promise;
}

complete(value) {
this.isCompleted = true;
this._resolve(value);
}

completeError(error) {
this._reject(error);
}
}

var webm =
'data:video/webm;base64,GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA='
var mp4 =
Expand Down Expand Up @@ -46,21 +73,19 @@ var oldIOS =
var nativeWakeLock = 'wakeLock' in navigator

var NoSleep = (function () {
var _releasedNative = true
var _nativeRequestInProgress = false
var _nativeEnabledCompleter;
var _playVideoCompleter;

function NoSleep() {
var _this = this

_classCallCheck(this, NoSleep)

this.nativeEnabled = false
if (nativeWakeLock) {
this._wakeLock = null
var handleVisibilityChange = function handleVisibilityChange() {
if (
_this._wakeLock !== null &&
document.visibilityState === 'visible'
) {
if (_this._wakeLock !== null && document.visibilityState === 'visible') {
_this.enable()
}
}
Expand Down Expand Up @@ -106,27 +131,36 @@ var NoSleep = (function () {
},
{
key: 'enable',
value: function enable() {
value: async function enable() {
var _this2 = this

if (nativeWakeLock) {
_nativeRequestInProgress = true
await this.disable()
if (_nativeEnabledCompleter == null) {
_nativeEnabledCompleter = new PromiseCompleter()
}
navigator.wakeLock
.request('screen')
.then(function (wakeLock) {
_releasedNative = false
_nativeRequestInProgress = false

_this2._wakeLock = wakeLock
_this2.nativeEnabled = true
_nativeEnabledCompleter.complete()
_nativeEnabledCompleter = null
console.log("Wake Lock active.");
_this2._wakeLock.addEventListener('release', function () {
_releasedNative = true
_this2.nativeEnabled = false
_this2._wakeLock = null
console.log("Wake Lock released.");
})
})
.catch(function (err) {
_nativeRequestInProgress = false
console.error(err.name + ', ' + err.message)
_this2.nativeEnabled = false
var errorMessage = err.name + ', ' + err.message
console.error(errorMessage)
_nativeEnabledCompleter.completeError(errorMessage)
_nativeEnabledCompleter = null
})
return _nativeEnabledCompleter.future
} else if (oldIOS) {
this.disable()
console.warn(
Expand All @@ -138,17 +172,34 @@ var NoSleep = (function () {
window.setTimeout(window.stop, 0)
}
}, 15000)
return Promise.resolve()
} else {
this.noSleepVideo.play()
if (_playVideoCompleter == null) {
_playVideoCompleter = new PromiseCompleter()
}
var playPromise = this.noSleepVideo.play()
playPromise.then(function (res) {
_playVideoCompleter.complete()
_playVideoCompleter = null
}).catch(function (err) {
var errorMessage = err.name + ', ' + err.message
console.error(errorMessage)
_playVideoCompleter.completeError(errorMessage)
_playVideoCompleter = null
});
return _playVideoCompleter.future
}
},
},
{
key: 'disable',
value: function disable() {
value: async function disable() {
if (nativeWakeLock) {
if (_nativeEnabledCompleter != null) {
await _nativeEnabledCompleter.future
}
if (this._wakeLock != null) {
_releasedNative = true
this.nativeEnabled = false
this._wakeLock.release()
}

Expand All @@ -162,34 +213,29 @@ var NoSleep = (function () {
this.noSleepTimer = null
}
} else {
if (_playVideoCompleter != null) {
await _playVideoCompleter.future
}
this.noSleepVideo.pause()
}
return Promise.resolve();
},
},
{
key: 'enabled',
value: async function enabled() {
key: 'isEnabled',
value: async function isEnabled() {
if (nativeWakeLock) {
if (_nativeRequestInProgress == true) {
// Wait until the request is done.
while (true) {
// Wait for 42 milliseconds.
await new Promise((resolve, reject) => setTimeout(resolve, 42))
if (_nativeRequestInProgress == false) {
break
}
}
}

// todo: use WakeLockSentinel.released when that is available (https://developer.mozilla.org/en-US/docs/Web/API/WakeLockSentinel/released)
if (_releasedNative != false) {
return false
if (_nativeEnabledCompleter != null) {
await _nativeEnabledCompleter.future
}

return true
return this.nativeEnabled
} else if (oldIOS) {
return this.noSleepTimer != null
} else {
if (_playVideoCompleter != null) {
await _playVideoCompleter.future
}
if (this.noSleepVideo == undefined) {
return false
}
Expand All @@ -208,17 +254,22 @@ var noSleep = new NoSleep()
var Wakelock = {
enabled: async function () {
try {
return noSleep.enabled()
return noSleep.isEnabled()
} catch (e) {
return false
}
},
toggle: async function (enable) {
if (enable) {
noSleep.enable()
} else {
noSleep.disable()
try {
if (enable) {
await noSleep.enable()
} else {
await noSleep.disable()
}
} catch (e) {
throw e
}
return Promise.resolve()
},
}

Expand Down
14 changes: 13 additions & 1 deletion wakelock_plus/lib/src/wakelock_plus_web_plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,20 @@ class WakelockPlusWebPlugin extends WakelockPlusPlatformInterface {
Future<void> toggle({required bool enable}) async {
// Make sure the JS library is loaded before calling it.
await _ensureJsLoaded();
final completer = Completer<void>();

wakelock_plus_web.toggle(enable);
wakelock_plus_web.toggle(enable).toDart.then(
// onResolve
(value) {
completer.complete();
},
// onReject
onError: (error) {
completer.completeError(error);
},
);

return completer.future;
}

@override
Expand Down
2 changes: 1 addition & 1 deletion wakelock_plus/lib/src/web_impl/js_wakelock.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'dart:js_interop';

/// Toggles the JS wakelock.
@JS()
external void toggle(bool enable);
external JSPromise<JSAny?> toggle(bool enable);

/// Returns a JS promise of whether the wakelock is enabled or not.
@JS()
Expand Down
25 changes: 19 additions & 6 deletions wakelock_plus/test/wakelock_plus_web_plugin_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ void main() {
WakelockPlusPlatformInterface.instance = WakelockPlusWebPlugin();
});

tearDown(() async {
await WakelockPlus.disable();
});

test('$WakelockPlusWebPlugin set as default instance', () {
expect(
WakelockPlusPlatformInterface.instance, isA<WakelockPlusWebPlugin>());
Expand All @@ -28,23 +32,32 @@ void main() {

test('enable', () async {
await WakelockPlus.enable();
// Wait a bit for web to enable the wakelock
await Future.delayed(const Duration(milliseconds: 50));
expect(WakelockPlus.enabled, completion(isTrue));
});

test('enable more than once', () async {
await WakelockPlus.enable();
await WakelockPlus.enable();
await WakelockPlus.enable();
expect(WakelockPlus.enabled, completion(isTrue));
});

test('disable', () async {
await WakelockPlus.enable();
// Wait a bit for web to enable the wakelock
await Future.delayed(const Duration(milliseconds: 50));
await WakelockPlus.disable();
expect(WakelockPlus.enabled, completion(isFalse));
});

test('disable more than once', () async {
await WakelockPlus.enable();
await WakelockPlus.disable();
await WakelockPlus.disable();
await WakelockPlus.disable();
expect(WakelockPlus.enabled, completion(isFalse));
});

test('toggle', () async {
await WakelockPlus.toggle(enable: true);
// Wait a bit for web to enable the wakelock
await Future.delayed(const Duration(milliseconds: 50));
expect(WakelockPlus.enabled, completion(isTrue));

await WakelockPlus.toggle(enable: false);
Expand Down

0 comments on commit 4900aaf

Please sign in to comment.