Showing
3 changed files
with
51 additions
and
35 deletions
| @@ -77,34 +77,41 @@ class _BarcodeScannerWithControllerState | @@ -77,34 +77,41 @@ class _BarcodeScannerWithControllerState | ||
| 77 | child: Row( | 77 | child: Row( |
| 78 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, | 78 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
| 79 | children: [ | 79 | children: [ |
| 80 | - IconButton( | ||
| 81 | - color: Colors.white, | ||
| 82 | - icon: ValueListenableBuilder( | ||
| 83 | - valueListenable: controller.torchState, | 80 | + ValueListenableBuilder( |
| 81 | + valueListenable: controller.hasTorchState, | ||
| 84 | builder: (context, state, child) { | 82 | builder: (context, state, child) { |
| 85 | - if (state == null) { | ||
| 86 | - return const Icon( | ||
| 87 | - Icons.flash_off, | ||
| 88 | - color: Colors.grey, | ||
| 89 | - ); | 83 | + if (state != true) { |
| 84 | + return const SizedBox.shrink(); | ||
| 90 | } | 85 | } |
| 91 | - switch (state as TorchState) { | ||
| 92 | - case TorchState.off: | ||
| 93 | - return const Icon( | ||
| 94 | - Icons.flash_off, | ||
| 95 | - color: Colors.grey, | ||
| 96 | - ); | ||
| 97 | - case TorchState.on: | ||
| 98 | - return const Icon( | ||
| 99 | - Icons.flash_on, | ||
| 100 | - color: Colors.yellow, | ||
| 101 | - ); | ||
| 102 | - } | ||
| 103 | - }, | ||
| 104 | - ), | ||
| 105 | - iconSize: 32.0, | ||
| 106 | - onPressed: () => controller.toggleTorch(), | ||
| 107 | - ), | 86 | + return IconButton( |
| 87 | + color: Colors.white, | ||
| 88 | + icon: ValueListenableBuilder( | ||
| 89 | + valueListenable: controller.torchState, | ||
| 90 | + builder: (context, state, child) { | ||
| 91 | + if (state == null) { | ||
| 92 | + return const Icon( | ||
| 93 | + Icons.flash_off, | ||
| 94 | + color: Colors.grey, | ||
| 95 | + ); | ||
| 96 | + } | ||
| 97 | + switch (state as TorchState) { | ||
| 98 | + case TorchState.off: | ||
| 99 | + return const Icon( | ||
| 100 | + Icons.flash_off, | ||
| 101 | + color: Colors.grey, | ||
| 102 | + ); | ||
| 103 | + case TorchState.on: | ||
| 104 | + return const Icon( | ||
| 105 | + Icons.flash_on, | ||
| 106 | + color: Colors.yellow, | ||
| 107 | + ); | ||
| 108 | + } | ||
| 109 | + }, | ||
| 110 | + ), | ||
| 111 | + iconSize: 32.0, | ||
| 112 | + onPressed: () => controller.toggleTorch(), | ||
| 113 | + ); | ||
| 114 | + }), | ||
| 108 | IconButton( | 115 | IconButton( |
| 109 | color: Colors.white, | 116 | color: Colors.white, |
| 110 | icon: isStarted | 117 | icon: isStarted |
| @@ -99,7 +99,8 @@ class MobileScannerController { | @@ -99,7 +99,8 @@ class MobileScannerController { | ||
| 99 | 99 | ||
| 100 | bool isStarting = false; | 100 | bool isStarting = false; |
| 101 | 101 | ||
| 102 | - bool? _hasTorch; | 102 | + /// A notifier that provides availability of the Torch (Flash) |
| 103 | + final ValueNotifier<bool?> hasTorchState = ValueNotifier(false); | ||
| 103 | 104 | ||
| 104 | /// Returns whether the device has a torch. | 105 | /// Returns whether the device has a torch. |
| 105 | /// | 106 | /// |
| @@ -210,8 +211,9 @@ class MobileScannerController { | @@ -210,8 +211,9 @@ class MobileScannerController { | ||
| 210 | ); | 211 | ); |
| 211 | } | 212 | } |
| 212 | 213 | ||
| 213 | - _hasTorch = startResult['torchable'] as bool? ?? false; | ||
| 214 | - if (_hasTorch! && torchEnabled) { | 214 | + final hasTorch = startResult['torchable'] as bool? ?? false; |
| 215 | + hasTorchState.value = hasTorch; | ||
| 216 | + if (hasTorch && torchEnabled) { | ||
| 215 | torchState.value = TorchState.on; | 217 | torchState.value = TorchState.on; |
| 216 | } | 218 | } |
| 217 | 219 | ||
| @@ -223,7 +225,7 @@ class MobileScannerController { | @@ -223,7 +225,7 @@ class MobileScannerController { | ||
| 223 | startResult['videoHeight'] as double? ?? 0, | 225 | startResult['videoHeight'] as double? ?? 0, |
| 224 | ) | 226 | ) |
| 225 | : toSize(startResult['size'] as Map? ?? {}), | 227 | : toSize(startResult['size'] as Map? ?? {}), |
| 226 | - hasTorch: _hasTorch!, | 228 | + hasTorch: hasTorch, |
| 227 | textureId: kIsWeb ? null : startResult['textureId'] as int?, | 229 | textureId: kIsWeb ? null : startResult['textureId'] as int?, |
| 228 | webId: kIsWeb ? startResult['ViewID'] as String? : null, | 230 | webId: kIsWeb ? startResult['ViewID'] as String? : null, |
| 229 | ); | 231 | ); |
| @@ -244,7 +246,7 @@ class MobileScannerController { | @@ -244,7 +246,7 @@ class MobileScannerController { | ||
| 244 | /// | 246 | /// |
| 245 | /// Throws if the controller was not initialized. | 247 | /// Throws if the controller was not initialized. |
| 246 | Future<void> toggleTorch() async { | 248 | Future<void> toggleTorch() async { |
| 247 | - final hasTorch = _hasTorch; | 249 | + final hasTorch = hasTorchState.value; |
| 248 | 250 | ||
| 249 | if (hasTorch == null) { | 251 | if (hasTorch == null) { |
| 250 | throw const MobileScannerException( | 252 | throw const MobileScannerException( |
| @@ -98,8 +98,7 @@ mixin InternalStreamCreation on WebBarcodeReaderBase { | @@ -98,8 +98,7 @@ mixin InternalStreamCreation on WebBarcodeReaderBase { | ||
| 98 | 98 | ||
| 99 | /// Mixin for libraries that don't have built-in torch support | 99 | /// Mixin for libraries that don't have built-in torch support |
| 100 | mixin InternalTorchDetection on InternalStreamCreation { | 100 | mixin InternalTorchDetection on InternalStreamCreation { |
| 101 | - @override | ||
| 102 | - Future<bool> hasTorch() async { | 101 | + Future<List<String>> getSupportedTorchStates() async { |
| 103 | try { | 102 | try { |
| 104 | final track = localMediaStream?.getVideoTracks(); | 103 | final track = localMediaStream?.getVideoTracks(); |
| 105 | if (track != null) { | 104 | if (track != null) { |
| @@ -107,13 +106,21 @@ mixin InternalTorchDetection on InternalStreamCreation { | @@ -107,13 +106,21 @@ mixin InternalTorchDetection on InternalStreamCreation { | ||
| 107 | final photoCapabilities = await promiseToFuture<PhotoCapabilities>( | 106 | final photoCapabilities = await promiseToFuture<PhotoCapabilities>( |
| 108 | imageCapture.getPhotoCapabilities(), | 107 | imageCapture.getPhotoCapabilities(), |
| 109 | ); | 108 | ); |
| 110 | - return photoCapabilities.fillLightMode != null; | 109 | + final fillLightMode = photoCapabilities.fillLightMode; |
| 110 | + if (fillLightMode != null) { | ||
| 111 | + return fillLightMode; | ||
| 112 | + } | ||
| 111 | } | 113 | } |
| 112 | } catch (e) { | 114 | } catch (e) { |
| 113 | // ImageCapture is not supported by some browsers: | 115 | // ImageCapture is not supported by some browsers: |
| 114 | // https://developer.mozilla.org/en-US/docs/Web/API/ImageCapture#browser_compatibility | 116 | // https://developer.mozilla.org/en-US/docs/Web/API/ImageCapture#browser_compatibility |
| 115 | } | 117 | } |
| 116 | - return false; | 118 | + return []; |
| 119 | + } | ||
| 120 | + | ||
| 121 | + @override | ||
| 122 | + Future<bool> hasTorch() async { | ||
| 123 | + return (await getSupportedTorchStates()).isNotEmpty; | ||
| 117 | } | 124 | } |
| 118 | 125 | ||
| 119 | @override | 126 | @override |
-
Please register or login to post a comment