Julian Steenbakker
Committed by GitHub

Merge branch 'master' into support-multiple-formats-on-ios

  1 +# These owners will be the default owners for everything in
  2 +# the repo. Unless a later match takes precedence,
  3 +# review when someone opens a pull request.
  4 +# For more on how to customize the CODEOWNERS file - https://help.github.com/en/articles/about-code-owners
  5 +
  6 +* @juliansteenbakker
  1 +# .github/workflows/auto-author-assign.yml
  2 +name: 'Auto Author Assign'
  3 +
  4 +on:
  5 + pull_request_target:
  6 + types: [opened, reopened]
  7 +
  8 +permissions:
  9 + pull-requests: write
  10 +
  11 +jobs:
  12 + assign-author:
  13 + runs-on: ubuntu-latest
  14 + steps:
  15 + - uses: toshimaru/auto-author-assign@v1.6.1
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 release-please: 7 release-please:
8 runs-on: ubuntu-latest 8 runs-on: ubuntu-latest
9 steps: 9 steps:
10 - - uses: GoogleCloudPlatform/release-please-action@v3.4.1 10 + - uses: GoogleCloudPlatform/release-please-action@v3.5.0
11 with: 11 with:
12 token: ${{ secrets.GITHUB_TOKEN }} 12 token: ${{ secrets.GITHUB_TOKEN }}
13 release-type: simple 13 release-type: simple
@@ -9,6 +9,9 @@ class MobileScanner extends StatefulWidget { @@ -9,6 +9,9 @@ class MobileScanner extends StatefulWidget {
9 /// The controller of the camera. 9 /// The controller of the camera.
10 final MobileScannerController? controller; 10 final MobileScannerController? controller;
11 11
  12 + /// Calls the provided [onPermissionSet] callback when the permission is set.
  13 + final Function(bool permissionGranted)? onPermissionSet;
  14 +
12 /// Function that gets called when a Barcode is detected. 15 /// Function that gets called when a Barcode is detected.
13 /// 16 ///
14 /// [barcode] The barcode object with all information about the scanned code. 17 /// [barcode] The barcode object with all information about the scanned code.
@@ -34,6 +37,7 @@ class MobileScanner extends StatefulWidget { @@ -34,6 +37,7 @@ class MobileScanner extends StatefulWidget {
34 this.controller, 37 this.controller,
35 this.fit = BoxFit.cover, 38 this.fit = BoxFit.cover,
36 this.allowDuplicates = false, 39 this.allowDuplicates = false,
  40 + this.onPermissionSet,
37 }); 41 });
38 42
39 @override 43 @override
@@ -48,7 +52,8 @@ class _MobileScannerState extends State<MobileScanner> @@ -48,7 +52,8 @@ class _MobileScannerState extends State<MobileScanner>
48 void initState() { 52 void initState() {
49 super.initState(); 53 super.initState();
50 WidgetsBinding.instance.addObserver(this); 54 WidgetsBinding.instance.addObserver(this);
51 - controller = widget.controller ?? MobileScannerController(); 55 + controller = widget.controller ??
  56 + MobileScannerController(onPermissionSet: widget.onPermissionSet);
52 if (!controller.isStarting) controller.start(); 57 if (!controller.isStarting) controller.start();
53 } 58 }
54 59
@@ -118,7 +123,8 @@ class _MobileScannerState extends State<MobileScanner> @@ -118,7 +123,8 @@ class _MobileScannerState extends State<MobileScanner>
118 } 123 }
119 } else { 124 } else {
120 if (widget.controller == null) { 125 if (widget.controller == null) {
121 - controller = MobileScannerController(); 126 + controller =
  127 + MobileScannerController(onPermissionSet: widget.onPermissionSet);
122 } else if (oldWidget.controller != widget.controller) { 128 } else if (oldWidget.controller != widget.controller) {
123 controller = widget.controller!; 129 controller = widget.controller!;
124 } 130 }
1 import 'dart:async'; 1 import 'dart:async';
2 import 'dart:io'; 2 import 'dart:io';
3 -import 'dart:typed_data';  
4 3
5 import 'package:flutter/cupertino.dart'; 4 import 'package:flutter/cupertino.dart';
6 import 'package:flutter/foundation.dart'; 5 import 'package:flutter/foundation.dart';
@@ -40,6 +39,7 @@ class MobileScannerController { @@ -40,6 +39,7 @@ class MobileScannerController {
40 static int? _controllerHashcode; 39 static int? _controllerHashcode;
41 StreamSubscription? events; 40 StreamSubscription? events;
42 41
  42 + Function(bool permissionGranted)? onPermissionSet;
43 final ValueNotifier<MobileScannerArguments?> args = ValueNotifier(null); 43 final ValueNotifier<MobileScannerArguments?> args = ValueNotifier(null);
44 final ValueNotifier<TorchState> torchState = ValueNotifier(TorchState.off); 44 final ValueNotifier<TorchState> torchState = ValueNotifier(TorchState.off);
45 late final ValueNotifier<CameraFacing> cameraFacingState; 45 late final ValueNotifier<CameraFacing> cameraFacingState;
@@ -65,6 +65,7 @@ class MobileScannerController { @@ -65,6 +65,7 @@ class MobileScannerController {
65 this.ratio, 65 this.ratio,
66 this.torchEnabled, 66 this.torchEnabled,
67 this.formats, 67 this.formats,
  68 + this.onPermissionSet,
68 this.autoResume = true, 69 this.autoResume = true,
69 this.returnImage = false, 70 this.returnImage = false,
70 }) { 71 }) {
@@ -155,11 +156,14 @@ class MobileScannerController { @@ -155,11 +156,14 @@ class MobileScannerController {
155 state = result 156 state = result
156 ? MobileScannerState.authorized 157 ? MobileScannerState.authorized
157 : MobileScannerState.denied; 158 : MobileScannerState.denied;
  159 + onPermissionSet?.call(result);
158 break; 160 break;
159 case MobileScannerState.denied: 161 case MobileScannerState.denied:
160 isStarting = false; 162 isStarting = false;
  163 + onPermissionSet?.call(false);
161 throw PlatformException(code: 'NO ACCESS'); 164 throw PlatformException(code: 'NO ACCESS');
162 case MobileScannerState.authorized: 165 case MobileScannerState.authorized:
  166 + onPermissionSet?.call(true);
163 break; 167 break;
164 } 168 }
165 } 169 }
@@ -191,6 +195,9 @@ class MobileScannerController { @@ -191,6 +195,9 @@ class MobileScannerController {
191 } on PlatformException catch (error) { 195 } on PlatformException catch (error) {
192 debugPrint('${error.code}: ${error.message}'); 196 debugPrint('${error.code}: ${error.message}');
193 isStarting = false; 197 isStarting = false;
  198 + if (error.code == "MobileScannerWeb") {
  199 + onPermissionSet?.call(false);
  200 + }
194 // setAnalyzeMode(AnalyzeMode.none.index); 201 // setAnalyzeMode(AnalyzeMode.none.index);
195 return; 202 return;
196 } 203 }
@@ -203,6 +210,10 @@ class MobileScannerController { @@ -203,6 +210,10 @@ class MobileScannerController {
203 hasTorch = startResult['torchable'] as bool? ?? false; 210 hasTorch = startResult['torchable'] as bool? ?? false;
204 211
205 if (kIsWeb) { 212 if (kIsWeb) {
  213 + onPermissionSet?.call(
  214 + true,
  215 + ); // If we reach this line, it means camera permission has been granted
  216 +
206 args.value = MobileScannerArguments( 217 args.value = MobileScannerArguments(
207 webId: startResult['ViewID'] as String?, 218 webId: startResult['ViewID'] as String?,
208 size: Size( 219 size: Size(
@@ -286,6 +297,7 @@ class MobileScannerController { @@ -286,6 +297,7 @@ class MobileScannerController {
286 events?.cancel(); 297 events?.cancel();
287 events = null; 298 events = null;
288 _controllerHashcode = null; 299 _controllerHashcode = null;
  300 + onPermissionSet = null;
289 } 301 }
290 barcodesController.close(); 302 barcodesController.close();
291 } 303 }