Skip to content
This repository has been archived by the owner on Oct 10, 2020. It is now read-only.

Web support #194

Open
wants to merge 9 commits into
base: 3.x
Choose a base branch
from
Open

Web support #194

wants to merge 9 commits into from

Conversation

fercarcedo
Copy link

@fercarcedo fercarcedo commented Mar 17, 2020

This PR introduces web support, using the JsQRScanner JavaScript library.

The interface is implemented in HTML and CSS and tries to resemble as much as possible the one found on the mobile versions.

As a limitation, this web version doesn't support enabling the flashlight. In order to check if a device has a flashlight and enable it, we need to use the ImageCapture class which, at the time of opening this PR, has support problems with Firefox and Safari. It also doesn't seem to offer the ability to turn off the flashlight once turned on (once you request the flashlight to be turned on this seems to stick to the current video track session and it's on until you start a whole new track).

This PR is implemented as a separate plugin. This seems to be the way to do it, as this post details https://medium.com/flutter/how-to-write-a-flutter-web-plugin-5e26c689ea1 (given the fact that this plugin does not follow the federated style). If you want it implemented in any other way, let me know :)

Closes #190

@fercarcedo fercarcedo changed the base branch from master to 3.x March 17, 2020 17:07
@fercarcedo fercarcedo force-pushed the web-support branch 2 times, most recently from 460b2a1 to 45b2c47 Compare March 17, 2020 17:22
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
document.querySelector('head').append(script);
script.setAttribute('src', 'https://cdn.jsdelivr.net/gh/jbialobr/JsQRScanner@master/war/js/jsqrscanner.nocache.js');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

External JavaScript should be embedded in the plugin.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have moved the script to a local js file embedded in the plugin, as well as extracted the CSS styles into its own separate file. Oddly enough, previous attempts of embedding the JS file failed, but now it's all working fine

@treeder
Copy link

treeder commented Mar 17, 2020

Initial test seems to work!

One big issue though, the camera doesn't turn off after the scan completes. I believe this might be related: jbialobr/JsQRScanner#23

@fercarcedo
Copy link
Author

Initial test seems to work!

One big issue though, the camera doesn't turn off after the scan completes. I believe this might be related: jbialobr/JsQRScanner#23

I'm going to take a look at it, thank you!

@fercarcedo
Copy link
Author

Now the camera seems to be closing as expected. @treeder could you check again?

@treeder
Copy link

treeder commented Mar 17, 2020

Yep, shuts camera down now. 👍

@devtronic
Copy link
Member

Great job, thank you. Unfortunately I'm currently working in a long term project so the review process will take a bit more time. I'll review this PR asap.

@fercarcedo
Copy link
Author

Don't worry. Thank you!

@treeder
Copy link

treeder commented Mar 17, 2020

FYI, to test this, use this in pubspec.yaml:

  barcode_scan:
  barcode_scan_web:
    git:
      url: git://github.com/fercarcedo/flutter_barcode_reader.git
      ref: web-support
      path: flutter_barcode_reader_web/

@treeder
Copy link

treeder commented Mar 17, 2020

Something seems to be going wrong when you make a production build, it can't find the qrcode scanner js file I believe, getting a 404 page instead.

image

@treeder
Copy link

treeder commented Mar 19, 2020

I'm guessing these assets needs to be defined in your pubspec.yaml @fercarcedo : https://flutter.dev/docs/development/ui/assets-and-images#bundling-of-package-assets

They aren't in the build/web folder after a flutter build web.

@fercarcedo
Copy link
Author

I'm guessing these assets needs to be defined in your pubspec.yaml @fercarcedo : https://flutter.dev/docs/development/ui/assets-and-images#bundling-of-package-assets

They aren't in the build/web folder after a flutter build web.

I'm going to try again later today, but yesterday I tried placing the files in an asset folder and referencing them in pubspec.yaml (assets/jsqrscanner.nocache.js) and also by leaving them where they are now (inside lib/assets) and in pubspec.yaml registering them with packages/barcode_scan_web/assets/jsqrscanner.nocache.js , but both approaches failed.

Thank you for taking time to investigate

@fercarcedo
Copy link
Author

fercarcedo commented Mar 19, 2020

An update on this: I have managed to solve this issue. Turns out that, in addition to having to register the assets in pubspec.yaml, you need to reference them from HTML as assets/packages/package_name/assets (I was using packages/package_name/assets, without the leading assets/, which was somehow working fine on debug builds).

But now there is a different problem which I'll take more time to investigate: the jsqrscanner library reports an error, but only when working on release mode
imagen

@treeder
Copy link

treeder commented Mar 20, 2020

@fercarcedo Not trying to tell you how to work here, but would you mind not force-pushing to this pull request? Makes it hard to figure out what you changed (and less important, breaks builds that use those lost commits). They can (and most likely will) squash and merge or rebase and merge your pull request anyways.

@treeder
Copy link

treeder commented Mar 20, 2020

The asset thing I found weird too, I'm not sure if it's just for flutter web, but it doesn't seem to match the documentation. If you put them in the assets directory, then I think you get what happened to you, it'll add a second assets folder in the build/web directory like this:

image

I found I had to do the following to make it feel right and get images to show up:

Create an images folder in the root directory, alongside pubspec.yaml, then in pubspec.yaml:

  assets:
    - images/
    - images/logos/

Then to use them:

image: AssetImage('images/logos/abc.png'),

🤷‍♂

@treeder
Copy link

treeder commented Mar 20, 2020

@devtronic I'm fairly new to flutter, but is embedding the JS rather than linking to a CDN the recommended way to do it for these web components? I couldn't find any discussions on this topic.

@treeder
Copy link

treeder commented Mar 20, 2020

I'm getting an error in dev mode now too:

image

Unfortunately can't help debugging because I don't know what changed since the working commits are gone.

@fercarcedo
Copy link
Author

fercarcedo commented Mar 20, 2020

That's weird, I didn't encounter this issue in dev mode, but if you want you can try again with the new commit. I've replaced the minified version of JsQRScanner I was using previously with the unminified one, in order to be able to see the errors more crearly. The issue you're facing is weird, since I'm using allowInterop in order to expose the Dart function scannerReady to JS.

Regarding force-pushing, I was performing them since they were simple additions and I thought no one was reviewing the commits just yet. Since you are looking at it now, I'll make new commits from now on :)

I've opened an issue on the JsQRScanner repo because I'm starting to think it may be a problem with the library itself (worst case scenario I'll simply use another library and update this PR with it). jbialobr/JsQRScanner#24

@treeder
Copy link

treeder commented Mar 20, 2020

Nope, not working:

image

This all worked fine yesterday though, just not in production. Maybe something else you changed is causing these issues? Can you rollback to when it worked, then start from there again?

@fercarcedo
Copy link
Author

fercarcedo commented Mar 20, 2020

Unfortunately, I can't reproduce the issue. I'm trying it with the same code in pubspec.yaml you mentioned:

barcode_scan:
barcode_scan_web:
    git:
      url: git://github.com/fercarcedo/flutter_barcode_reader.git
      ref: web-support
      path: flutter_barcode_reader_web/  

And everything works fine in debug mode. The only thing I changed after it worked for you was to move the assets files and reference them in pubspec.yaml (but it shouldn't be causing this issue, since given your stacktrace it's finding the library correctly, but it seems it isn't exposing the dart function correctly, although the line that exposes it it's intact). That's weird.

Could you try cleaning up your browser cache in order to see if it makes a difference?

@treeder
Copy link

treeder commented Mar 20, 2020

I'm actually hardcoding the commits now:

  barcode_scan_web:
    git:
      url: git://github.com/fercarcedo/flutter_barcode_reader.git
      ref: 44841ca3db925fe4136778d9b65e3275094e54f8
      path: flutter_barcode_reader_web/

Can you try that and see if it still works? Wonder if you're still using an older version.

@fercarcedo
Copy link
Author

I just tried it and it still works. Also I looked into the build/web folder to see the bundled assets inside assets/packages/barcode_scan_web and I verified that the jsqrscanner.nocache.js file is the unminified one, so it appears to be using the latest version. Also, if you look at the commit you can see right there on the dart file the call to allowInterop, so this error seems weird...

@treeder
Copy link

treeder commented Mar 20, 2020

I did a flutter clean and a complete rebuild and still getting the most recent error above with the allowInterop. 🤷‍♂

@treeder
Copy link

treeder commented Mar 20, 2020

Any chance you still have your history from when it was working?

I put the cdn source back in to ensure it's not the local assets, but got the same allowInterop issue. Then I had to change line 87 to this to get past the allowInterop issue:

    _scanner = JsQRScanner(allowInterop(onQRCodeScanned), allowInterop(provideVideo));

But now I'm getting this from the scan:

image

There has to be something else that changed other than the asset locations.

@fercarcedo
Copy link
Author

I'll take a look at it, I'll keep you updated

@treeder
Copy link

treeder commented Jun 12, 2020

@fercarcedo can you try a rebase on this?

@fercarcedo
Copy link
Author

Yes, I have a rebase in progress, but I think I have to modify the code to handle the new callbacks introduced. I'm not sure if this weekend I'll have time to implement this, but next week definitely, so I'll keep you updated

@brockmcblockchain
Copy link

any update on this @fercarcedo ?

@fercarcedo
Copy link
Author

Yes, I had some time over the weekend to work on the rebase. In fact I'm finishing it up right now :) (currently I'm modifying the code to make use of the newly added Options api). Then if it continues to work properly I'll update this PR. I'll keep you updated, but shouldn't take long :)

@brockmcblockchain
Copy link

Awesome! thanks for the update!

@treeder
Copy link

treeder commented Jul 15, 2020

Hey @fercarcedo , how goes it? :)

