Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 3712 - new mlkit and zxing scanners on flutter 3.7 #3767

Merged
merged 6 commits into from
Mar 17, 2023

Conversation

monsieurtanuki
Copy link
Contributor

New files:

  • smooth_barcode_scanner_mlkit.dart: Barcode scanner based on MLKit.
  • smooth_barcode_scanner_mockup.dart: Fake barcode scanner, for tests.
  • smooth_barcode_scanner_type.dart: Barcode scanner types.
  • smooth_barcode_scanner_zxing.dart: Barcode scanner based on ZXing.

Deleted files:

  • scanner: removed folder
  • camera_controller.dart
  • camera_image_cropper.dart
  • camera_full_getter.dart
  • camera_image_preview.dart
  • camera_modes.dart
  • lifecycle_aware_widget.dart
  • lifecycle_manager.dart
  • scan_flash_toggle.dart
  • scan_visor.dart
  • scanner_overlay.dart
  • user_preferences_dialog_editor.dart

Impacted files:

  • app_test.dart: now uses new enum SmoothBarcodeScannerType
  • background_task_badge.dart: now uses flutter 3.7 badge
  • basic_test.dart: now uses new enum SmoothBarcodeScannerType
  • build.gradle: upgraded kotlin to 1.8.0
  • camera_helper.dart: simplified
  • camera_scan_page.dart: simplified
  • constant_icons.dart: added an adaptive "flip camera" icon
  • file_cache_manager_impl.dart: minor 3.7 refactoring
  • goldens.dart: minor 3.7 refactoring
  • labeler.yml: removed references to deleted files
  • main_fdroid.dart: now uses new enum SmoothBarcodeScannerType
  • main_google_play.dart: now uses new enum SmoothBarcodeScannerType
  • main_ios.dart: now uses new enum SmoothBarcodeScannerType
  • network_config.dart: minor 3.7 refactoring
  • new_product_page.dart: minor 3.7 refactoring
  • onboarding_bottom_bar.dart: minor 3.7 refactoring
  • pubspec.lock: wtf
  • apple_app_store/pubspec.yaml: minor 3.7 refactoring
  • google_play/pubspec.yaml: minor 3.7 refactoring
  • shared/pubspec.yaml: minor 3.7 refactoring
  • uri_store/pubspec.yaml: minor 3.7 refactoring
  • data_importer/pubspec.yaml: minor 3.7 refactoring
  • data_importer_shared/pubspec.yaml: minor 3.7 refactoring
  • smooth_app/pubspec.yaml: now includes mlkit and zxing scanners; minor 3.7 refactoring; removed now redundant badge; minor upgrades
  • scan_page.dart: simplified
  • user_preferences.dart: removed now useless methods
  • user_preferences_dev_mode.dart: removed duration and scan parameter settings
  • user_preferences_settings.dart: removed now useless parameter; minor 3.7 refactoring

What

  • Heavy refactoring of the barcode scanners.
  • Basically, now we rely on existing barcode scanners: mobile_scanner for mlkit and qr_code_scanner for zxing.
  • En passant, upgraded to flutter 3.7.

Screenshot

mlkit zxing
Screenshot_2023-03-14-17-15-57 Screenshot_2023-03-14-16-57-21

Fixes bug(s)

New files:
* `smooth_barcode_scanner_mlkit.dart`: Barcode scanner based on MLKit.
* `smooth_barcode_scanner_mockup.dart`: Fake barcode scanner, for tests.
* `smooth_barcode_scanner_type.dart`: Barcode scanner types.
* `smooth_barcode_scanner_zxing.dart`: Barcode scanner based on ZXing.

Deleted files:
* `scanner`: removed folder
* `camera_controller.dart`
* `camera_image_cropper.dart`
* `camera_full_getter.dart`
* `camera_image_preview.dart`
* `camera_modes.dart`
* `lifecycle_aware_widget.dart`
* `lifecycle_manager.dart`
* `scan_flash_toggle.dart`
* `scan_visor.dart`
* `scanner_overlay.dart`
* `user_preferences_dialog_editor.dart`

