Navaron Bracke

remove the old zxing bindings

1 -import 'dart:async';  
2 -import 'dart:html';  
3 -import 'dart:typed_data';  
4 -import 'dart:ui';  
5 -  
6 -import 'package:js/js.dart';  
7 -import 'package:mobile_scanner/src/enums/barcode_format.dart';  
8 -import 'package:mobile_scanner/src/enums/camera_facing.dart';  
9 -import 'package:mobile_scanner/src/objects/barcode.dart';  
10 -import 'package:mobile_scanner/src/web/base.dart';  
11 -  
12 -@JS('ZXing.BrowserMultiFormatReader')  
13 -@staticInterop  
14 -class JsZXingBrowserMultiFormatReader {  
15 - /// https://github.com/zxing-js/library/blob/1e9ccb3b6b28d75b9eef866dba196d8937eb4449/src/browser/BrowserMultiFormatReader.ts#L11  
16 - external factory JsZXingBrowserMultiFormatReader(  
17 - dynamic hints,  
18 - int timeBetweenScansMillis,  
19 - );  
20 -}  
21 -  
22 -@JS()  
23 -@anonymous  
24 -abstract class ResultPoint {  
25 - /// The x coordinate of the point.  
26 - external double get x;  
27 -  
28 - /// The y coordinate of the point.  
29 - external double get y;  
30 -}  
31 -  
32 -@JS()  
33 -@anonymous  
34 -abstract class Result {  
35 - /// raw text encoded by the barcode  
36 - external String get text;  
37 -  
38 - /// Returns raw bytes encoded by the barcode, if applicable, otherwise null  
39 - external Uint8ClampedList? get rawBytes;  
40 -  
41 - /// Representing the format of the barcode that was decoded  
42 - external int? format;  
43 -  
44 - /// Returns the result points of the barcode. These points represent the corners of the barcode.  
45 - external List<Object?> get resultPoints;  
46 -}  
47 -  
48 -extension ResultExt on Result {  
49 - Barcode toBarcode() {  
50 - final corners = resultPoints  
51 - .cast<ResultPoint>()  
52 - .map((ResultPoint rp) => Offset(rp.x, rp.y))  
53 - .toList();  
54 -  
55 - final rawBytes = this.rawBytes;  
56 - return Barcode(  
57 - rawValue: text,  
58 - rawBytes: rawBytes != null ? Uint8List.fromList(rawBytes) : null,  
59 - format: barcodeFormat,  
60 - corners: corners,  
61 - );  
62 - }  
63 -  
64 - /// https://github.com/zxing-js/library/blob/1e9ccb3b6b28d75b9eef866dba196d8937eb4449/src/core/BarcodeFormat.ts#L28  
65 - BarcodeFormat get barcodeFormat {  
66 - switch (format) {  
67 - case 0:  
68 - return BarcodeFormat.aztec;  
69 - case 1:  
70 - return BarcodeFormat.codebar;  
71 - case 2:  
72 - return BarcodeFormat.code39;  
73 - case 3:  
74 - return BarcodeFormat.code93;  
75 - case 4:  
76 - return BarcodeFormat.code128;  
77 - case 5:  
78 - return BarcodeFormat.dataMatrix;  
79 - case 6:  
80 - return BarcodeFormat.ean8;  
81 - case 7:  
82 - return BarcodeFormat.ean13;  
83 - case 8:  
84 - return BarcodeFormat.itf;  
85 - // case 9:  
86 - // return BarcodeFormat.maxicode;  
87 - case 10:  
88 - return BarcodeFormat.pdf417;  
89 - case 11:  
90 - return BarcodeFormat.qrCode;  
91 - // case 12:  
92 - // return BarcodeFormat.rss14;  
93 - // case 13:  
94 - // return BarcodeFormat.rssExp;  
95 - case 14:  
96 - return BarcodeFormat.upcA;  
97 - case 15:  
98 - return BarcodeFormat.upcE;  
99 - default:  
100 - return BarcodeFormat.unknown;  
101 - }  
102 - }  
103 -}  
104 -  
105 -extension ZXingBarcodeFormat on BarcodeFormat {  
106 - int get zxingBarcodeFormat {  
107 - switch (this) {  
108 - case BarcodeFormat.aztec:  
109 - return 0;  
110 - case BarcodeFormat.codabar:  
111 - return 1;  
112 - case BarcodeFormat.code39:  
113 - return 2;  
114 - case BarcodeFormat.code93:  
115 - return 3;  
116 - case BarcodeFormat.code128:  
117 - return 4;  
118 - case BarcodeFormat.dataMatrix:  
119 - return 5;  
120 - case BarcodeFormat.ean8:  
121 - return 6;  
122 - case BarcodeFormat.ean13:  
123 - return 7;  
124 - case BarcodeFormat.itf:  
125 - return 8;  
126 - case BarcodeFormat.pdf417:  
127 - return 10;  
128 - case BarcodeFormat.qrCode:  
129 - return 11;  
130 - case BarcodeFormat.upcA:  
131 - return 14;  
132 - case BarcodeFormat.upcE:  
133 - return 15;  
134 - case BarcodeFormat.unknown:  
135 - case BarcodeFormat.all:  
136 - default:  
137 - return -1;  
138 - }  
139 - }  
140 -}  
141 -  
142 -typedef BarcodeDetectionCallback = void Function(  
143 - Result? result,  
144 - dynamic error,  
145 -);  
146 -  
147 -extension JsZXingBrowserMultiFormatReaderExt  
148 - on JsZXingBrowserMultiFormatReader {  
149 - external Promise<void> decodeFromVideoElementContinuously(  
150 - VideoElement source,  
151 - BarcodeDetectionCallback callbackFn,  
152 - );  
153 -  
154 - /// Continuously decodes from video input  
155 - external void decodeContinuously(  
156 - VideoElement element,  
157 - BarcodeDetectionCallback callbackFn,  
158 - );  
159 -  
160 - external Promise<void> decodeFromStream(  
161 - MediaStream stream,  
162 - VideoElement videoSource,  
163 - BarcodeDetectionCallback callbackFn,  
164 - );  
165 -  
166 - external Promise<void> decodeFromConstraints(  
167 - dynamic constraints,  
168 - VideoElement videoSource,  
169 - BarcodeDetectionCallback callbackFn,  
170 - );  
171 -  
172 - external void stopContinuousDecode();  
173 -  
174 - external VideoElement prepareVideoElement(VideoElement videoSource);  
175 -  
176 - /// Defines what the [videoElement] src will be.  
177 - external void addVideoSource(  
178 - VideoElement videoElement,  
179 - MediaStream stream,  
180 - );  
181 -  
182 - external bool isVideoPlaying(VideoElement video);  
183 -  
184 - external void reset();  
185 -  
186 - /// The HTML video element, used to display the camera stream.  
187 - external VideoElement? videoElement;  
188 -  
189 - /// The stream output from camera.  
190 - external MediaStream? stream;  
191 -}  
192 -  
193 -/// Barcode reader that uses zxing-js library.  
194 -class ZXingBarcodeReader extends WebBarcodeReaderBase  
195 - with InternalStreamCreation, InternalTorchDetection {  
196 - JsZXingBrowserMultiFormatReader? _reader;  
197 -  
198 - ZXingBarcodeReader({required super.videoContainer});  
199 -  
200 - @override  
201 - bool get isStarted => localMediaStream != null;  
202 -  
203 - @override  
204 - Future<void> start({  
205 - required CameraFacing cameraFacing,  
206 - List<BarcodeFormat>? formats,  
207 - Duration? detectionTimeout,  
208 - }) async {  
209 - final JsMap? hints;  
210 - if (formats != null && !formats.contains(BarcodeFormat.all)) {  
211 - hints = JsMap();  
212 - final zxingFormats =  
213 - formats.map((e) => e.zxingBarcodeFormat).where((e) => e > 0).toList();  
214 - // set hint DecodeHintType.POSSIBLE_FORMATS  
215 - // https://github.com/zxing-js/library/blob/1e9ccb3b6b28d75b9eef866dba196d8937eb4449/src/core/DecodeHintType.ts#L28  
216 - hints.set(2, zxingFormats);  
217 - } else {  
218 - hints = null;  
219 - }  
220 - if (detectionTimeout != null) {  
221 - frameInterval = detectionTimeout;  
222 - }  
223 - _reader = JsZXingBrowserMultiFormatReader(  
224 - hints,  
225 - frameInterval.inMilliseconds,  
226 - );  
227 - videoContainer.children = [video];  
228 -  
229 - final stream = await initMediaStream(cameraFacing);  
230 -  
231 - prepareVideoElement(video);  
232 - if (stream != null) {  
233 - await attachStreamToVideo(stream, video);  
234 - }  
235 - }  
236 -  
237 - @override  
238 - void prepareVideoElement(VideoElement videoSource) {  
239 - _reader?.prepareVideoElement(videoSource);  
240 - }  
241 -  
242 - @override  
243 - Future<void> attachStreamToVideo(  
244 - MediaStream stream,  
245 - VideoElement videoSource,  
246 - ) async {  
247 - _reader?.addVideoSource(videoSource, stream);  
248 - _reader?.videoElement = videoSource;  
249 - _reader?.stream = stream;  
250 - localMediaStream = stream;  
251 - await videoSource.play();  
252 - }  
253 -  
254 - StreamController<Barcode?>? controller;  
255 -  
256 - @override  
257 - Future<void> stopDetectBarcodeContinuously() async {  
258 - _reader?.stopContinuousDecode();  
259 - controller?.close();  
260 - controller = null;  
261 - }  
262 -  
263 - @override  
264 - Stream<Barcode?> detectBarcodeContinuously() {  
265 - controller ??= StreamController<Barcode?>();  
266 - controller!.onListen = () async {  
267 - _reader?.decodeContinuously(  
268 - video,  
269 - allowInterop((result, error) {  
270 - if (result != null) {  
271 - controller?.add(result.toBarcode());  
272 - }  
273 - }),  
274 - );  
275 - };  
276 - controller!.onCancel = () => stopDetectBarcodeContinuously();  
277 - return controller!.stream;  
278 - }  
279 -  
280 - @override  
281 - Future<void> stop() async {  
282 - _reader?.reset();  
283 - super.stop();  
284 - }  
285 -}