fluttercommunity / wakelock_plus

Flutter plugin that allows you to keep the device screen awake on Android, iOS, macOS, Windows, Linux, and web.
BSD 3-Clause "New" or "Revised" License
71 stars 54 forks source link

Loading of no_sleep.js does not respect assetBase #19

Open Blutchie opened 9 months ago

Blutchie commented 9 months ago

I'm using a package that depends on wakelock_plus, and on the first attempt to make a web build it seemed to work fine. However, our app is designed to be embedded into other web applications and when doing so it broke because it returned a 404 not found when trying to load no_sleep.js. This is because it tries to load it from the root of the domain instead of the assetBase.

I analyzed the generated main.dart.js and fixed it locally after the built. I first thought it was a bug in Flutter and have been searching in existing issues. I found something similar and posted a comment. But then a member of the Flutter team pointed to me that this was not their code, but part of this package, and advised to use the getAssetUrl API.

Below the link of his comment with some additional details: https://github.com/flutter/flutter/issues/121417#issuecomment-1945212351

diegotori commented 9 months ago

@Blutchie do you have an angle on what needs to be modified in no_sleep.js in order to make this work?

Blutchie commented 9 months ago

Hi @diegotori, I just read your question. Sadly I don't know except for what you already changed based on the other comment. I'm pretty new to Flutter, I just started to work on my first project, normally I work on .NET projects..

gabrielginter commented 3 months ago

Hi, I'm having the same issue, sadly this prevents use cases like "embedded mode" (multi-view mode) or loading assets through a CDN.

I believe the method importJsLibrary in file wakelock_plus/lib/src/web_impl/import_js_library.dart should use rootBundle.load('assets....

rootBundle should take care of pointing to the correct baseUrl set with assetBase.

If you release a version, I'll be happy to test it.

gabrielginter commented 3 months ago

I'm gonna correct myself here, what you need is to resolve the URL, not load the asset, so rootBundle won't help.

After looking at other plugins that perform a similar action (fluttertoast here), it seems that removing the ./ from the url in _libraryUrl and using assetManager.getAssetUrl would fix the issue, so the function would look something like:

String _libraryUrl(String url, String pluginName) {
  if (url.startsWith('./')) {
    url = url.replaceFirst('./', '');
  }

  if (url.startsWith('assets/')) {
    return ui.assetManager.getAssetUrl(
      'packages/$pluginName/$url',
    );
  }

  return url;
}

I tested this in release mode (with a CDN as assetBase) and debug mode, both work correctly.