Yaroslav

Removed dynamic load of js libraries, added web setup to README.md

... ... @@ -53,6 +53,12 @@ Ensure that you granted camera permission in XCode -> Signing & Capabilities:
<img width="696" alt="Screenshot of XCode where Camera is checked" src="https://user-images.githubusercontent.com/24459435/193464115-d76f81d0-6355-4cb2-8bee-538e413a3ad0.png">
## Web
This package uses ZXing on web to read barcodes so it needs to be included in `index.html` as script.
```html
<script src="https://unpkg.com/@zxing/library@0.19.1" type="application/javascript"/>
```
## Usage
Import `package:mobile_scanner/mobile_scanner.dart`, and use the widget with or without the controller.
... ...
... ... @@ -8,7 +8,6 @@ import 'package:mobile_scanner/mobile_scanner_web.dart';
import 'package:mobile_scanner/src/barcode_utility.dart';
import 'package:mobile_scanner/src/enums/camera_facing.dart';
import 'package:mobile_scanner/src/objects/barcode.dart';
import 'package:mobile_scanner/src/web/utils.dart';
/// This plugin is the web implementation of mobile_scanner.
/// It only supports QR codes.
... ... @@ -26,8 +25,6 @@ class MobileScannerWebPlugin {
);
final MobileScannerWebPlugin instance = MobileScannerWebPlugin();
_jsLibrariesLoadingFuture = injectJSLibraries(barCodeReader.jsLibraries);
channel.setMethodCallHandler(instance.handleMethodCall);
event.setController(instance.controller);
}
... ... @@ -55,11 +52,8 @@ class MobileScannerWebPlugin {
ZXingBarcodeReader(videoContainer: vidDiv);
StreamSubscription? _barCodeStreamSubscription;
static late Future _jsLibrariesLoadingFuture;
/// Handle incomming messages
Future<dynamic> handleMethodCall(MethodCall call) async {
await _jsLibrariesLoadingFuture;
switch (call.method) {
case 'start':
return _start(call.arguments as Map);
... ...
... ... @@ -39,9 +39,6 @@ abstract class WebBarcodeReaderBase {
int get videoWidth;
int get videoHeight;
/// JS libraries to be injected into html page.
List<JsLibrary> get jsLibraries;
/// Starts streaming video
Future<void> start({
required CameraFacing cameraFacing,
... ...
... ... @@ -20,12 +20,6 @@ class Code {
external Uint8ClampedList get binaryData;
}
const jsqrLibrary = JsLibrary(
contextName: 'jsQR',
url: 'https://cdn.jsdelivr.net/npm/jsqr@1.4.0/dist/jsQR.min.js',
usesRequireJs: true,
);
/// Barcode reader that uses jsQR library.
/// jsQR supports only QR codes format.
class JsQrCodeReader extends WebBarcodeReaderBase
... ... @@ -36,9 +30,6 @@ class JsQrCodeReader extends WebBarcodeReaderBase
bool get isStarted => localMediaStream != null;
@override
List<JsLibrary> get jsLibraries => [jsqrLibrary];
@override
Future<void> start({
required CameraFacing cameraFacing,
List<BarcodeFormat>? formats,
... ...
import 'dart:async';
import 'dart:html' as html;
import 'dart:js' show JsObject, context;
import 'package:mobile_scanner/src/web/base.dart';
Future<void> loadScript(JsLibrary library) async {
dynamic amd;
dynamic define;
// ignore: avoid_dynamic_calls
if (library.usesRequireJs && context['define']?['amd'] != null) {
// In dev, requireJs is loaded in. Disable it here.
// see https://github.com/dart-lang/sdk/issues/33979
define = JsObject.fromBrowserObject(context['define'] as Object);
// ignore: avoid_dynamic_calls
amd = define['amd'];
// ignore: avoid_dynamic_calls
define['amd'] = false;
}
try {
await loadScriptUsingScriptTag(library.url);
} finally {
if (amd != null) {
// Re-enable requireJs
// ignore: avoid_dynamic_calls
define['amd'] = amd;
}
}
}
Future<void> loadScriptUsingScriptTag(String url) {
final script = html.ScriptElement()
..async = true
..defer = false
..crossOrigin = 'anonymous'
..type = 'text/javascript'
// ignore: unsafe_html
..src = url;
html.document.head!.append(script);
return script.onLoad.first;
}
/// Injects JS [libraries]
///
/// Returns a [Future] that resolves when all of the `script` tags `onLoad` events trigger.
Future<void> injectJSLibraries(List<JsLibrary> libraries) {
final List<Future<void>> loading = [];
for (final library in libraries) {
final future = loadScript(library);
loading.add(future);
}
return Future.wait(loading);
}
... ... @@ -168,12 +168,6 @@ extension JsZXingBrowserMultiFormatReaderExt
external MediaStream? stream;
}
const zxingJsLibrary = JsLibrary(
contextName: 'ZXing',
url: 'https://unpkg.com/@zxing/library@0.19.1',
usesRequireJs: true,
);
/// Barcode reader that uses zxing-js library.
class ZXingBarcodeReader extends WebBarcodeReaderBase
with InternalStreamCreation, InternalTorchDetection {
... ... @@ -185,9 +179,6 @@ class ZXingBarcodeReader extends WebBarcodeReaderBase
bool get isStarted => localMediaStream != null;
@override
List<JsLibrary> get jsLibraries => [zxingJsLibrary];
@override
Future<void> start({
required CameraFacing cameraFacing,
List<BarcodeFormat>? formats,
... ...