Navaron Bracke

no-op the zoom & torch on the web

1 import 'dart:js_interop'; 1 import 'dart:js_interop';
2 2
3 -import 'package:mobile_scanner/src/enums/torch_state.dart';  
4 import 'package:web/web.dart'; 3 import 'package:web/web.dart';
5 4
6 /// This class represents a delegate that manages the constraints for a [MediaStreamTrack]. 5 /// This class represents a delegate that manages the constraints for a [MediaStreamTrack].
@@ -27,107 +26,8 @@ final class MediaTrackConstraintsDelegate { @@ -27,107 +26,8 @@ final class MediaTrackConstraintsDelegate {
27 return MediaTrackSettings( 26 return MediaTrackSettings(
28 width: settings.width, 27 width: settings.width,
29 height: settings.height, 28 height: settings.height,
30 - zoom: settings.zoomNullable ?? 1.0,  
31 - facingMode: settings.facingModeNullable ?? '',  
32 - focusMode: settings.focusModeNullable ?? 'none',  
33 - torch: settings.torchNullable ?? false,  
34 - focusDistance: settings.focusDistanceNullable ?? 0.0, 29 + facingMode: settings.facingMode,
35 aspectRatio: settings.aspectRatio, 30 aspectRatio: settings.aspectRatio,
36 ); 31 );
37 } 32 }
38 -  
39 - /// Returns a list of supported flashlight modes for the given [mediaStream].  
40 - ///  
41 - /// The [TorchState.off] mode is always supported, regardless of the return value.  
42 - Future<List<TorchState>> getSupportedFlashlightModes(  
43 - MediaStream? mediaStream,  
44 - ) async {  
45 - if (mediaStream == null) {  
46 - return [];  
47 - }  
48 -  
49 - final List<JSAny?> tracks = mediaStream.getVideoTracks().toDart;  
50 -  
51 - if (tracks.isEmpty) {  
52 - return [];  
53 - }  
54 -  
55 - final MediaStreamTrack? track = tracks.first as MediaStreamTrack?;  
56 -  
57 - if (track == null) {  
58 - return [];  
59 - }  
60 -  
61 - try {  
62 - final MediaTrackCapabilities capabilities = track.getCapabilities();  
63 -  
64 - return [  
65 - if (capabilities.torch) TorchState.on,  
66 - ];  
67 - } catch (_) {  
68 - // Firefox does not support getCapabilities() yet.  
69 - // https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack/getCapabilities#browser_compatibility  
70 -  
71 - return [];  
72 - }  
73 - }  
74 -  
75 - /// Returns whether the given [mediaStream] has a flashlight.  
76 - Future<bool> hasFlashlight(MediaStream? mediaStream) async {  
77 - return (await getSupportedFlashlightModes(mediaStream)).isNotEmpty;  
78 - }  
79 -  
80 - /// Set the flashlight state of the given [mediaStream] to the given [value].  
81 - Future<void> setFlashlightState(  
82 - MediaStream? mediaStream,  
83 - TorchState value,  
84 - ) async {  
85 - if (mediaStream == null) {  
86 - return;  
87 - }  
88 -  
89 - if (await hasFlashlight(mediaStream)) {  
90 - final List<JSAny?> tracks = mediaStream.getVideoTracks().toDart;  
91 -  
92 - if (tracks.isEmpty) {  
93 - return;  
94 - }  
95 -  
96 - final bool flashlightEnabled = switch (value) {  
97 - TorchState.on => true,  
98 - TorchState.off || TorchState.unavailable => false,  
99 - };  
100 -  
101 - final MediaStreamTrack? track = tracks.first as MediaStreamTrack?;  
102 -  
103 - final MediaTrackConstraints constraints = MediaTrackConstraints(  
104 - advanced: [  
105 - {'torch': flashlightEnabled}.jsify(),  
106 - ].toJS,  
107 - );  
108 -  
109 - await track?.applyConstraints(constraints).toDart;  
110 - }  
111 - }  
112 -}  
113 -  
114 -// TODO: turn this extension into an extension type when Dart 3.3 releases.  
115 -  
116 -// This extension exists because the Web IDL bindings for MediaTrackSettings  
117 -// do not account for unavailable properties.  
118 -extension _NullableMediaTrackSettings on MediaTrackSettings {  
119 - @JS('facingMode')  
120 - external String? get facingModeNullable;  
121 -  
122 - @JS('focusDistance')  
123 - external num? get focusDistanceNullable;  
124 -  
125 - @JS('focusMode')  
126 - external String? get focusModeNullable;  
127 -  
128 - @JS('torch')  
129 - external bool? get torchNullable;  
130 -  
131 - @JS('zoom')  
132 - external num? get zoomNullable;  
133 } 33 }
@@ -52,6 +52,11 @@ class MobileScannerWeb extends MobileScannerPlatform { @@ -52,6 +52,11 @@ class MobileScannerWeb extends MobileScannerPlatform {
52 Completer<void>? _cameraPermissionCompleter; 52 Completer<void>? _cameraPermissionCompleter;
53 53
54 /// The stream controller for the media track settings stream. 54 /// The stream controller for the media track settings stream.
  55 + ///
  56 + /// Currently, only the facing mode setting can be supported,
  57 + /// because that is the only property for video tracks that can be observed.
  58 + ///
  59 + /// See https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#instance_properties_of_video_tracks
55 final StreamController<MediaTrackSettings> _settingsController = 60 final StreamController<MediaTrackSettings> _settingsController =
56 StreamController.broadcast(); 61 StreamController.broadcast();
57 62
@@ -71,14 +76,12 @@ class MobileScannerWeb extends MobileScannerPlatform { @@ -71,14 +76,12 @@ class MobileScannerWeb extends MobileScannerPlatform {
71 Stream<BarcodeCapture?> get barcodesStream => _barcodesController.stream; 76 Stream<BarcodeCapture?> get barcodesStream => _barcodesController.stream;
72 77
73 @override 78 @override
74 - Stream<TorchState> get torchStateStream => _settingsController.stream.map(  
75 - (settings) => settings.torch ? TorchState.on : TorchState.off,  
76 - ); 79 + Stream<TorchState> get torchStateStream =>
  80 + _settingsController.stream.map((_) => TorchState.off);
77 81
78 @override 82 @override
79 - Stream<double> get zoomScaleStateStream => _settingsController.stream.map(  
80 - (settings) => settings.zoom.toDouble(),  
81 - ); 83 + Stream<double> get zoomScaleStateStream =>
  84 + _settingsController.stream.map((_) => 1.0);
82 85
83 void _handleMediaTrackSettingsChange(MediaTrackSettings settings) { 86 void _handleMediaTrackSettingsChange(MediaTrackSettings settings) {
84 if (_settingsController.isClosed) { 87 if (_settingsController.isClosed) {