Skip to content

Commit

Permalink
Merge branch 'develop' into fix/4304
Browse files Browse the repository at this point in the history
  • Loading branch information
monsieurtanuki authored Jul 16, 2023
2 parents 2575620 + 7487b72 commit 72d9f3a
Show file tree
Hide file tree
Showing 38 changed files with 579 additions and 343 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/waldo_sessions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Upload builds to Waldo

on:
pull_request_target:
types:
- opened
- edited
- synchronize

jobs:
build:
runs-on: macos-latest
defaults:
run:
shell: bash
steps:
- name: "Checkout code"
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Setup Java JDK
uses: actions/[email protected]
with:
distribution: 'zulu'
java-version: 11

# Get the flutter version from ./flutter-version.txt
- run: echo "FLUTTER_VERSION=$(cat flutter-version.txt)" >> $GITHUB_OUTPUT
id: flutter-version

- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
#channel: stable
cache: true
flutter-version: ${{ steps.flutter-version.outputs.FLUTTER_VERSION }}
cache-key: flutter-${{ hashFiles('flutter-version.txt')}}-${{ hashFiles('packages\smooth_app\pubspec.lock')}}

- run: flutter --version

- name: Get dependencies
run: ci/pub_upgrade.sh

# Build apk.
- name: Build APK
run: flutter build apk --debug -t lib/entrypoints/android/main_google_play.dart
working-directory: ./packages/smooth_app

- name: Upload APK to Waldo
uses: waldoapp/gh-action-upload@v1
with:
build_path: packages/smooth_app/build/app/outputs/flutter-apk/app-debug.apk
upload_token: ${{ secrets.WALDO_SESSIONS_ANDROID }}

- name: Write comment
uses: mshick/add-pr-comment@v2
with:
message: "You can test this PR on: [https://app.waldo.com/applications/app-19d476740ba1bb36/sessions](Android)"

# TODO Build the iOS variant and upload it
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Starting this April, we invite all users and contributors to build a vision for

