Skip to content

Commit

Permalink
chore: Shared common scanner (#3883)
Browse files Browse the repository at this point in the history
* First movement

* devcotainer

* Lint fixes

* Shared visor

* Final moves

* Final lint fixes

* Empty widget, moved scan header

* Update scanner_ml_kit.dart

---------

Co-authored-by: Marvin Moeltgen
  • Loading branch information
M123-dev authored Apr 18, 2023
1 parent a613620 commit f7e42c7
Show file tree
Hide file tree
Showing 42 changed files with 623 additions and 376 deletions.
5 changes: 3 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.224.3/containers/ubuntu
{
"image": "docker.io/cirrusci/flutter:beta",
"image": "docker.io/cirrusci/flutter:stable",
"forwardPorts": [
3000
],
"customizations": {
"vscode": {
"extensions": [
"Dart-Code.flutter"
"Dart-Code.flutter",
"dart-code.dart-code"
]
}
}
Expand Down
26 changes: 26 additions & 0 deletions packages/scanner/ml_kit/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/


# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.packages
build/
30 changes: 30 additions & 0 deletions packages/scanner/ml_kit/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.

version:
revision: eb6d86ee27deecba4a83536aa20f366a6044895c
channel: stable

project_type: plugin

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: eb6d86ee27deecba4a83536aa20f366a6044895c
base_revision: eb6d86ee27deecba4a83536aa20f366a6044895c
- platform: android
create_revision: eb6d86ee27deecba4a83536aa20f366a6044895c
base_revision: eb6d86ee27deecba4a83536aa20f366a6044895c

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
2 changes: 2 additions & 0 deletions packages/scanner/ml_kit/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Shared rules
include: package:openfoodfacts_flutter_lints/flutter.yaml
3 changes: 3 additions & 0 deletions packages/scanner/ml_kit/lib/scanner_ml_kit.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
library app_store_uri;

export 'src/scanner_ml_kit.dart';
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,59 @@ import 'dart:async';

import 'package:flutter/material.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/helpers/analytics_helper.dart';
import 'package:smooth_app/helpers/camera_helper.dart';
import 'package:smooth_app/helpers/haptic_feedback_helper.dart';
import 'package:smooth_app/pages/scan/scan_header.dart';
import 'package:smooth_app/pages/scan/smooth_barcode_scanner_visor.dart';
import 'package:smooth_app/widgets/screen_visibility.dart';
import 'package:scanner_shared/scanner_shared.dart';
import 'package:visibility_detector/visibility_detector.dart';

/// Scanner implementation using ML Kit
class ScannerMLKit extends Scanner {
const ScannerMLKit();

@override
String getType() => 'ML Kit';

@override
Widget getScanner({
required Future<bool> Function(String) onScan,
required Future<void> Function() hapticFeedback,
required Function(BuildContext)? onCameraFlashError,
required Function(String msg, String category,
{int? eventValue, String? barcode})
trackCustomEvent,
required bool hasMoreThanOneCamera,
}) {
return _SmoothBarcodeScannerMLKit(
onScan: onScan,
hapticFeedback: hapticFeedback,
trackCustomEvent: trackCustomEvent,
onCameraFlashError: onCameraFlashError,
hasMoreThanOneCamera: hasMoreThanOneCamera,
);
}
}

/// Barcode scanner based on MLKit.
class SmoothBarcodeScannerMLKit extends StatefulWidget {
const SmoothBarcodeScannerMLKit(
this.onScan, {
this.onCameraFlashError,
class _SmoothBarcodeScannerMLKit extends StatefulWidget {
const _SmoothBarcodeScannerMLKit({
required this.onScan,
required this.hapticFeedback,
required this.trackCustomEvent,
required this.onCameraFlashError,
required this.hasMoreThanOneCamera,
});

final Future<bool> Function(String) onScan;
final Future<void> Function() hapticFeedback;

final Function(String msg, String category,
{int? eventValue, String? barcode}) trackCustomEvent;
final Function(BuildContext)? onCameraFlashError;
final bool hasMoreThanOneCamera;

@override
State<StatefulWidget> createState() => _SmoothBarcodeScannerMLKitState();
}

class _SmoothBarcodeScannerMLKitState extends State<SmoothBarcodeScannerMLKit>
class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit>
with SingleTickerProviderStateMixin {
// just 1D formats and ios supported
static const List<BarcodeFormat> _barcodeFormats = <BarcodeFormat>[
Expand All @@ -43,7 +72,7 @@ class _SmoothBarcodeScannerMLKitState extends State<SmoothBarcodeScannerMLKit>

bool _isStarted = true;

bool get _showFlipCameraButton => CameraHelper.hasMoreThanOneCamera;
bool get _showFlipCameraButton => widget.hasMoreThanOneCamera;

final MobileScannerController _controller = MobileScannerController(
torchEnabled: false,
Expand All @@ -67,9 +96,8 @@ class _SmoothBarcodeScannerMLKitState extends State<SmoothBarcodeScannerMLKit>
await _controller.start();
_isStarted = true;
} on Exception {
AnalyticsHelper.trackEvent(
AnalyticsEvent.scanStrangeRestart,
);
widget.trackCustomEvent(
Scanner.ANALYTICS_STRANGE_RESTART, Scanner.ANALYTICS_CATEGORY);
}
}

Expand All @@ -81,17 +109,16 @@ class _SmoothBarcodeScannerMLKitState extends State<SmoothBarcodeScannerMLKit>
await _controller.stop();
_isStarted = false;
} on Exception {
AnalyticsHelper.trackEvent(
AnalyticsEvent.scanStrangeRestop,
);
widget.trackCustomEvent(
Scanner.ANALYTICS_STRANGE_RESTOP, Scanner.ANALYTICS_CATEGORY);
}
}

@override
Widget build(BuildContext context) => VisibilityDetector(
key: const ValueKey<String>('VisibilityDetector'),
onVisibilityChanged: (final VisibilityInfo info) async {
if (info.visible) {
if (info.visibleBounds.height > 0.0) {
await _start();
} else {
await _stop();
Expand Down Expand Up @@ -123,10 +150,6 @@ class _SmoothBarcodeScannerMLKitState extends State<SmoothBarcodeScannerMLKit>
child: SmoothBarcodeScannerVisor(),
),
),
const Align(
alignment: Alignment.topCenter,
child: ScanHeader(),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
Expand Down Expand Up @@ -156,7 +179,7 @@ class _SmoothBarcodeScannerMLKitState extends State<SmoothBarcodeScannerMLKit>
},
),
onPressed: () async {
SmoothHapticFeedback.click();
widget.hapticFeedback.call();
await _controller.switchCamera();
},
),
Expand All @@ -168,7 +191,7 @@ class _SmoothBarcodeScannerMLKitState extends State<SmoothBarcodeScannerMLKit>
Widget? child,
) {
if (state != true) {
return EMPTY_WIDGET;
return const SizedBox.shrink();
}
return IconButton(
color: Colors.white,
Expand All @@ -194,7 +217,7 @@ class _SmoothBarcodeScannerMLKitState extends State<SmoothBarcodeScannerMLKit>
},
),
onPressed: () async {
SmoothHapticFeedback.click();
widget.hapticFeedback.call();

try {
await _controller.toggleTorch();
Expand Down
23 changes: 23 additions & 0 deletions packages/scanner/ml_kit/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: scanner_ml_kit
description: Scanner implementation using ML Kit
version: 1.0.0
publish_to: "none"

environment:
sdk: ">=2.19.0 <3.0.0"

dependencies:
flutter:
sdk: flutter

visibility_detector: 0.4.0+2
mobile_scanner: 3.2.0
scanner_shared:
path: ../shared

dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: 2.0.1
openfoodfacts_flutter_lints:
git: https://github.com/openfoodfacts/openfoodfacts_flutter_lints.git
8 changes: 8 additions & 0 deletions packages/scanner/ml_kit/test/scanner_ml_kit_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import 'package:flutter_test/flutter_test.dart';

// The CI needs at least one test
void main() {
testWidgets('Fake test', (WidgetTester tester) async {
expect(true, true);
});
}
30 changes: 30 additions & 0 deletions packages/scanner/shared/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.packages
build/
10 changes: 10 additions & 0 deletions packages/scanner/shared/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: eb6d86ee27deecba4a83536aa20f366a6044895c
channel: stable

project_type: package
2 changes: 2 additions & 0 deletions packages/scanner/shared/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Shared rules
include: package:openfoodfacts_flutter_lints/flutter.yaml
6 changes: 6 additions & 0 deletions packages/scanner/shared/lib/scanner_shared.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
library app_store_shared;

export 'src/scanner.dart';
export 'src/scanner_mocked.dart';
export 'src/scanner_visor.dart';
export 'src/utils.dart';
22 changes: 22 additions & 0 deletions packages/scanner/shared/lib/src/scanner.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';

/// Base class for the Scanner interface…
abstract class Scanner {
const Scanner();

static const String ANALYTICS_CATEGORY = 'scanning';
static const String ANALYTICS_STRANGE_RESTART = 'strange restart';
static const String ANALYTICS_STRANGE_RESTOP = 'strange restop';

String getType();

Widget getScanner({
required Future<bool> Function(String) onScan,
required Future<void> Function() hapticFeedback,
required Function(BuildContext)? onCameraFlashError,
required Function(String msg, String category,
{int? eventValue, String? barcode})
trackCustomEvent,
required bool hasMoreThanOneCamera,
});
}
23 changes: 23 additions & 0 deletions packages/scanner/shared/lib/src/scanner_mocked.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'package:flutter/material.dart';

import 'package:scanner_shared/scanner_shared.dart';

/// Empty implementation for an [AppStore]
class MockedScanner extends Scanner {
const MockedScanner();

@override
String getType() => 'Mocked';

@override
Widget getScanner({
required Future<bool> Function(String) onScan,
required Future<void> Function() hapticFeedback,
required Function(BuildContext)? onCameraFlashError,
required Function(String msg, String category,
{int? eventValue, String? barcode})
trackCustomEvent,
required bool hasMoreThanOneCamera,
}) =>
Container();
}
Loading

0 comments on commit f7e42c7

Please sign in to comment.