Impacted files:
* `app_test.dart`: now uses new enum `SmoothBarcodeScannerType`
* `background_task_badge.dart`: now uses flutter 3.7 badge
* `basic_test.dart`: now uses new enum `SmoothBarcodeScannerType`
* `build.gradle`: upgraded kotlin to 1.8.0
* `camera_helper.dart`: simplified
* `camera_scan_page.dart`: simplified
* `constant_icons.dart`: added an adaptive "flip camera" icon
* `file_cache_manager_impl.dart`: minor 3.7 refactoring
* `goldens.dart`: minor 3.7 refactoring
* `labeler.yml`: removed references to delete files
* `main_fdroid.dart`: now uses new enum `SmoothBarcodeScannerType`
* `main_google_play.dart`: now uses new enum `SmoothBarcodeScannerType`
* `main_ios.dart`: now uses new enum `SmoothBarcodeScannerType`
* `network_config.dart`: minor 3.7 refactoring
* `new_product_page.dart`: minor 3.7 refactoring
* `onboarding_bottom_bar.dart`: minor 3.7 refactoring
* `pubspec.lock`: wtf
* `apple_app_store/pubspec.yaml`: minor 3.7 refactoring
* `google_play/pubspec.yaml`: minor 3.7 refactoring
* `shared/pubspec.yaml`: minor 3.7 refactoring
* `uri_store/pubspec.yaml`: minor 3.7 refactoring
* `data_importer/pubspec.yaml`: minor 3.7 refactoring
* `data_importer_shared/pubspec.yaml`: minor 3.7 refactoring
* `smooth_app/pubspec.yaml`: now includes mlkit and zxing scanners; minor 3.7 refactoring; removed now redundant `badge`; minor upgrades
* `scan_page.dart`: simplified
* `user_preferences.dart`: removed now useless methods
* `user_preferences_dev_mode.dart`: removed duration and scan parameter settings
* `user_preferences_settings.dart`: removed now useless parameter; minor 3.7 refactoring
@monsieurtanuki monsieurtanuki requested a review from a team as a code owner March 15, 2023 09:42
@github-actions github-actions bot added Android dependencies GitHub goldens 🤗 Onboarding We need to onboard users on how the app works, but also on content like Nutri-Score, Eco-Score… Product addition The easier it is to add a product and get Nutri-Score, Eco-Score, the happier the users. 🥫 Product page 🤳🥫 Scan We need to be able to scan on low-end, old devices, even with a bad camera, connexion… 🧪 Tests 🤳 ZXing labels Mar 15, 2023
@monsieurtanuki monsieurtanuki changed the title feat/3712 - new mlkit and zxing scanners on flutter 3.7 feat: 3712 - new mlkit and zxing scanners on flutter 3.7 Mar 15, 2023
@monsieurtanuki
Copy link
Contributor Author

The code was written in flutter 3.7, as it was the main focus of the issue. The barcode scan refactoring was "only" a side-effect.
Therefore, the CI has to be upgraded to 3.7 / 2.19 for the pre-tests to work.
Meanwhile, we would be better off with a new official version of Smoothie - hopefully the last flutter 3.0.5 version.

@M123-dev
Copy link
Member

Should I push the ci changes on your branch

@monsieurtanuki
Copy link
Contributor Author

Should I push the ci changes on your branch

Please do, thanks!

@teolemon
Copy link
Member

I'm making slow progress on pushing out the release to the Apple app store, we had an issue with the CI, which is not solved yet.

@teolemon
Copy link
Member

Ok, I've fixed the build, and the iOS build has been proposed to Apple.

Copy link

@adilwahla adilwahla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOOKS GOOD

Copy link
Member

@M123-dev M123-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all thanks for your work @monsieurtanuki I can't try to test this out.
Added some comments but no dealbreaker in it.

Some other things I want to have written down, do not forget (not for this PR):

  • We should implement some kind of on phone testing*
  • Ci can be fixed to the new version with no problem, though cd is going to be harder, we likely can't build if we remove the ml or zxing dependencie, but let this be my worry in a follow-up pr.
  • We need extensive analytics
  • When someone first starts the app (also after an update?) we hand the currently selected engine a mock image which a barcode, as close to how the scanner does it as possible. If it does not work, we report it to sentry/matomo? and switch the engine. I'd suggest to at first push both to play store to now break anything on edge devices.

On some devices, it seemed that ml kit only works when we store the image on the storage and let ml kit read it from there.

