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

Commit

Permalink
Rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
fercarcedo committed Jul 21, 2020
1 parent e4f3599 commit f7c9dd0
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 12 deletions.
86 changes: 75 additions & 11 deletions flutter_barcode_reader_web/lib/barcode_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ library jsqrscanner;
import 'dart:async';
import 'dart:html';
import 'dart:js';
import 'dart:typed_data';

import 'package:barcode_scan/gen/protos/protos.pb.dart' as proto;

import 'package:flutter/services.dart';
import 'package:js/js.dart';
import 'package:js/js_util.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';

class BarcodeScanPlugin {
Completer<String> _completer;
Completer<Uint8List> _completer;
JsQRScanner _scanner;
int _useCamera = -1;
List<dynamic> _cameras = new List<dynamic>();

static void registerWith(Registrar registrar) {
final MethodChannel channel = MethodChannel(
Expand All @@ -24,7 +29,43 @@ class BarcodeScanPlugin {
channel.setMethodCallHandler(instance.handleMethodCall);
}

Future<String> handleMethodCall(MethodCall call) async {
Future<dynamic> handleMethodCall(MethodCall call) async {
switch (call.method) {
case "numberOfCameras": return getNumberOfCameras();
default: return callScan(call);
}
}

Future<int> getNumberOfCameras() {
Completer<int> completer = new Completer<int>();
_getCameras().then((cameras) => completer.complete(cameras.length));
return completer.future;
}

Future<Iterable<dynamic>> _getCameras() {
Completer<Iterable<dynamic>> completer = new Completer<Iterable<dynamic>>();
window.navigator.mediaDevices.enumerateDevices().then((devices) {
completer.complete(devices.where((device) => device.kind == 'videoinput'));
}).catchError((error) {
completer.complete([]);
});
return completer.future;
}

Future<Uint8List> callScan(MethodCall call) {
var config;
if (call.arguments is Uint8List) {
var buffer = call.arguments as Uint8List;
config = proto.Configuration.fromBuffer(buffer);
} else {
config = proto.Configuration()
..useCamera = -1;
}
return scan(config);
}

Future<Uint8List> scan(proto.Configuration config) {
_useCamera = config.useCamera;
_ensureMediaDevicesSupported();
_createCSS();
var script = document.createElement('script');
Expand All @@ -34,15 +75,15 @@ class BarcodeScanPlugin {
_createHTML();
document.querySelector('#toolbar p').addEventListener('click', (event) => _onCloseByUser());
setProperty(window, 'JsQRScannerReady', allowInterop(this.scannerReady));
_completer = new Completer<String>();
_completer = new Completer<Uint8List>();
return _completer.future;
}

void _ensureMediaDevicesSupported() {
if (window.navigator.mediaDevices == null) {
throw PlatformException(
code: 'CAMERA_ACCESS_NOT_SUPPORTED',
message: "Camera access not supported by browser2"
message: "Camera access not supported by browser"
);
}
}
Expand Down Expand Up @@ -79,7 +120,11 @@ class BarcodeScanPlugin {

void onQRCodeScanned(String scannedText) {
if (!_completer.isCompleted) {
_completer.complete(scannedText);
var scanResult = proto.ScanResult()
..type = proto.ResultType.Barcode
..format = proto.BarcodeFormat.qr
..rawContent = scannedText;
_completer.complete(scanResult.writeToBuffer());
_close();
}
}
Expand All @@ -101,14 +146,24 @@ class BarcodeScanPlugin {
}

void scannerReady() {
_scanner = JsQRScanner(allowInterop(this.onQRCodeScanned), allowInterop(this.provideVideo));
_scanner.setSnapImageMaxSize(300);
var scannerParentElement = document.getElementById('scanner');
_scanner.appendTo(scannerParentElement);
window.navigator.getUserMedia(video: true).then((stream) {
window.navigator.mediaDevices.enumerateDevices().then((devices) {
_cameras = devices.where((device) => device.kind == 'videoinput').toList();
_scanner = JsQRScanner(allowInterop(this.onQRCodeScanned), allowInterop(this.provideVideo));
_scanner.setSnapImageMaxSize(300);
var scannerParentElement = document.getElementById('scanner');
_scanner.appendTo(scannerParentElement);
}).catchError((onError) => _reject(onError));
}).catchError((onError) => _reject(onError));
}

Promise<MediaStream> provideVideo() {
var videoPromise = getUserMedia(new UserMediaOptions(video: new VideoOptions(facingMode: 'environment')));
var videoPromise;
if (_useCamera < 0) {
videoPromise = getUserMedia(new UserMediaOptions(video: new VideoOptions(facingMode: 'environment')));
} else {
videoPromise = getUserMedia(new UserMediaOptions(video: new VideoOptions(deviceId: new DeviceIdOptions(exact: _cameras[_useCamera].deviceId))));
}
videoPromise.then(null, allowInterop(_reject));
return videoPromise;
}
Expand Down Expand Up @@ -137,8 +192,17 @@ class UserMediaOptions {
@anonymous
class VideoOptions {
external String get facingMode;
external DeviceIdOptions get deviceId;

external factory VideoOptions({ String facingMode = null, DeviceIdOptions deviceId = null });
}

@JS()
@anonymous
class DeviceIdOptions {
external String get exact;

external factory VideoOptions({ String facingMode });
external factory DeviceIdOptions({ String exact });
}

@JS()
Expand Down
2 changes: 2 additions & 0 deletions flutter_barcode_reader_web/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ dependencies:
flutter_web_plugins:
sdk: flutter
js: ^0.6.0
barcode_scan:
path: ../

environment:
sdk: ">=2.0.0-dev.58.0 <3.0.0"
Expand Down
6 changes: 5 additions & 1 deletion lib/platform_wrapper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:io' show Platform;

import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';

import './model/model.dart';
import 'gen/protos/protos.pb.dart' as proto;
Expand All @@ -13,6 +14,9 @@ class BarcodeScanner {
/// If the user has granted the access to the camera this code is returned.
static const cameraAccessGranted = 'PERMISSION_GRANTED';

/// If the device does not support camera access this code is returned.
static const cameraAccessNotSupported = 'CAMERA_ACCESS_NOT_SUPPORTED';

/// If the user has not granted the access to the camera this code is thrown.
static const cameraAccessDenied = 'PERMISSION_NOT_GRANTED';

Expand All @@ -32,7 +36,7 @@ class BarcodeScanner {
ScanOptions options = const ScanOptions(),
}) async {
assert(options != null);
if (Platform.isIOS) {
if (kIsWeb || Platform.isIOS) {
return _doScan(options);
}

Expand Down

0 comments on commit f7c9dd0

Please sign in to comment.