- This new mobile application aims to showcase Open Food Facts's power to a broad range of users through a smooth user experience and sleek user interface. It is a <b> Flutter application </b> by [Open Food Facts](https://github.com/openfoodfacts).
- We pioneered the collaborative scanning app in 2012. With this experimental app, we’re reinventing it from the ground up.
- Install it on [Android](https://play.google.com/store/apps/details?id=org.openfoodfacts.scanner) or [iPhone/iPad](https://apps.apple.com/app/open-food-facts/id588797948). Note that a internal development build ([Android](https://play.google.com/apps/internaltest/4699092342921529278) or [iPhone/iPad](https://testflight.apple.com/join/c2tiBHgd)) if you'd like to use the results of your PRs quicker.
- Install it on **Android** ([Google Play](https://play.google.com/store/apps/details?id=org.openfoodfacts.scanner), [F-Droid](https://f-droid.org/fr/packages/openfoodfacts.github.scrachx.openfood/) or [Amazon App Store](https://www.amazon.com/Open-Food-Facts-food-Nutriscore/dp/B00U49IVIU)) or [iPhone/iPad](https://apps.apple.com/app/open-food-facts/id588797948). Note that a internal development build ([Android](https://play.google.com/apps/internaltest/4699092342921529278) or **iPhone/iPad** ([App Store](https://testflight.apple.com/join/c2tiBHgd)) if you'd like to use the results of your PRs quicker.

<img alt="app showcase" height='175' src="https://user-images.githubusercontent.com/1689815/168430524-3adc923a-1ce3-4233-9af5-02e9d49a76ca.png" align="left" hspace="1" vspace="1">

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class AppleAppStore extends AppStore {
AppleAppStore(this.appId)
: assert(appId.isNotEmpty),
assert(!appId.startsWith('id')),
assert(Platform.isIOS);
assert(Platform.isIOS || Platform.isMacOS);

final String appId;
final InAppReview _inAppReview = InAppReview.instance;
Expand Down
120 changes: 82 additions & 38 deletions packages/scanner/ml_kit/lib/src/scanner_ml_kit.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';

import 'package:async/async.dart';
import 'package:flutter/material.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:scanner_shared/scanner_shared.dart';
Expand Down Expand Up @@ -83,7 +84,6 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit>

static const ValueKey<String> _visibilityKey =
ValueKey<String>('VisibilityDetector');
static const double _cornerPadding = 26.0;

bool _isStarted = true;

Expand All @@ -100,6 +100,11 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit>
autoStart: true,
);

// Stores a background operation when the screen isn't visible
CancelableOperation<void>? _autoStopCameraOperation;
// Stores the latest visibility value of the screen
VisibilityInfo? _latestVisibilityInfoEvent;

@override
void initState() {
super.initState();
Expand All @@ -113,25 +118,64 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit>
if (state == AppLifecycleState.paused) {
_stop();
} else if (state == AppLifecycleState.resumed) {
/// When the app is resumed (from the launcher for example), the camera is
/// always started and we can't prevent this behavior.
///
/// To fix it, we check when the app is resumed if the camera is the
/// visible page and if that's not the case, we wait for the camera to be
/// initialized to stop it
WidgetsBinding.instance.addPostFrameCallback((_) {
if (ScreenVisibilityDetector.invisible(context)) {
_pauseCameraWhenInitialized();
}
});
_autoStopCameraOperation?.cancel();
_checkIfAppIsRestarting();
}
}

void _checkIfAppIsRestarting([int retry = 0]) {
/// When the app is resumed (from the launcher for example), the camera is
/// always started due to the [autostart] feature and we can't
/// prevent this behavior.
///
/// To fix it, we check when the app is resumed if the camera is the
/// visible page and if that's not the case, we wait for the camera to be
/// initialized to stop it.
///
/// Comment from @g123k: This is a very hacky way (temporary I hope) and
/// more explanation are available on the PR:
/// [https://github.com/openfoodfacts/smooth-app/pull/4292]
///
// ignore: prefer_function_declarations_over_variables
final Function fn = () {
if (ScreenVisibilityDetector.invisible(context)) {
_pauseCameraWhenInitialized();
} else if (retry < 1) {
// In 99% of cases, this won't happen, but if for some reason, we are
// "considered" as visible, we will retry in a few milliseconds
// and if we are still invisible -> force stop the camera
_autoStopCameraOperation = CancelableOperation<void>.fromFuture(
Future<void>.delayed(
const Duration(milliseconds: 500),
() => _checkIfAppIsRestarting(retry + 1),
),
);
} else if (_latestVisibilityInfoEvent?.visible == false) {
_pauseCameraWhenInitialized();
}
};

// Ensure to wait for the first frame
if (retry == 0) {
// ignore: avoid_dynamic_calls
WidgetsBinding.instance.addPostFrameCallback((_) => fn.call());
} else {
// ignore: avoid_dynamic_calls
scheduleMicrotask(() => fn.call());
}
}

Future<void> _pauseCameraWhenInitialized() async {
if (!mounted) {
return;
}

if (_controller.isStarting) {
return Future<void>.delayed(
const Duration(milliseconds: 250),
() => _pauseCameraWhenInitialized(),
_autoStopCameraOperation = CancelableOperation<void>.fromFuture(
Future<void>.delayed(
const Duration(milliseconds: 250),
() => _pauseCameraWhenInitialized(),
),
);
}

Expand All @@ -155,6 +199,7 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit>
}

Future<void> _stop() async {
_autoStopCameraOperation?.cancel();
if (!_isStarted) {
return;
}
Expand All @@ -172,6 +217,7 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit>
return VisibilityDetector(
key: _visibilityKey,
onVisibilityChanged: (final VisibilityInfo info) async {
_latestVisibilityInfoEvent = info;
if (info.visibleBounds.height > 0.0) {
await _start();
} else {
Expand Down Expand Up @@ -200,27 +246,30 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit>
),
Center(
child: SmoothBarcodeScannerVisor(
cornerRadius: _cornerPadding,
contentPadding: widget.contentPadding,
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(_cornerPadding),
padding: const EdgeInsets.all(
SmoothBarcodeScannerVisor.CORNER_PADDING,
),
child: Row(
mainAxisAlignment: _showFlipCameraButton
? MainAxisAlignment.spaceBetween
: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
if (_showFlipCameraButton)
IconButton(
enableFeedback: true,
VisorButton(
onTap: () async {
widget.hapticFeedback.call();
await _controller.switchCamera();
},
tooltip: widget.toggleCameraModeTooltip ??
'Switch between back and front camera',
color: Colors.white,
icon: ValueListenableBuilder<CameraFacing>(
child: ValueListenableBuilder<CameraFacing>(
valueListenable: _controller.cameraFacingState,
builder: (
BuildContext context,
Expand All @@ -235,10 +284,6 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit>
}
},
),
onPressed: () async {
widget.hapticFeedback.call();
await _controller.switchCamera();
},
),
ValueListenableBuilder<bool?>(
valueListenable: _controller.hasTorchState,
Expand All @@ -250,12 +295,19 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit>
if (state != true) {
return const SizedBox.shrink();
}
return IconButton(
enableFeedback: true,
return VisorButton(
tooltip: widget.toggleFlashModeTooltip ??
'Turn ON or OFF the flash of the camera',
color: Colors.white,
icon: ValueListenableBuilder<TorchState>(
onTap: () async {
widget.hapticFeedback.call();

try {
await _controller.toggleTorch();
} catch (err) {
widget.onCameraFlashError?.call(context);
}
},
child: ValueListenableBuilder<TorchState>(
valueListenable: _controller.torchState,
builder: (
BuildContext context,
Expand All @@ -276,15 +328,6 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit>
}
},
),
onPressed: () async {
widget.hapticFeedback.call();

try {
await _controller.toggleTorch();
} catch (err) {
widget.onCameraFlashError?.call(context);
}
},
);
},
),
Expand All @@ -300,6 +343,7 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit>
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_autoStopCameraOperation?.cancel();
_controller.dispose();
super.dispose();
}
Expand Down
2 changes: 2 additions & 0 deletions packages/scanner/ml_kit/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ dependencies:
sdk: flutter

visibility_detector: 0.4.0+2
async: 2.11.0

mobile_scanner:
git:
url: https://github.com/openfoodfacts/mobile_scanner.git
Expand Down
Loading

0 comments on commit 72d9f3a

Please sign in to comment.