Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Do not merge!) Poked around wakelock_plus (web) #25

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
41 changes: 19 additions & 22 deletions wakelock_plus/lib/src/wakelock_plus_web_plugin.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:async';

import 'package:flutter_web_plugins/flutter_web_plugins.dart';
import 'package:js/js.dart';
import 'package:js/js_util.dart';
import 'package:wakelock_plus_platform_interface/wakelock_plus_platform_interface.dart';
import 'package:wakelock_plus/src/web_impl/import_js_library.dart';
import 'package:wakelock_plus/src/web_impl/js_wakelock.dart'
Expand All @@ -11,39 +11,36 @@ import 'package:wakelock_plus/src/web_impl/js_wakelock.dart'
///
/// This class implements the `wakelock_plus` plugin functionality for web.
class WakelockPlusWebPlugin extends WakelockPlusPlatformInterface {
/// Builds an instance of the plugin, and imports the JS implementation.
WakelockPlusWebPlugin() {
_jsLoaded = importJsLibrary(
url: 'packages/wakelock_plus/assets/no_sleep.js', flutterPluginName: 'wakelock_plus');
}

// The future that signals when the JS is loaded.
// This needs to be `await`ed before accessing any methods of the
// JS-interop layer.
Future<void>? _jsLoaded;

/// Registers [WakelockPlusWebPlugin] as the default instance of the
/// [WakelockPlatformInterface].
static void registerWith(Registrar registrar) {
// Import a version of `NoSleep.js` that was adjusted for the wakelock
// plugin.
importJsLibrary(
url: 'assets/no_sleep.js', flutterPluginName: 'wakelock_plus');

WakelockPlusPlatformInterface.instance = WakelockPlusWebPlugin();
}

@override
Future<void> toggle({required bool enable}) async {
// Await _jsLoaded before accessing wakelock_plus_web
await _jsLoaded!;

wakelock_plus_web.toggle(enable);
}

@override
Future<bool> get enabled async {
final completer = Completer<bool>();

wakelock_plus_web.enabled().then(
// onResolve
allowInterop((value) {
assert(value is bool);

completer.complete(value);
}),
// onReject
allowInterop((error) {
completer.completeError(error);
}),
);

return completer.future;
await _jsLoaded!;

// Can be simplified a lot
return promiseToFuture(wakelock_plus_web.enabled());
}
}
40 changes: 27 additions & 13 deletions wakelock_plus/lib/src/web_impl/import_js_library.dart
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
import 'dart:html' as html;
import 'dart:ui_web' as ui_web;

/// This is an implementation of the `import_js_library` plugin that is used
/// until that plugin is migrated to null safety.
/// See https://github.com/florent37/flutter_web_import_js_library/pull/6#issuecomment-735349208.

/// Imports a JS script file from the given [url] given the relative
/// [flutterPluginName].
void importJsLibrary({required String url, String? flutterPluginName}) {
///
/// Returns a Future that resolves when the library is loaded.
Future<void> importJsLibrary({required String url, String? flutterPluginName}) {
if (flutterPluginName == null) {
_importJSLibraries([url]);
} else {
_importJSLibraries([_libraryUrl(url, flutterPluginName)]);
return _importJSLibraries([url]);
}
return _importJSLibraries([_libraryUrl(url, flutterPluginName)]);
}

String _libraryUrl(String url, String pluginName) {
if (url.startsWith('./')) {
url = url.replaceFirst('./', '');
return './assets/packages/$pluginName/$url';
}
if (url.startsWith('assets/')) {
return './assets/packages/$pluginName/$url';
} else {
return url;
}
return ui_web.assetManager.getAssetUrl(url);
//
// TODO: Fix this properly!
//
// if (url.startsWith('./')) {
// url = url.replaceFirst('./', '');
// return './assets/packages/$pluginName/$url';
// }
// if (url.startsWith('assets/')) {
// return './assets/packages/$pluginName/$url';
// } else {
// return url;
// }
}

html.ScriptElement _createScriptTag(String library) {
Expand All @@ -46,6 +52,14 @@ Future<void> _importJSLibraries(List<String> libraries) {
final scriptTag = _createScriptTag(library);
head!.children.add(scriptTag);
loading.add(scriptTag.onLoad.first);
// Recommended: add an onError listener to know that something
// went wrong here, rather than swallowing the problem.
scriptTag.onError.listen((html.Event e) {
final String src = (e.target as html.ScriptElement).src;
loading.add(Future.error(
Exception('Error loading: $src')
));
});
}
}

Expand Down
3 changes: 2 additions & 1 deletion wakelock_plus/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,5 @@ flutter:
# https://flutter.dev/custom-fonts/#from-packages

assets:
- assets/no_sleep.js
- lib/assets/no_sleep.js
- packages/wakelock_plus/assets/no_sleep.js
13 changes: 13 additions & 0 deletions wakelock_plus/test/wakelock_plus_web_plugin_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ import 'package:wakelock_plus/src/wakelock_plus_web_plugin.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import 'package:wakelock_plus_platform_interface/wakelock_plus_platform_interface.dart';

// This test could be run with:
// flutter run test --platform chrome
// But there's something weird about the JS not loading.
//
// The test can be manually run with:
// flutter run -d chrome test/wakelock_plus_web_plugin_test.dart
// or:
// with -d web-server to run it in other browsers.
void main() {
group('$WakelockPlusWebPlugin', () {
setUpAll(() async {
Expand All @@ -28,6 +36,7 @@ void main() {
});

test('disable', () async {
await WakelockPlus.enable();
await WakelockPlus.disable();
expect(WakelockPlus.enabled, completion(isFalse));
});
Expand All @@ -36,6 +45,10 @@ void main() {
await WakelockPlus.toggle(enable: true);
expect(WakelockPlus.enabled, completion(isTrue));

// toggle(false) fails after toggle(true).
// (This seems like a no_sleep.js issue.)
// You can see this same failure by calling `WakelockPlus.enable()`
// right before `disable()` in the test above.
await WakelockPlus.toggle(enable: false);
expect(WakelockPlus.enabled, completion(isFalse));
});
Expand Down
Loading