p-mazhnik

feat: add hasTorch notifier

... ... @@ -77,7 +77,13 @@ class _BarcodeScannerWithControllerState
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
ValueListenableBuilder(
valueListenable: controller.hasTorchState,
builder: (context, state, child) {
if (state != true) {
return const SizedBox.shrink();
}
return IconButton(
color: Colors.white,
icon: ValueListenableBuilder(
valueListenable: controller.torchState,
... ... @@ -104,7 +110,8 @@ class _BarcodeScannerWithControllerState
),
iconSize: 32.0,
onPressed: () => controller.toggleTorch(),
),
);
}),
IconButton(
color: Colors.white,
icon: isStarted
... ...
... ... @@ -99,7 +99,8 @@ class MobileScannerController {
bool isStarting = false;
bool? _hasTorch;
/// A notifier that provides availability of the Torch (Flash)
final ValueNotifier<bool?> hasTorchState = ValueNotifier(false);
/// Returns whether the device has a torch.
///
... ... @@ -210,8 +211,9 @@ class MobileScannerController {
);
}
_hasTorch = startResult['torchable'] as bool? ?? false;
if (_hasTorch! && torchEnabled) {
final hasTorch = startResult['torchable'] as bool? ?? false;
hasTorchState.value = hasTorch;
if (hasTorch && torchEnabled) {
torchState.value = TorchState.on;
}
... ... @@ -223,7 +225,7 @@ class MobileScannerController {
startResult['videoHeight'] as double? ?? 0,
)
: toSize(startResult['size'] as Map? ?? {}),
hasTorch: _hasTorch!,
hasTorch: hasTorch,
textureId: kIsWeb ? null : startResult['textureId'] as int?,
webId: kIsWeb ? startResult['ViewID'] as String? : null,
);
... ... @@ -244,7 +246,7 @@ class MobileScannerController {
///
/// Throws if the controller was not initialized.
Future<void> toggleTorch() async {
final hasTorch = _hasTorch;
final hasTorch = hasTorchState.value;
if (hasTorch == null) {
throw const MobileScannerException(
... ...
... ... @@ -98,8 +98,7 @@ mixin InternalStreamCreation on WebBarcodeReaderBase {
/// Mixin for libraries that don't have built-in torch support
mixin InternalTorchDetection on InternalStreamCreation {
@override
Future<bool> hasTorch() async {
Future<List<String>> getSupportedTorchStates() async {
try {
final track = localMediaStream?.getVideoTracks();
if (track != null) {
... ... @@ -107,13 +106,21 @@ mixin InternalTorchDetection on InternalStreamCreation {
final photoCapabilities = await promiseToFuture<PhotoCapabilities>(
imageCapture.getPhotoCapabilities(),
);
return photoCapabilities.fillLightMode != null;
final fillLightMode = photoCapabilities.fillLightMode;
if (fillLightMode != null) {
return fillLightMode;
}
}
} catch (e) {
// ImageCapture is not supported by some browsers:
// https://developer.mozilla.org/en-US/docs/Web/API/ImageCapture#browser_compatibility
}
return false;
return [];
}
@override
Future<bool> hasTorch() async {
return (await getSupportedTorchStates()).isNotEmpty;
}
@override
... ...