/// Returns if the device has at least one camera
static bool get hasACamera {
/// Returns if the device has more than one camera
static bool get hasMoreThanOneCamera {
if (_cameras == null) {
throw Exception('Please call [init] before!');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw Exception('Please call [init] before!');
throw Exception('Please call [init] before, no cameras found!');

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No no, if you haven't called init before it's null. If you have called init before and found no camera, it's empty.

ext.kotlin_version = '1.6.10'
ext.kotlin_version = '1.8.0'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was kind of impact has this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea. It's just that I couldn't build locally without upgrading.
Maybe flutter 3.7 related?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@M123-dev Please try to build apk locally.
To me it's a nightmare with that stupid kotlin and that stupid gradle, that I was supposed to freely despise using flutter. But in fact I'm trapped.
On top of that, stupid Android Studio cannot downgrade the kotlin version, so nothing is compatible anymore between those 3 stupid moronic tools.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had some problems at first with some invalid caches which I had to delete myself and a lot of warnings about the kotlin version but it turned out to work eventually

),
);
if (!CameraHelper.hasACamera) {
return EMPTY_WIDGET;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe log something here, or show a dedicated message on the page. Unlikely for real phones, but great for debugging.

(If someone see's a "We've found no camera" text they know what to report in contrast to just a blank screen)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(If someone see's a "We've found no camera" text they know what to report in contrast to just a blank screen)

Fair enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pushed:
Screenshot_2023-03-16-19-14-54

@M123-dev Tell me if that's enough, and I localize the message.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could offer common solutions if there are any (like restarting the app, rebooting device, attaching external camera, getting your device fixed)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@teolemon I wish there were a "getting your device fixed" button :)
I don't think there are any implementable common solution.
The best thing I can do, at least for this PR, is to change the "No camera found" label. Perhaps in another PR an additional "try to detect a camera" button?

try {
await _controller.stop();
_isStarted = false;
} on Exception catch (e) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should log to sentry

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually. For the moment I'm still not 100% sure about the visibility/invisibility steps.

),
Container(
decoration: ShapeDecoration(
shape: zxing.QrScannerOverlayShape(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zxing mentioned on the mlkit page?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed:

  • zxing comes with a visor, mlkit does not, so if we use zxing's visor in mlkit we have the same UI
  • of course we could create a custom visor, different from zxing's, and use it in zxing and mlkit
  • to be discussed - I'm not sure it's worth to hassle to "xor" zxing and mlkit, code wise. We can just embed both, while using the same "flavors" as now and use only one barcode scanner, depending on the entry point parameter

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the one we had before

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the one we had before

To be honest it doesn't look that different.
But if needed, please create an issue asking for the old painter from scan_visor.dart to be implemented, instead of the default zxing visor.

@monsieurtanuki
Copy link
Contributor Author

First of all thanks for your work @monsieurtanuki

You're welcome!

We should implement some kind of on phone testing

I'm not sure how we could do that, if you mean automated tests.

Ci can be fixed to the new version with no problem, though cd is going to be harder, we likely can't build if we remove the ml or zxing dependencie, but let this be my worry in a follow-up pr.

Not sure what you mean, but as I said in a comment for this PR we may not have to select either zxing or mlkit, build wise: we just embed both and the only different is the entry point that selects which one.

We need extensive analytics

I'm not sure that's relevant anymore, as most of the work is done by the external packages.
Which analytics would you like to add?

When someone first starts the app (also after an update?) we hand the currently selected engine a mock image which a barcode, as close to how the scanner does it as possible. If it does not work, we report it to sentry/matomo? and switch the engine. I'd suggest to at first push both to play store to now break anything on edge devices.

Is that a fact? I believed that there was only one embedded scanner in the previous version.
In addition to that, that would make sense only for mlkit downgraded to zxing, as - for some reason - on FDroid mlkit is "forbidden".
I don't think we can provide an image to the engine; it works with the camera.

On some devices, it seemed that ml kit only works when we store the image on the storage and let ml kit read it from there.

Again, that's supposed to be dealt with the external mlkit package. Anyway there's no related parameter in the package. If you could find the related issue, we should contact the "problematic" users for additional tests.

@teolemon Additional thought: now we can easily create automated screenshots of the home page of the app, if we just create a specific "scanner type" called "screenshot" that displays a saved picture, with the zxing visor on top.

Impacted file:
* `camera_scan_page.dart`: new "no camera found" message
@teolemon
Copy link
Member

I was thinking on how to make the carousel feel immersive. So far, I only have half-convincing/bad ideas.

  • get rid of the carousel and loose the compare feature, and move to a card based UI at the bottom of the screen
  • make the carousel edge to edge, and get rid of the card metaphor
  • some kind of very low resolution background for the carousel, based on the dominant colors of the camera stream
  • Find a way to move the focus to the bottom up of the screen
  • Your idea here

@monsieurtanuki
Copy link
Contributor Author

I was thinking on how to make the carousel feel immersive. So far, I only have half-convincing/bad ideas.

I've just created #3777.
In the current PR we change flutter version and 78 files are created/deleted/changed, therefore I suggest to do things step by step, issue by issue, PR by PR.

Copy link
Member

@M123-dev M123-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, we are somewhat restricted on testing the scanner, don't know if that's good or not. I'd say let's merge iterate further

M123-dev and others added 2 commits March 17, 2023 14:42
Impacted files:
* `app_en.arb`: new label for "no camera found"
* `app_fr.arb`: new label for "no camera found"
* `camera_scan_page.dart`: localized "no camera found" message
@monsieurtanuki
Copy link
Contributor Author

Thank you @adilwahla @M123-dev @teolemon for your reviews, feedbacks and commits!
It's not that I'm shy but I'm not sure when I can merge this PR, regarding the 4.6.0 version?

@M123-dev
Copy link
Member

Feel free to merge, the release is done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Android dependencies GitHub goldens 🌐 l10n 🤗 Onboarding We need to onboard users on how the app works, but also on content like Nutri-Score, Eco-Score… Product addition The easier it is to add a product and get Nutri-Score, Eco-Score, the happier the users. 🥫 Product page 🤳🥫 Scan We need to be able to scan on low-end, old devices, even with a bad camera, connexion… 🧪 Tests 🤳 ZXing
Projects
None yet
4 participants