@fercarcedo
Copy link
Author

fercarcedo commented Jul 15, 2020

I need to finish up the handling of some callbacks (for example, the permissions granted event, which has some problems right now), as well as to test everything again to make sure there are no regressions. Over the week of course I have less time than over the weekend, but everything seems to be progressing nicely. I expect this rebase to be finished during the course of the week :) Will keep you updated

@fercarcedo
Copy link
Author

Update: added remaining callback handling and fixed errors. What I have to complete now is the ability to specify which camera to use (as opposed to always using the rear camera right now) and check that everything still works as expected. It's very likely that this PR will be updated tomorrow

@fercarcedo
Copy link
Author

fercarcedo commented Jul 20, 2020

Another update: I need to do some more testing before updating the PR, but now the rebase is complete and everything seems to be working as expected. So tomorrow I'll update this PR if there are no problems found during testing :)

@fercarcedo
Copy link
Author

Rebase completed 🚀 🚀

@brockmcblockchain
Copy link

@devtronic @treeder care to take a look?

sdk: flutter
js: ^0.6.0
barcode_scan:
path: ../
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this leftover from development? It's causing problems during pub get for me:

Running "flutter pub get" in flutter...                         
Error on line 13, column 11: Invalid description in the "barcode_scan_web" pubspec on the "barcode_scan" dependency: "../" is a relative path, but this isn't a local pubspec.



