diff --git a/.github/workflows/waldo_sessions.yml b/.github/workflows/waldo_sessions.yml new file mode 100644 index 00000000000..51e8548a30b --- /dev/null +++ b/.github/workflows/waldo_sessions.yml @@ -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/setup-java@v3.11.0 + 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 \ No newline at end of file diff --git a/README.md b/README.md index 11ff43d0660..9011e80fa73 100644 --- a/README.md +++ b/README.md @@ -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 Flutter application 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. app showcase diff --git a/packages/app_store/apple_app_store/lib/src/apple_app_store.dart b/packages/app_store/apple_app_store/lib/src/apple_app_store.dart index 00b21f21660..0513aef47cd 100644 --- a/packages/app_store/apple_app_store/lib/src/apple_app_store.dart +++ b/packages/app_store/apple_app_store/lib/src/apple_app_store.dart @@ -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; diff --git a/packages/scanner/ml_kit/lib/src/scanner_ml_kit.dart b/packages/scanner/ml_kit/lib/src/scanner_ml_kit.dart index c34384ace10..2b67d7fd0a8 100644 --- a/packages/scanner/ml_kit/lib/src/scanner_ml_kit.dart +++ b/packages/scanner/ml_kit/lib/src/scanner_ml_kit.dart @@ -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'; @@ -83,7 +84,6 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit> static const ValueKey _visibilityKey = ValueKey('VisibilityDetector'); - static const double _cornerPadding = 26.0; bool _isStarted = true; @@ -100,6 +100,11 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit> autoStart: true, ); + // Stores a background operation when the screen isn't visible + CancelableOperation? _autoStopCameraOperation; + // Stores the latest visibility value of the screen + VisibilityInfo? _latestVisibilityInfoEvent; + @override void initState() { super.initState(); @@ -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.fromFuture( + Future.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 _pauseCameraWhenInitialized() async { + if (!mounted) { + return; + } + if (_controller.isStarting) { - return Future.delayed( - const Duration(milliseconds: 250), - () => _pauseCameraWhenInitialized(), + _autoStopCameraOperation = CancelableOperation.fromFuture( + Future.delayed( + const Duration(milliseconds: 250), + () => _pauseCameraWhenInitialized(), + ), ); } @@ -155,6 +199,7 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit> } Future _stop() async { + _autoStopCameraOperation?.cancel(); if (!_isStarted) { return; } @@ -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 { @@ -200,14 +246,15 @@ 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 @@ -215,12 +262,14 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit> crossAxisAlignment: CrossAxisAlignment.center, children: [ 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( + child: ValueListenableBuilder( valueListenable: _controller.cameraFacingState, builder: ( BuildContext context, @@ -235,10 +284,6 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit> } }, ), - onPressed: () async { - widget.hapticFeedback.call(); - await _controller.switchCamera(); - }, ), ValueListenableBuilder( valueListenable: _controller.hasTorchState, @@ -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( + onTap: () async { + widget.hapticFeedback.call(); + + try { + await _controller.toggleTorch(); + } catch (err) { + widget.onCameraFlashError?.call(context); + } + }, + child: ValueListenableBuilder( valueListenable: _controller.torchState, builder: ( BuildContext context, @@ -276,15 +328,6 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit> } }, ), - onPressed: () async { - widget.hapticFeedback.call(); - - try { - await _controller.toggleTorch(); - } catch (err) { - widget.onCameraFlashError?.call(context); - } - }, ); }, ), @@ -300,6 +343,7 @@ class _SmoothBarcodeScannerMLKitState extends State<_SmoothBarcodeScannerMLKit> @override void dispose() { WidgetsBinding.instance.removeObserver(this); + _autoStopCameraOperation?.cancel(); _controller.dispose(); super.dispose(); } diff --git a/packages/scanner/ml_kit/pubspec.yaml b/packages/scanner/ml_kit/pubspec.yaml index 9acba17987f..2a1f8e93a1b 100644 --- a/packages/scanner/ml_kit/pubspec.yaml +++ b/packages/scanner/ml_kit/pubspec.yaml @@ -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 diff --git a/packages/scanner/shared/lib/src/scanner_visor.dart b/packages/scanner/shared/lib/src/scanner_visor.dart index ee903f9f8d5..a8cb880ca57 100644 --- a/packages/scanner/shared/lib/src/scanner_visor.dart +++ b/packages/scanner/shared/lib/src/scanner_visor.dart @@ -3,12 +3,13 @@ import 'package:flutter_svg/flutter_svg.dart'; class SmoothBarcodeScannerVisor extends StatelessWidget { const SmoothBarcodeScannerVisor({ - required this.cornerRadius, this.contentPadding, super.key, }); - final double cornerRadius; + static const double CORNER_PADDING = 26.0; + static const double STROKE_WIDTH = 3.0; + final EdgeInsetsGeometry? contentPadding; @override @@ -19,7 +20,7 @@ class SmoothBarcodeScannerVisor extends StatelessWidget { padding: contentPadding, // The duration is twice the time required to hide the header duration: const Duration(milliseconds: 250), - curve: contentPadding.horizontal > cornerRadius * 2 + curve: contentPadding.horizontal > CORNER_PADDING * 2 ? Curves.easeOutQuad : Curves.decelerate, child: SizedBox.expand( @@ -39,13 +40,13 @@ class SmoothBarcodeScannerVisor extends StatelessWidget { EdgeInsetsGeometry _computePadding() { if (contentPadding == null) { - return EdgeInsets.all(cornerRadius); + return const EdgeInsets.all(CORNER_PADDING); } else { - return EdgeInsets.only( - top: cornerRadius / 4.0, - left: cornerRadius, - right: cornerRadius, - bottom: cornerRadius, + return const EdgeInsets.only( + top: CORNER_PADDING / 4.0, + left: CORNER_PADDING, + right: CORNER_PADDING, + bottom: CORNER_PADDING, ).add(contentPadding!); } } @@ -54,13 +55,12 @@ class SmoothBarcodeScannerVisor extends StatelessWidget { class _ScanVisorPainter extends CustomPainter { _ScanVisorPainter(); - static const double strokeWidth = 3.0; static const double _fullCornerSize = 31.0; static const double _halfCornerSize = _fullCornerSize / 2; static const Radius _borderRadius = Radius.circular(_halfCornerSize); final Paint _paint = Paint() - ..strokeWidth = strokeWidth + ..strokeWidth = SmoothBarcodeScannerVisor.STROKE_WIDTH ..color = Colors.white ..style = PaintingStyle.stroke; @@ -79,7 +79,7 @@ class _ScanVisorPainter extends CustomPainter { static Path getPath(Rect rect, bool includeLineBetweenCorners) { final double bottomPosition; if (includeLineBetweenCorners) { - bottomPosition = rect.bottom - strokeWidth; + bottomPosition = rect.bottom - SmoothBarcodeScannerVisor.STROKE_WIDTH; } else { bottomPosition = rect.bottom; } @@ -146,3 +146,38 @@ class _ScanVisorPainter extends CustomPainter { return path; } } + +class VisorButton extends StatelessWidget { + const VisorButton({ + required this.child, + required this.onTap, + required this.tooltip, + }); + + final VoidCallback onTap; + final String tooltip; + final Widget child; + + @override + Widget build(BuildContext context) { + return Material( + type: MaterialType.transparency, + child: InkWell( + onTap: onTap, + borderRadius: const BorderRadius.all( + Radius.circular( + SmoothBarcodeScannerVisor.CORNER_PADDING, + ), + ), + child: Tooltip( + message: tooltip, + enableFeedback: true, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: child, + ), + ), + ), + ); + } +} diff --git a/packages/scanner/zxing/lib/src/scanner_zxing.dart b/packages/scanner/zxing/lib/src/scanner_zxing.dart index 448f9921a73..2a62a25e2e3 100644 --- a/packages/scanner/zxing/lib/src/scanner_zxing.dart +++ b/packages/scanner/zxing/lib/src/scanner_zxing.dart @@ -78,8 +78,6 @@ class _SmoothBarcodeScannerZXingState BarcodeFormat.upcE, ]; - static const double _cornerPadding = 26; - bool _visible = false; final GlobalKey _qrKey = GlobalKey(debugLabel: 'QR'); QRViewController? _controller; @@ -131,14 +129,15 @@ class _SmoothBarcodeScannerZXingState ), 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 @@ -146,16 +145,15 @@ class _SmoothBarcodeScannerZXingState crossAxisAlignment: CrossAxisAlignment.center, children: [ if (_showFlipCameraButton) - IconButton( - icon: Icon(getCameraFlip()), + VisorButton( tooltip: widget.toggleCameraModeTooltip ?? 'Switch between back and front camera', - color: Colors.white, - onPressed: () async { + onTap: () async { widget.hapticFeedback.call(); await _controller?.flipCamera(); setState(() {}); }, + child: Icon(getCameraFlip()), ), FutureBuilder( future: _controller?.getFlashStatus(), @@ -164,14 +162,10 @@ class _SmoothBarcodeScannerZXingState if (flashOn == null) { return EMPTY_WIDGET; } - return IconButton( - icon: - Icon(flashOn ? Icons.flash_on : Icons.flash_off), - enableFeedback: true, + return VisorButton( tooltip: widget.toggleFlashModeTooltip ?? 'Turn ON or OFF the flash of the camera', - color: Colors.white, - onPressed: () async { + onTap: () async { widget.hapticFeedback.call(); try { @@ -181,6 +175,9 @@ class _SmoothBarcodeScannerZXingState widget.onCameraFlashError?.call(context); } }, + child: Icon( + flashOn ? Icons.flash_on : Icons.flash_off, + ), ); }, ), diff --git a/packages/smooth_app/lib/cards/product_cards/smooth_product_base_card.dart b/packages/smooth_app/lib/cards/product_cards/smooth_product_base_card.dart index 8f77f3acc9a..94aeaff7797 100644 --- a/packages/smooth_app/lib/cards/product_cards/smooth_product_base_card.dart +++ b/packages/smooth_app/lib/cards/product_cards/smooth_product_base_card.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:smooth_app/generic_lib/design_constants.dart'; import 'package:smooth_app/generic_lib/widgets/smooth_card.dart'; +import 'package:smooth_app/helpers/haptic_feedback_helper.dart'; /// A common Widget for carrousel item cards. /// It allows to have the correct width/height and also a scale down feature, @@ -12,11 +13,13 @@ class SmoothProductBaseCard extends StatelessWidget { const SmoothProductBaseCard({ required this.child, this.backgroundColorOpacity, + this.margin, super.key, }); final Widget child; final double? backgroundColorOpacity; + final EdgeInsets? margin; @override Widget build(BuildContext context) { @@ -34,6 +37,7 @@ class SmoothProductBaseCard extends StatelessWidget { color: themeData.brightness == Brightness.light ? Colors.white.withOpacity(backgroundColorOpacity ?? 1.0) : Colors.black.withOpacity(backgroundColorOpacity ?? 1.0), + margin: margin, padding: padding, child: FittedBox( fit: BoxFit.scaleDown, @@ -66,7 +70,10 @@ class ProductCardCloseButton extends StatelessWidget { return InkWell( customBorder: const CircleBorder(), - onTap: () => onRemove?.call(context), + onTap: () { + onRemove?.call(context); + SmoothHapticFeedback.lightNotification(); + }, child: Tooltip( message: appLocalizations.product_card_remove_product_tooltip, child: Padding( diff --git a/packages/smooth_app/lib/cards/product_cards/smooth_product_card_not_found.dart b/packages/smooth_app/lib/cards/product_cards/smooth_product_card_not_found.dart index e98940e9bec..22c8c933a98 100644 --- a/packages/smooth_app/lib/cards/product_cards/smooth_product_card_not_found.dart +++ b/packages/smooth_app/lib/cards/product_cards/smooth_product_card_not_found.dart @@ -25,6 +25,9 @@ class SmoothProductCardNotFound extends StatelessWidget { final TextTheme textTheme = Theme.of(context).textTheme; return SmoothProductBaseCard( + margin: const EdgeInsets.symmetric( + vertical: VERY_SMALL_SPACE, + ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, diff --git a/packages/smooth_app/lib/helpers/analytics_helper.dart b/packages/smooth_app/lib/helpers/analytics_helper.dart index 786d12577c9..eee1ef29dbf 100644 --- a/packages/smooth_app/lib/helpers/analytics_helper.dart +++ b/packages/smooth_app/lib/helpers/analytics_helper.dart @@ -199,7 +199,7 @@ class AnalyticsHelper { _analyticsReporting = _AnalyticsTrackingMode.anonymous; } - await MatomoTracker.instance.setOptOut(optout: false); + await MatomoTracker.instance.setOptOut(optOut: false); if (MatomoTracker.instance.initialized) { MatomoTracker.instance.setVisitorUserId(_uuid); diff --git a/packages/smooth_app/lib/pages/onboarding/next_button.dart b/packages/smooth_app/lib/pages/onboarding/next_button.dart index d0ba7bdbc86..1c167cf4e9f 100644 --- a/packages/smooth_app/lib/pages/onboarding/next_button.dart +++ b/packages/smooth_app/lib/pages/onboarding/next_button.dart @@ -46,8 +46,8 @@ class NextButton extends StatelessWidget { backgroundColor: Colors.white, foregroundColor: Colors.black, icon: ConstantIcons.instance.getBackIcon(), - iconPadding: Platform.isIOS - ? const EdgeInsetsDirectional.only(end: 2.5) + iconPadding: Platform.isIOS || Platform.isMacOS + ? const EdgeInsetsDirectional.only(end: 2.0) : EdgeInsets.zero, ), rightButton: OnboardingBottomButton( diff --git a/packages/smooth_app/lib/pages/preferences/user_preferences_widgets.dart b/packages/smooth_app/lib/pages/preferences/user_preferences_widgets.dart index 52dbe65988d..ae70212176f 100644 --- a/packages/smooth_app/lib/pages/preferences/user_preferences_widgets.dart +++ b/packages/smooth_app/lib/pages/preferences/user_preferences_widgets.dart @@ -92,6 +92,7 @@ class UserPreferencesSwitchItem extends StatelessWidget { style: const TextStyle(height: 1.5), ), ), + activeColor: Theme.of(context).primaryColor, value: value, onChanged: onChanged, isThreeLine: true, diff --git a/packages/smooth_app/lib/pages/product/summary_card.dart b/packages/smooth_app/lib/pages/product/summary_card.dart index a9e0593e32e..f10374acd11 100644 --- a/packages/smooth_app/lib/pages/product/summary_card.dart +++ b/packages/smooth_app/lib/pages/product/summary_card.dart @@ -48,6 +48,7 @@ class SummaryCard extends StatefulWidget { this.isSettingClickable = true, this.isProductEditable = true, this.attributeGroupsClickable = true, + this.padding, }); final Product _product; @@ -75,6 +76,8 @@ class SummaryCard extends StatefulWidget { /// If true, all chips / groups are clickable final bool attributeGroupsClickable; + final EdgeInsetsGeometry? padding; + @override State createState() => _SummaryCardState(); } @@ -107,7 +110,7 @@ class _SummaryCardState extends State with UpToDateMixin { isSettingClickable: widget.isSettingClickable, ), body: Padding( - padding: SMOOTH_CARD_PADDING, + padding: widget.padding ?? SMOOTH_CARD_PADDING, child: _buildSummaryCardContent(context), ), margin: EdgeInsets.zero, @@ -121,10 +124,11 @@ class _SummaryCardState extends State with UpToDateMixin { Widget _buildLimitedSizeSummaryCard(double parentHeight) { return Padding( - padding: const EdgeInsets.symmetric( - horizontal: SMALL_SPACE, - vertical: VERY_SMALL_SPACE, - ), + padding: widget.padding ?? + const EdgeInsets.symmetric( + horizontal: SMALL_SPACE, + vertical: VERY_SMALL_SPACE, + ), child: Stack( children: [ ClipRRect( diff --git a/packages/smooth_app/lib/pages/scan/scan_page.dart b/packages/smooth_app/lib/pages/scan/scan_page.dart index e794f89909f..89c986e159f 100644 --- a/packages/smooth_app/lib/pages/scan/scan_page.dart +++ b/packages/smooth_app/lib/pages/scan/scan_page.dart @@ -97,7 +97,7 @@ class _ScanPageState extends State { Expanded( flex: _carouselHeightPct, child: Padding( - padding: const EdgeInsetsDirectional.only(bottom: 10), + padding: const EdgeInsetsDirectional.only(bottom: 10.0), child: SmoothProductCarousel( containSearchCard: true, onPageChangedTo: (int page, String? barcode) async { @@ -187,11 +187,9 @@ class _PermissionDeniedCard extends StatelessWidget { return Container( alignment: Alignment.topCenter, constraints: BoxConstraints.tightForFinite( - width: constraints.maxWidth * - SmoothProductCarousel.carouselViewPortFraction, + width: constraints.maxWidth, height: math.min(constraints.maxHeight * 0.9, 200), ), - padding: SmoothProductCarousel.carouselItemInternalPadding, child: SmoothCard( padding: const EdgeInsetsDirectional.only( top: 10.0, diff --git a/packages/smooth_app/lib/pages/scan/scan_product_card.dart b/packages/smooth_app/lib/pages/scan/scan_product_card.dart index 1d35f7d120f..a4a362b6681 100644 --- a/packages/smooth_app/lib/pages/scan/scan_product_card.dart +++ b/packages/smooth_app/lib/pages/scan/scan_product_card.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:openfoodfacts/openfoodfacts.dart'; import 'package:provider/provider.dart'; import 'package:smooth_app/data_models/product_preferences.dart'; +import 'package:smooth_app/generic_lib/design_constants.dart'; import 'package:smooth_app/pages/navigator/app_navigator.dart'; import 'package:smooth_app/pages/product/hideable_container.dart'; import 'package:smooth_app/pages/product/summary_card.dart'; @@ -34,6 +35,9 @@ class ScanProductCard extends StatelessWidget { product, productPreferences, attributeGroupsClickable: false, + padding: const EdgeInsets.symmetric( + vertical: VERY_SMALL_SPACE, + ), ), ), ), diff --git a/packages/smooth_app/lib/pages/scan/smooth_barcode_scanner_visor.dart b/packages/smooth_app/lib/pages/scan/smooth_barcode_scanner_visor.dart deleted file mode 100644 index c06335eb5fc..00000000000 --- a/packages/smooth_app/lib/pages/scan/smooth_barcode_scanner_visor.dart +++ /dev/null @@ -1,120 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:smooth_app/helpers/app_helper.dart'; - -// TODO(m123): Remove this file and place it into packages/scanner/shared/src - -class SmoothBarcodeScannerVisor extends StatelessWidget { - const SmoothBarcodeScannerVisor({super.key}); - - @override - Widget build(BuildContext context) => SizedBox.expand( - child: CustomPaint( - painter: _ScanVisorPainter(), - child: Center( - child: SvgPicture.asset( - 'assets/icons/visor_icon.svg', - width: 35.0, - height: 32.0, - package: AppHelper.APP_PACKAGE, - ), - ), - ), - ); -} - -class _ScanVisorPainter extends CustomPainter { - _ScanVisorPainter(); - - static const double strokeWidth = 3.0; - static const double _fullCornerSize = 31.0; - static const double _halfCornerSize = _fullCornerSize / 2; - static const Radius _borderRadius = Radius.circular(_halfCornerSize); - - final Paint _paint = Paint() - ..strokeWidth = strokeWidth - ..color = Colors.white - ..style = PaintingStyle.stroke; - - @override - void paint(Canvas canvas, Size size) { - final Rect rect = Rect.fromLTRB(0.0, 0.0, size.width, size.height); - canvas.drawPath(getPath(rect, false), _paint); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; - - /// Returns a path to draw the visor - /// [includeLineBetweenCorners] will draw lines between each corner, instead - /// of moving the cursor - static Path getPath(Rect rect, bool includeLineBetweenCorners) { - final double bottomPosition; - if (includeLineBetweenCorners) { - bottomPosition = rect.bottom - strokeWidth; - } else { - bottomPosition = rect.bottom; - } - - final Path path = Path() - // Top left - ..moveTo(rect.left, rect.top + _fullCornerSize) - ..lineTo(rect.left, rect.top + _halfCornerSize) - ..arcToPoint( - Offset(rect.left + _halfCornerSize, rect.top), - radius: _borderRadius, - ) - ..lineTo(rect.left + _fullCornerSize, rect.top); - - // Top right - if (includeLineBetweenCorners) { - path.lineTo(rect.right - _fullCornerSize, rect.top); - } else { - path.moveTo(rect.right - _fullCornerSize, rect.top); - } - - path - ..lineTo(rect.right - _halfCornerSize, rect.top) - ..arcToPoint( - Offset(rect.right, _halfCornerSize), - radius: _borderRadius, - ) - ..lineTo(rect.right, rect.top + _fullCornerSize); - - // Bottom right - if (includeLineBetweenCorners) { - path.lineTo(rect.right, bottomPosition - _fullCornerSize); - } else { - path.moveTo(rect.right, bottomPosition - _fullCornerSize); - } - - path - ..lineTo(rect.right, bottomPosition - _halfCornerSize) - ..arcToPoint( - Offset(rect.right - _halfCornerSize, bottomPosition), - radius: _borderRadius, - ) - ..lineTo(rect.right - _fullCornerSize, bottomPosition); - - // Bottom left - if (includeLineBetweenCorners) { - path.lineTo(rect.left + _fullCornerSize, bottomPosition); - } else { - path.moveTo(rect.left + _fullCornerSize, bottomPosition); - } - - path - ..lineTo(rect.left + _halfCornerSize, bottomPosition) - ..arcToPoint( - Offset(rect.left, bottomPosition - _halfCornerSize), - radius: _borderRadius, - ) - ..lineTo(rect.left, bottomPosition - _fullCornerSize); - - if (includeLineBetweenCorners) { - path.lineTo(rect.left, rect.top + _halfCornerSize); - } - - return path; - } -} diff --git a/packages/smooth_app/lib/widgets/smooth_product_carousel.dart b/packages/smooth_app/lib/widgets/smooth_product_carousel.dart index 79497163932..9846521feb4 100644 --- a/packages/smooth_app/lib/widgets/smooth_product_carousel.dart +++ b/packages/smooth_app/lib/widgets/smooth_product_carousel.dart @@ -7,6 +7,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:provider/provider.dart'; +import 'package:scanner_shared/scanner_shared.dart' hide EMPTY_WIDGET; import 'package:smooth_app/cards/product_cards/smooth_product_base_card.dart'; import 'package:smooth_app/cards/product_cards/smooth_product_card_error.dart'; import 'package:smooth_app/cards/product_cards/smooth_product_card_loading.dart'; @@ -32,22 +33,13 @@ class SmoothProductCarousel extends StatefulWidget { final bool containSearchCard; final Function(int page, String? productBarcode)? onPageChangedTo; - static const EdgeInsetsGeometry carouselItemHorizontalPadding = - EdgeInsetsDirectional.only( - top: LARGE_SPACE, - start: VERY_LARGE_SPACE, - end: VERY_LARGE_SPACE, - bottom: VERY_LARGE_SPACE, - ); - static const EdgeInsetsGeometry carouselItemInternalPadding = - EdgeInsets.symmetric(horizontal: 2.0); - static const double carouselViewPortFraction = 0.91; - @override State createState() => _SmoothProductCarouselState(); } class _SmoothProductCarouselState extends State { + static const double HORIZONTAL_SPACE_BETWEEN_CARDS = 5.0; + final CarouselController _controller = CarouselController(); List barcodes = []; bool _returnToSearchCard = false; @@ -128,17 +120,21 @@ class _SmoothProductCarouselState extends State { itemCount: barcodes.length + _searchCardAdjustment, itemBuilder: (BuildContext context, int itemIndex, int itemRealIndex) { - return Padding( - padding: SmoothProductCarousel.carouselItemInternalPadding, - child: widget.containSearchCard && itemIndex == 0 - ? SearchCard(height: constraints.maxHeight) - : _getWidget(itemIndex - _searchCardAdjustment), + return SizedBox.expand( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: HORIZONTAL_SPACE_BETWEEN_CARDS, + ), + child: widget.containSearchCard && itemIndex == 0 + ? SearchCard(height: constraints.maxHeight) + : _getWidget(itemIndex - _searchCardAdjustment), + ), ); }, carouselController: _controller, options: CarouselOptions( enlargeCenterPage: false, - viewportFraction: SmoothProductCarousel.carouselViewPortFraction, + viewportFraction: _computeViewPortFraction(), height: constraints.maxHeight, enableInfiniteScroll: false, onPageChanged: (int index, CarouselPageChangedReason reason) { @@ -206,6 +202,15 @@ class _SmoothProductCarouselState extends State { ); } } + + double _computeViewPortFraction() { + final double screenWidth = MediaQuery.of(context).size.width; + return (screenWidth - + (SmoothBarcodeScannerVisor.CORNER_PADDING * 2) - + (SmoothBarcodeScannerVisor.STROKE_WIDTH * 2) + + (HORIZONTAL_SPACE_BETWEEN_CARDS * 4)) / + screenWidth; + } } class SearchCard extends StatelessWidget { @@ -223,6 +228,9 @@ class SearchCard extends StatelessWidget { return SmoothProductBaseCard( backgroundColorOpacity: OPACITY, + margin: const EdgeInsets.symmetric( + vertical: VERY_SMALL_SPACE, + ), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, diff --git a/packages/smooth_app/macos/Podfile b/packages/smooth_app/macos/Podfile index dade8dfad0d..049abe29542 100644 --- a/packages/smooth_app/macos/Podfile +++ b/packages/smooth_app/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.11' +platform :osx, '10.14' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/packages/smooth_app/macos/Podfile.lock b/packages/smooth_app/macos/Podfile.lock new file mode 100644 index 00000000000..c29e0e1cb54 --- /dev/null +++ b/packages/smooth_app/macos/Podfile.lock @@ -0,0 +1,110 @@ +PODS: + - audioplayers_darwin (0.0.1): + - FlutterMacOS + - device_info_plus (0.0.1): + - FlutterMacOS + - file_selector_macos (0.0.1): + - FlutterMacOS + - flutter_secure_storage_macos (3.3.1): + - FlutterMacOS + - FlutterMacOS (1.0.0) + - FMDB (2.7.5): + - FMDB/standard (= 2.7.5) + - FMDB/standard (2.7.5) + - in_app_review (0.2.0): + - FlutterMacOS + - mobile_scanner (3.0.0): + - FlutterMacOS + - package_info_plus (0.0.1): + - FlutterMacOS + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - Sentry/HybridSDK (7.31.5) + - sentry_flutter (0.0.1): + - Flutter + - FlutterMacOS + - Sentry/HybridSDK (= 7.31.5) + - share_plus (0.0.1): + - FlutterMacOS + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - sqflite (0.0.2): + - FlutterMacOS + - FMDB (>= 2.7.5) + - url_launcher_macos (0.0.1): + - FlutterMacOS + +DEPENDENCIES: + - audioplayers_darwin (from `Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos`) + - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) + - file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`) + - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`) + - FlutterMacOS (from `Flutter/ephemeral`) + - in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`) + - mobile_scanner (from `Flutter/ephemeral/.symlinks/plugins/mobile_scanner/macos`) + - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) + - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) + - sentry_flutter (from `Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos`) + - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) + - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) + - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) + - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) + +SPEC REPOS: + trunk: + - FMDB + - Sentry + +EXTERNAL SOURCES: + audioplayers_darwin: + :path: Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos + device_info_plus: + :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos + file_selector_macos: + :path: Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos + flutter_secure_storage_macos: + :path: Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos + FlutterMacOS: + :path: Flutter/ephemeral + in_app_review: + :path: Flutter/ephemeral/.symlinks/plugins/in_app_review/macos + mobile_scanner: + :path: Flutter/ephemeral/.symlinks/plugins/mobile_scanner/macos + package_info_plus: + :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos + path_provider_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin + sentry_flutter: + :path: Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos + share_plus: + :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos + shared_preferences_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin + sqflite: + :path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos + url_launcher_macos: + :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos + +SPEC CHECKSUMS: + audioplayers_darwin: dcad41de4fbd0099cb3749f7ab3b0cb8f70b810c + device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f + file_selector_macos: 0f85c1108e2fd597b58246bc0b0c1cb483d7593b + flutter_secure_storage_macos: 6ceee8fbc7f484553ad17f79361b556259df89aa + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + in_app_review: a850789fad746e89bce03d4aeee8078b45a53fd0 + mobile_scanner: ed7618fb749adc6574563e053f3b8e5002c13994 + package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce + path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 + Sentry: 4c9babff9034785067c896fd580b1f7de44da020 + sentry_flutter: 1346a880b24c0240807b53b10cf50ddad40f504e + share_plus: 76dd39142738f7a68dd57b05093b5e8193f220f7 + shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c + sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea + url_launcher_macos: 5335912b679c073563f29d89d33d10d459f95451 + +PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 + +COCOAPODS: 1.12.1 diff --git a/packages/smooth_app/macos/Runner.xcodeproj/project.pbxproj b/packages/smooth_app/macos/Runner.xcodeproj/project.pbxproj index 5a8906299c8..ede8e8e666e 100644 --- a/packages/smooth_app/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/smooth_app/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ @@ -256,6 +256,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -404,7 +405,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -483,7 +484,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -530,7 +531,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png index 82b6f9d9a33..c07ed39868e 100644 Binary files a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png index 13b35eba55c..2b356a32109 100644 Binary files a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png index 0a3f5fa40fb..60ff11baf0c 100644 Binary files a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png index bdb57226d5f..5b896d9c9d4 100644 Binary files a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png index f083318e09c..6e715cfbba5 100644 Binary files a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png index 326c0e72c9d..351d273a1ba 100644 Binary files a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png index 2f1632cfddf..bc0be216422 100644 Binary files a/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and b/packages/smooth_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/packages/smooth_app/pubspec.lock b/packages/smooth_app/pubspec.lock index 8e6bc3fcdef..44046f18cdb 100644 --- a/packages/smooth_app/pubspec.lock +++ b/packages/smooth_app/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "405666cd3cf0ee0a48d21ec67e65406aad2c726d9fa58840d3375e7bdcd32a07" + sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a url: "https://pub.dev" source: hosted - version: "60.0.0" + version: "61.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "1952250bd005bacb895a01bf1b4dc00e3ba1c526cf47dca54dfe24979c65f5b3" + sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 url: "https://pub.dev" source: hosted - version: "5.12.0" + version: "5.13.0" app_settings: dependency: "direct main" description: @@ -57,18 +57,18 @@ packages: dependency: transitive description: name: archive - sha256: "80e5141fafcb3361653ce308776cfd7d45e6e9fbb429e14eec571382c0c5fecb" + sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a" url: "https://pub.dev" source: hosted - version: "3.3.2" + version: "3.3.7" args: dependency: transitive description: name: args - sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" assorted_layout_widgets: dependency: "direct main" description: @@ -153,10 +153,10 @@ packages: dependency: transitive description: name: barcode - sha256: "52570564684bbb0240a9f1fdb6bad12adc5e0540103c1c96d6dd550bd928b1c9" + sha256: "789f898eef0bd88312470bdb2cc996f895ad7dd5f89e9adde84b204546a90b45" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.2.4" barcode_widget: dependency: "direct main" description: @@ -177,10 +177,10 @@ packages: dependency: transitive description: name: build - sha256: "43865b79fbb78532e4bff7c33087aa43b1d488c4fdef014eaef568af6d8016dc" + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.1" built_collection: dependency: transitive description: @@ -193,10 +193,10 @@ packages: dependency: transitive description: name: built_value - sha256: "2f17434bd5d52a26762043d6b43bb53b3acd029b4d9071a329f46d67ef297e6d" + sha256: "598a2a682e2a7a90f08ba39c0aaa9374c5112340f0a2e275f61b59389543d166" url: "https://pub.dev" source: hosted - version: "8.5.0" + version: "8.6.1" camera: dependency: "direct main" description: @@ -209,10 +209,10 @@ packages: dependency: transitive description: name: camera_android - sha256: f83e406d34f5faa80bf0f5c3beee4b4c11da94a94e9621c1bb8e312988621b4b + sha256: cac448df2567b35e2bd70b8c66368fcba4923f88bc898723516c2ce553765db6 url: "https://pub.dev" source: hosted - version: "0.10.8+2" + version: "0.10.8+4" camera_avfoundation: dependency: transitive description: @@ -321,18 +321,18 @@ packages: dependency: transitive description: name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" csslib: dependency: transitive description: name: csslib - sha256: b36c7f7e24c0bdf1bf9a3da461c837d1de64b9f8beb190c9011d8c72a3dfd745 + sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f" url: "https://pub.dev" source: hosted - version: "0.17.2" + version: "0.17.3" cupertino_icons: dependency: "direct main" description: @@ -345,10 +345,10 @@ packages: dependency: transitive description: name: dart_style - sha256: f4f1f73ab3fd2afcbcca165ee601fe980d966af6a21b5970c6c9376955c528ad + sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" data_importer: dependency: "direct main" description: @@ -431,34 +431,34 @@ packages: dependency: transitive description: name: file_selector_linux - sha256: d17c5e450192cdc40b718804dfb4eaf79a71bed60ee9530703900879ba50baa3 + sha256: "770eb1ab057b5ae4326d1c24cc57710758b9a46026349d021d6311bd27580046" url: "https://pub.dev" source: hosted - version: "0.9.1+3" + version: "0.9.2" file_selector_macos: dependency: transitive description: name: file_selector_macos - sha256: "6290eec24fc4cc62535fe609e0c6714d3c1306191dc8c3b0319eaecc09423a3a" + sha256: "4ada532862917bf16e3adb3891fe3a5917a58bae03293e497082203a80909412" url: "https://pub.dev" source: hosted - version: "0.9.2" + version: "0.9.3+1" file_selector_platform_interface: dependency: transitive description: name: file_selector_platform_interface - sha256: "2a7f4bbf7bd2f022ecea85bfb1754e87f7dd403a9abc17a84a4fa2ddfe2abc0a" + sha256: "412705a646a0ae90f33f37acfae6a0f7cbc02222d6cd34e479421c3e74d3853c" url: "https://pub.dev" source: hosted - version: "2.5.1" + version: "2.6.0" file_selector_windows: dependency: transitive description: name: file_selector_windows - sha256: ef246380b66d1fb9089fc65622c387bf3780bca79f533424c31d07f12c2c7fd8 + sha256: "1372760c6b389842b77156203308940558a2817360154084368608413835fc26" url: "https://pub.dev" source: hosted - version: "0.9.2" + version: "0.9.3" fimber: dependency: "direct main" description: @@ -513,18 +513,42 @@ packages: dependency: "direct main" description: name: flutter_email_sender - sha256: "39398c3e6cf4fbe99798d3ac6ae7d229290d57f1504a4a9a0d35f3737dc28930" + sha256: "52b713a67a966be4d9e6f68a323fc0a5bc2da71c567eb451af1aa90d30adbc3a" url: "https://pub.dev" source: hosted - version: "6.0.0" + version: "6.0.1" flutter_image_compress: dependency: "direct main" description: name: flutter_image_compress - sha256: "37f1b26399098e5f97b74c1483f534855e7dff68ead6ddaccf747029fb03f29f" + sha256: "2babae2c69ee4849c3d3ae0f1f10c14a6b8132390e4583c5d3b1f02e8167a022" url: "https://pub.dev" source: hosted - version: "1.1.3" + version: "2.0.3" + flutter_image_compress_common: + dependency: transitive + description: + name: flutter_image_compress_common + sha256: "88aae2219cd4507992643f19aee7882fe8ff82375ffa8cb4c876e3bfe3e7c3b6" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + flutter_image_compress_platform_interface: + dependency: transitive + description: + name: flutter_image_compress_platform_interface + sha256: dae0a3eb1fb7f38cf327cc2005dc287bc891becdd83c519277de4415fd9e065d + url: "https://pub.dev" + source: hosted + version: "1.0.1" + flutter_image_compress_web: + dependency: transitive + description: + name: flutter_image_compress_web + sha256: "677f02509bdf5fd71afb560a22f0444e82c9ee887d223cd006cb44fd145fcb17" + url: "https://pub.dev" + source: hosted + version: "0.1.3" flutter_launcher_icons: dependency: "direct dev" description: @@ -566,10 +590,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "96af49aa6b57c10a312106ad6f71deed5a754029c24789bbf620ba784f0bd0b0" + sha256: "950e77c2bbe1692bc0874fc7fb491b96a4dc340457f4ea1641443d0a6c1ea360" url: "https://pub.dev" source: hosted - version: "2.0.14" + version: "2.0.15" flutter_secure_storage: dependency: "direct main" description: @@ -648,10 +672,10 @@ packages: dependency: transitive description: name: freezed_annotation - sha256: aeac15850ef1b38ee368d4c53ba9a847e900bb2c53a4db3f6881cbb3cb684338 + sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.4.1" fuchsia_remote_debug_protocol: dependency: transitive description: flutter @@ -669,18 +693,18 @@ packages: dependency: transitive description: name: fwfh_text_style - sha256: "37806ee0222f79b6e8d4c698c322c897eae6a817258156f40aeece4e588fac60" + sha256: f0883ccb64b7bb3f2a7a091542c2e834fc3e2a6aa54158f46b3c43b55675d8f7 url: "https://pub.dev" source: hosted - version: "2.22.08+1" + version: "2.22.8+3" glob: dependency: transitive description: name: glob - sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c" + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" go_router: dependency: "direct main" description: @@ -709,10 +733,10 @@ packages: dependency: transitive description: name: html - sha256: "58e3491f7bf0b6a4ea5110c0c688877460d1a6366731155c4a4580e7ded773e8" + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" url: "https://pub.dev" source: hosted - version: "0.15.3" + version: "0.15.4" http: dependency: "direct main" description: @@ -749,26 +773,26 @@ packages: dependency: transitive description: name: image_picker_android - sha256: "89ba2aa6904d8180ca44fd5f5014523f02319101904e3e571fbe792e395b77ed" + sha256: d2bab152deb2547ea6f53d82ebca9b7e77386bb706e5789e815d37e08ea475bb url: "https://pub.dev" source: hosted - version: "0.8.6+14" + version: "0.8.7+3" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "98f50d6b9f294c8ba35e25cc0d13b04bfddd25dbc8d32fa9d566a6572f2c081c" + sha256: "869fe8a64771b7afbc99fc433a5f7be2fea4d1cb3d7c11a48b6b579eb9c797f0" url: "https://pub.dev" source: hosted - version: "2.1.12" + version: "2.2.0" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: d779210bda268a03b57e923fb1e410f32f5c5e708ad256348bcbf1f44f558fd0 + sha256: b3e2f21feb28b24dd73a35d7ad6e83f568337c70afab5eabac876e23803f264b url: "https://pub.dev" source: hosted - version: "0.8.7+4" + version: "0.8.8" image_picker_linux: dependency: transitive description: @@ -866,10 +890,10 @@ packages: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.1" lists: dependency: transitive description: @@ -882,10 +906,10 @@ packages: dependency: transitive description: name: logging - sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" lottie: dependency: "direct main" description: @@ -914,10 +938,10 @@ packages: dependency: "direct main" description: name: matomo_tracker - sha256: "4500ed4ee9385f95e9195b448742e75c9115ffa59b4960e6ad3b79bdcd903c47" + sha256: a96ef1e0c03cd8b73db31a50352bbde31a7718333af85afbe36e8ae176cc23a4 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "3.1.0" matrix4_transform: dependency: transitive description: @@ -988,7 +1012,7 @@ packages: description: path: "." ref: HEAD - resolved-ref: "3462ba8ce07287bb2c46818660a0f03f00884804" + resolved-ref: "215b1027d8df69f621e18c855c8cb09db2fa9640" url: "https://github.com/openfoodfacts/openfoodfacts_flutter_lints.git" source: git version: "1.0.0" @@ -1052,18 +1076,18 @@ packages: dependency: transitive description: name: path_provider_foundation - sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3" + sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.2.4" path_provider_linux: dependency: transitive description: name: path_provider_linux - sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1" + sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 url: "https://pub.dev" source: hosted - version: "2.1.10" + version: "2.1.11" path_provider_platform_interface: dependency: "direct dev" description: @@ -1076,10 +1100,10 @@ packages: dependency: transitive description: name: path_provider_windows - sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6 + sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96" url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.7" percent_indicator: dependency: "direct main" description: @@ -1100,42 +1124,42 @@ packages: dependency: transitive description: name: permission_handler_android - sha256: "8028362b40c4a45298f1cbfccd227c8dd6caf0e27088a69f2ba2ab15464159e2" + sha256: c0c9754479a4c4b1c1f3862ddc11930c9b3f03bef2816bb4ea6eed1e13551d6f url: "https://pub.dev" source: hosted - version: "10.2.0" + version: "10.3.2" permission_handler_apple: dependency: transitive description: name: permission_handler_apple - sha256: "08dcb6ce628ac0b257e429944b4c652c2a4e6af725bdf12b498daa2c6b2b1edb" + sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5" url: "https://pub.dev" source: hosted - version: "9.1.0" + version: "9.1.4" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface - sha256: de20a5c3269229c1ae2e5a6b822f6cb59578b23e8255c93fbeebfc82116e6b11 + sha256: "7c6b1500385dd1d2ca61bb89e2488ca178e274a69144d26bbd65e33eae7c02a9" url: "https://pub.dev" source: hosted - version: "3.10.0" + version: "3.11.3" permission_handler_windows: dependency: transitive description: name: permission_handler_windows - sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b + sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098 url: "https://pub.dev" source: hosted - version: "0.1.2" + version: "0.1.3" petitparser: dependency: transitive description: name: petitparser - sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" + sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.4.0" photo_view: dependency: "direct main" description: @@ -1160,6 +1184,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + url: "https://pub.dev" + source: hosted + version: "3.7.3" polylabel: dependency: transitive description: @@ -1297,50 +1329,50 @@ packages: dependency: transitive description: name: shared_preferences_android - sha256: "6478c6bbbecfe9aced34c483171e90d7c078f5883558b30ec3163cf18402c749" + sha256: fe8401ec5b6dcd739a0fe9588802069e608c3fdbfd3c3c93e546cf2f90438076 url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: e014107bb79d6d3297196f4f2d0db54b5d1f85b8ea8ff63b8e8b391a02700feb + sha256: f39696b83e844923b642ce9dd4bd31736c17e697f6731a5adf445b1274cf3cd4 url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.2" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa" + sha256: "71d6806d1449b0a9d4e85e0c7a917771e672a3d5dc61149cc9fac871115018e1" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.0" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: fb5cf25c0235df2d0640ac1b1174f6466bd311f621574997ac59018a6664548d + sha256: "23b052f17a25b90ff2b61aad4cc962154da76fb62848a9ce088efe30d7c50ab1" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.0" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5" + sha256: "7347b194fb0bbeb4058e6a4e87ee70350b6b2b90f8ac5f8bd5b3a01548f6d33a" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.2.0" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173" + sha256: f95e6a43162bce43c9c3405f3eb6f39e5b5d11f65fab19196cf8225e2777624d url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.0" shimmer: dependency: "direct main" description: @@ -1358,10 +1390,10 @@ packages: dependency: transitive description: name: source_gen - sha256: "373f96cf5a8744bc9816c1ff41cf5391bbdbe3d7a96fe98c622b6738a8a7bd33" + sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" source_span: dependency: transitive description: @@ -1382,10 +1414,10 @@ packages: dependency: transitive description: name: sqflite_common - sha256: e77abf6ff961d69dfef41daccbb66b51e9983cdd5cb35bf30733598057401555 + sha256: "8f7603f3f8f126740bc55c4ca2d1027aab4b74a1267a3e31ce51fe40e3b65b8f" url: "https://pub.dev" source: hosted - version: "2.4.5" + version: "2.4.5+1" stack_trace: dependency: transitive description: @@ -1454,18 +1486,18 @@ packages: dependency: transitive description: name: tuple - sha256: "0ea99cd2f9352b2586583ab2ce6489d1f95a5f6de6fb9492faaf97ae2060f0aa" + sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.2" typed_data: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" unicode: dependency: transitive description: @@ -1478,10 +1510,10 @@ packages: dependency: transitive description: name: universal_io - sha256: "06866290206d196064fd61df4c7aea1ffe9a4e7c4ccaa8fcded42dd41948005d" + sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.2" url_launcher: dependency: "direct main" description: @@ -1494,10 +1526,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "7aac14be5f4731b923cc697ae2d42043945076cd0dbb8806baecc92c1dc88891" + sha256: "15f5acbf0dce90146a0f5a2c4a002b1814a6303c4c5c075aa2623b2d16156f03" url: "https://pub.dev" source: hosted - version: "6.0.33" + version: "6.0.36" url_launcher_ios: dependency: transitive description: @@ -1518,34 +1550,34 @@ packages: dependency: transitive description: name: url_launcher_macos - sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e" + sha256: "1c4fdc0bfea61a70792ce97157e5cc17260f61abbe4f39354513f39ec6fd73b1" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.6" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370" + sha256: bfdfa402f1f3298637d71ca8ecfe840b4696698213d5346e9d12d4ab647ee2ea url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "81fe91b6c4f84f222d186a9d23c73157dc4c8e1c71489c4d08be1ad3b228f1aa" + sha256: cc26720eefe98c1b71d85f9dc7ef0cada5132617046369d9dc296b3ecaa5cbb4 url: "https://pub.dev" source: hosted - version: "2.0.16" + version: "2.0.18" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "254708f17f7c20a9c8c471f67d86d76d4a3f9c1591aad1e15292008aceb82771" + sha256: "7967065dd2b5fccc18c653b97958fdf839c5478c28e767c61ee879f4e7882422" url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.0.7" uuid: dependency: "direct main" description: @@ -1558,26 +1590,26 @@ packages: dependency: transitive description: name: vector_graphics - sha256: ea8d3fc7b2e0f35de38a7465063ecfcf03d8217f7962aa2a6717132cb5d43a79 + sha256: "670f6e07aca990b4a2bcdc08a784193c4ccdd1932620244c3a86bb72a0eac67f" url: "https://pub.dev" source: hosted - version: "1.1.5" + version: "1.1.7" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: a5eaa5d19e123ad4f61c3718ca1ed921c4e6254238d9145f82aa214955d9aced + sha256: "7451721781d967db9933b63f5733b1c4533022c0ba373a01bdd79d1a5457f69f" url: "https://pub.dev" source: hosted - version: "1.1.5" + version: "1.1.7" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "15edc42f7eaa478ce854eaf1fbb9062a899c0e4e56e775dd73b7f4709c97c4ca" + sha256: "80a13c613c8bde758b1464a1755a7b3a8f2b6cec61fbf0f5a53c94c30f03ba2e" url: "https://pub.dev" source: hosted - version: "1.1.5" + version: "1.1.7" vector_math: dependency: transitive description: @@ -1606,10 +1638,10 @@ packages: dependency: transitive description: name: watcher - sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.1.0" webdriver: dependency: transitive description: @@ -1670,18 +1702,18 @@ packages: dependency: transitive description: name: xdg_directories - sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 + sha256: e0b1147eec179d3911f1f19b59206448f78195ca1d20514134e10641b7d7fbff url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.1" xml: dependency: transitive description: name: xml - sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5" + sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.3.0" yaml: dependency: transitive description: diff --git a/packages/smooth_app/pubspec.yaml b/packages/smooth_app/pubspec.yaml index 80d2c92e8c6..30c56176bbb 100644 --- a/packages/smooth_app/pubspec.yaml +++ b/packages/smooth_app/pubspec.yaml @@ -28,7 +28,7 @@ dependencies: image_picker: ^0.8.9 iso_countries: 2.1.0 latlong2: 0.8.1 - matomo_tracker: 2.0.0 + matomo_tracker: 3.1.0 package_info_plus: 3.0.3 device_info_plus: 8.1.0 permission_handler: 10.3.0 @@ -66,7 +66,7 @@ dependencies: lottie: 2.2.0 webview_flutter: 3.0.4 flutter_custom_tabs: ^1.0.4 - flutter_image_compress: 1.1.3 + flutter_image_compress: 2.0.3 # According to the build variant, only one "app store" implementation must be added when building a release # Call "flutter pub remove xxxx" to remove unused dependencies diff --git a/packages/smooth_app/test/dialogs/generic_lib/dialogs_test.dart b/packages/smooth_app/test/dialogs/generic_lib/dialogs_test.dart index ba6ae441f41..db25a110f66 100644 --- a/packages/smooth_app/test/dialogs/generic_lib/dialogs_test.dart +++ b/packages/smooth_app/test/dialogs/generic_lib/dialogs_test.dart @@ -10,6 +10,7 @@ import 'package:smooth_app/pages/preferences/user_preferences_page.dart'; import 'package:smooth_app/themes/color_provider.dart'; import 'package:smooth_app/themes/contrast_provider.dart'; import 'package:smooth_app/themes/theme_provider.dart'; + import '../../tests_utils/goldens.dart'; import '../../tests_utils/mocks.dart'; diff --git a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-amoled.png b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-amoled.png index a73a0a900f3..488de4e5eb6 100644 Binary files a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-amoled.png and b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-amoled.png differ diff --git a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-dark.png b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-dark.png index 7362a23806e..68131ffeef6 100644 Binary files a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-dark.png and b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-dark.png differ diff --git a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-light.png b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-light.png index f040a129d5a..e274c25004f 100644 Binary files a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-light.png and b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Improving-light.png differ diff --git a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-amoled.png b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-amoled.png index 7ce2d0226b0..a443af21fb3 100644 Binary files a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-amoled.png and b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-amoled.png differ diff --git a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-dark.png b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-dark.png index 7c7bf6da659..be07715e3ff 100644 Binary files a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-dark.png and b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-dark.png differ diff --git a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-light.png b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-light.png index 409766f0df3..028a39256c8 100644 Binary files a/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-light.png and b/packages/smooth_app/test/dialogs/generic_lib/goldens/user_preferences_page_dialogs_Translate-light.png differ diff --git a/packages/smooth_app/test/tests_utils/mocks.dart b/packages/smooth_app/test/tests_utils/mocks.dart index a63116c0e9b..eb2c3efef75 100644 --- a/packages/smooth_app/test/tests_utils/mocks.dart +++ b/packages/smooth_app/test/tests_utils/mocks.dart @@ -1,16 +1,19 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'dart:typed_data'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:matomo_tracker/matomo_tracker.dart'; import 'package:mockito/mockito.dart'; import 'package:provider/provider.dart'; import 'package:smooth_app/data_models/product_preferences.dart'; import 'package:smooth_app/data_models/user_management_provider.dart'; import 'package:smooth_app/data_models/user_preferences.dart'; import 'package:smooth_app/database/local_database.dart'; +import 'package:smooth_app/helpers/analytics_helper.dart'; import 'package:smooth_app/themes/color_provider.dart'; import 'package:smooth_app/themes/contrast_provider.dart'; import 'package:smooth_app/themes/smooth_theme.dart'; @@ -18,7 +21,7 @@ import 'package:smooth_app/themes/theme_provider.dart'; /// A wrapper for testing various pages of the app with a simple state. class MockSmoothApp extends StatelessWidget { - const MockSmoothApp( + MockSmoothApp( this.userPreferences, this.userManagementProvider, this.productPreferences, @@ -27,7 +30,9 @@ class MockSmoothApp extends StatelessWidget { this.colorProvider, this.child, { this.localDatabase, - }); + }) { + mockMatomo(); + } final UserPreferences userPreferences; final UserManagementProvider userManagementProvider; @@ -174,3 +179,46 @@ class _MockHttpClientSVGResponse extends Mock implements HttpClientResponse { final Uint8List svgBytes = utf8.encode(svgStr) as Uint8List; } + +Future mockMatomo() async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler( + const MethodChannel('dev.fluttercommunity.plus/device_info'), + (MethodCall call) async { + if (call.method == 'getDeviceInfo') { + return { + 'computerName': '_', + 'hostName': '_', + 'arch': '_', + 'model': '_', + 'kernelVersion': '_', + 'osRelease': '_', + 'activeCPUs': 1, + 'memorySize': 1, + 'cpuFrequency': 1, + }; + } + return null; + }); + + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler( + const MethodChannel('dev.fluttercommunity.plus/package_info'), + (MethodCall call) async { + if (call.method == 'getAll') { + return { + 'appName': '_', + 'packageName': '_', + 'version': '_', + 'buildNumber': '_', + 'buildSignature': '_', + 'installerStore': '_', + }; + } + return null; + }); + + await AnalyticsHelper.initMatomo(false); + MatomoTracker.instance.setOptOut(optOut: true); + MatomoTracker.instance.timer.cancel(); +} diff --git a/packages/smooth_app/windows/runner/resources/app_icon.ico b/packages/smooth_app/windows/runner/resources/app_icon.ico index c04e20caf63..68fd3e4f9d7 100644 Binary files a/packages/smooth_app/windows/runner/resources/app_icon.ico and b/packages/smooth_app/windows/runner/resources/app_icon.ico differ