13 │     path: ../ 

   │           ^^^


pub get failed (65;    ╵)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I still haven't figured out a way to have this work without it. The reason this is needed is the fact that I needed to modify some code in the general plugin code (platform-wrapper specifically) and so I need to use that modified version of the plugin. I'm not that experienced into Dart, so if you could shed some light on this I would really appreciate it :)

@treeder
Copy link

treeder commented Jul 27, 2020

I'm not sure what the expected behavior is for this anymore now that there's a ScanResult.type, but something is off. When a user cancels a scan, it throws a PlatformException that looks like this: PlatformException(USER_CANCELED, User closed the scan window, null). The problem is you can't check the type because it throws and there's not BarcodeScanner.userCancelled anymore.

@fercarcedo
Copy link
Author

Good point. I just checked again the ScanResult proto and it seems likely that the expected behavior would be to return a ScanResult of type Cancelled

@fercarcedo
Copy link
Author

Based on the Android source code of the plugin, I can confirm that indeed the expected behavior is to return a ScanResult of type Cancelled, and also that the remaining PlatformExceptions need to be converted to a ScanResult of type Error. I'm going to work on this later today and update this pull request

@treeder
Copy link

treeder commented Jul 28, 2020

Seems strange to me that it would return an error type and not throw an error. 🤷‍♂️ I asked that here too: #269

Do you know how to check an error message, ie: what caused the failure?

@fercarcedo
Copy link
Author

fercarcedo commented Jul 28, 2020

Seems strange to me too, but it's implemented that way in the Android source code. You can check out the ScanResultHandler.kt file, it returns an error type with the error as the rawContent.

Also, if you look at the README of the 3.x branch they assume a ScanResult is always returned (previously there were multiple catch blocks for the different exception types).

My understanding from the code is that you can get the error code from the rawContent of the ScanResult and then compare that to the various constants exposed through BarcodeScanner

@fercarcedo
Copy link
Author

PR updated :) I'm returning ScanResult for both errors and cancellations, with exactly the same code as the Android plugin

@brockmcblockchain
Copy link

@devtronic can we get a merge if it looks good to you?

@RicardoHds
Copy link

Any updates that how to use web support? I tried your options @fercarcedo @treeder but also have the same errors, also using the example folder.
Capture

And in my project
image

@treeder
Copy link

treeder commented Aug 10, 2020

@fercarcedo needs to remove relative path he has in the pubspec.

@treeder
Copy link

treeder commented Aug 10, 2020

Made a PR here: fercarcedo#1

@SetNameHere
Copy link

Hi,
first of all thanks for your work.
Is there any news on this? It would be really great to have web support for this package to use it in flutter PWAs

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Web support
9 participants