smooth-app icon indicating copy to clipboard operation
smooth-app copied to clipboard

feat: image list gallery

Open VaiTon opened this issue 1 year ago • 20 comments

In V1 (at least for android) we had a "Image gallery" page which would display the list of every image related to the product.

Here we have the carousel that gets activated whenever you click on the images (or click on edit images in the edit view) but it's not really a listing of every image related to the product.

That's why, as suggested by @teolemon, with this PR I'm implementing a product image gallery view as a list of clickable items. When a tile is clicked the corresponding image is opened (if existing) to be viewed/edited, or taken.

Below a video representing the flow:

https://user-images.githubusercontent.com/12072630/182968832-e76a0185-8471-40a6-8aeb-621d09ed00f8.mp4

VaiTon avatar Aug 03 '22 19:08 VaiTon

Codecov Report

Merging #2724 (0b580a3) into develop (2ea0da3) will decrease coverage by 1.82%. The diff coverage is n/a.

@@            Coverage Diff             @@
##           develop   #2724      +/-   ##
==========================================
- Coverage     8.86%   7.04%   -1.83%     
==========================================
  Files          161     223      +62     
  Lines         6623   10679    +4056     
==========================================
+ Hits           587     752     +165     
- Misses        6036    9927    +3891     
Impacted Files Coverage Δ
...kages/smooth_app/lib/widgets/attribute_button.dart 0.00% <0.00%> (-92.00%) :arrow_down:
...s/smooth_app/lib/data_models/user_preferences.dart 8.73% <0.00%> (-23.57%) :arrow_down:
packages/smooth_app/lib/themes/smooth_theme.dart 62.26% <0.00%> (-20.72%) :arrow_down:
...p/lib/generic_lib/dialogs/smooth_alert_dialog.dart 15.11% <0.00%> (-19.10%) :arrow_down:
...mooth_app/lib/data_models/product_preferences.dart 21.68% <0.00%> (-9.75%) :arrow_down:
packages/smooth_app/lib/main.dart 14.65% <0.00%> (-3.24%) :arrow_down:
.../smooth_app/lib/pages/onboarding/welcome_page.dart 0.00% <0.00%> (-3.13%) :arrow_down:
.../smooth_app/lib/pages/onboarding/scan_example.dart 0.00% <0.00%> (-2.28%) :arrow_down:
...ackages/smooth_app/lib/pages/scan/scan_header.dart 2.50% <0.00%> (-2.27%) :arrow_down:
...p/lib/pages/onboarding/consent_analytics_page.dart 0.00% <0.00%> (-1.57%) :arrow_down:
... and 244 more

:mega: We’re building smart automated test selection to slash your CI/CD build times. Learn more

codecov-commenter avatar Aug 03 '22 19:08 codecov-commenter

@monsieurtanuki @M123-dev @g123k if you could give me an initial code review it would be great!

VaiTon avatar Aug 04 '22 14:08 VaiTon

@VaiTon For the record it's a "draft": not something reviewers spend time on spontaneously. Unless instructed to :)

monsieurtanuki avatar Aug 04 '22 17:08 monsieurtanuki

@VaiTon I don't mean to be rude but you don't provide any explanation on the PR and any /// comment in the code. We don't know what you do and why you do it. That kind of information can help reviewers.

monsieurtanuki avatar Aug 04 '22 17:08 monsieurtanuki

@VaiTon I don't mean to be rude but you don't provide any explanation on the PR and any /// comment in the code. We don't know what you do and why you do it. That kind of information can help reviewers.

Sorry! I really thought I put something in the body of the PR while I didn't :laughing:. For the Draft, I did that on purpose but I'd like your review code wise to continue this path or not.

edit @monsieurtanuki added an explanation and a video!

VaiTon avatar Aug 04 '22 22:08 VaiTon

Havn't had a look at the code, but this is definitely great to have, AFAIK the images are the most important part of the product, so we should make it easy to edit and send them.

We can use this and build upon.

Some related issues:

  • https://github.com/openfoodfacts/smooth-app/issues/766
  • https://github.com/openfoodfacts/smooth-app/issues/2484
  • https://github.com/openfoodfacts/smooth-app/issues/2429
  • https://github.com/openfoodfacts/smooth-app/issues/2427
  • https://github.com/openfoodfacts/smooth-app/issues/2426
  • https://github.com/openfoodfacts/smooth-app/issues/2424
  • https://github.com/openfoodfacts/smooth-app/issues/2351

M123-dev avatar Aug 05 '22 16:08 M123-dev

The main issue I found while coding this is that at the moment we only have like 4 categories displayed instead of every image.

For example the Nutella has lots of images on the website but on the app only 4 are displayed.

VaiTon avatar Aug 05 '22 19:08 VaiTon

Do we need to show more then that

M123-dev avatar Aug 05 '22 20:08 M123-dev

I don't know what we're supposed to display in Smoothie, but this is the data we get from the server (https://world.openfoodfacts.org/cgi/search.pl?code=3017620425035&json=1&search_terms=):

"image_front_small_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/front_en.381.200.jpg",
"image_front_thumb_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/front_en.381.100.jpg",
"image_front_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/front_en.381.400.jpg",
"image_ingredients_small_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/ingredients_en.379.200.jpg",
"image_ingredients_thumb_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/ingredients_en.379.100.jpg",
"image_ingredients_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/ingredients_en.379.400.jpg",
"image_nutrition_small_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/nutrition_en.368.200.jpg",
"image_nutrition_thumb_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/nutrition_en.368.100.jpg",
"image_nutrition_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/nutrition_en.368.400.jpg",
"image_packaging_small_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/packaging_en.369.200.jpg",
"image_packaging_thumb_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/packaging_en.369.100.jpg",
"image_packaging_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/packaging_en.369.400.jpg",
"image_small_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/front_en.381.200.jpg",
"image_thumb_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/front_en.381.100.jpg",
"image_url": "https://images.openfoodfacts.org/images/products/301/762/042/5035/front_en.381.400.jpg",

monsieurtanuki avatar Aug 06 '22 08:08 monsieurtanuki

  • Part of this is #2351. The server is sending the IDs of all stored images.

teolemon avatar Aug 06 '22 09:08 teolemon

@monsieurtanuki the query that we do in the Android app is:

/**
 * Returns images for the current product
 *
 * @param barcode barcode for the current product
 */
@GET("$API_P/product/{barcode}.json?fields=images")
suspend fun getProductImages(@Path("barcode") barcode: String): ObjectNode

VaiTon avatar Aug 06 '22 10:08 VaiTon

@VaiTon Add ProductField.images to ProductQuery.fields, and find the results in Product.images.

monsieurtanuki avatar Aug 06 '22 11:08 monsieurtanuki

@VaiTon Add ProductField.images to ProductQuery.fields, and find the results in Product.images.

Where should I do this? The idea was to query for all the images only in the gallery view

VaiTon avatar Aug 06 '22 14:08 VaiTon

Where should I do this? The idea was to query for all the images only in the gallery view

Either you do that always for all products, and add ProductField.images to ProductQuery.fields.

Or you want specifically to extract those images only if the user goes to a specific page: then you have to asyncly download only the ProductField.images for that product. Something similar to what is coded in BarcodeProductQuery, like:

  Future<List<ProductImage>?> getFetchedProduct() async {
    final ProductQueryConfiguration configuration = ProductQueryConfiguration(
      barcode,
      fields: [ProductQuery.IMAGES],
      language: ProductQuery.getLanguage(),
      country: ProductQuery.getCountry(),
    );

    final ProductResult result;
    try {
      result = await OpenFoodAPIClient.getProduct(configuration);
    } catch (e) {
      return null;
    }

    if (result.status == 1) {
      final Product? product = result.product;
      if (product != null) {
        return product.images;
      }
    }
    return null;
  }

But then you probably have to cache the results somehow...

monsieurtanuki avatar Aug 06 '22 15:08 monsieurtanuki

@monsieurtanuki thanks! I think that we maybe could do without caching for now, as editing images requires an internet connection to download them (as far as I understand)

VaiTon avatar Aug 06 '22 15:08 VaiTon

/**
 * Returns images for the current product
 *
 * @param barcode barcode for the current product
 */
@GET("$API_P/product/{barcode}.json?fields=images")
suspend fun getProductImages(@Path("barcode") barcode: String): ObjectNode

Ohh luckily I don't know kotlin if you have to suspend fun in it 😆

M123-dev avatar Aug 07 '22 09:08 M123-dev

Now it should display every image. I'm not understanding why they're not opening in full screen anymore though..

VaiTon avatar Aug 07 '22 18:08 VaiTon

And now the last problem is that by querying ProductField.images I don't get the url to display the images, so I can only edit the main 4 images. Any help @M123-dev @monsieurtanuki ?

VaiTon avatar Aug 09 '22 21:08 VaiTon

And now the last problem is that by querying ProductField.images I don't get the url to display the images, so I can only edit the main 4 images. Any help @M123-dev @monsieurtanuki ?

@VaiTon Quickly said: perhaps with ImageHelper:

static String? buildUrl(
    final String? barcode,
    final ProductImage image, {
    final QueryType? queryType,
  })

monsieurtanuki avatar Aug 10 '22 06:08 monsieurtanuki

https://static.openfoodfacts.org/images/products/359/671/046/2858/1.jpg where 1 is img_id

teolemon avatar Aug 10 '22 07:08 teolemon

@VaiTon do you have an updated screenshot ?

teolemon avatar Aug 16 '22 11:08 teolemon

Updated screenshot

immagine

VaiTon avatar Aug 16 '22 15:08 VaiTon

thanks 👍 I was indeed expecting a grid of squares for unselected images, like in v1 (for extreme cases, and also because you shouldn't be able to do all the same operations on an unselected image as on a selected one, eg client or server side cropping, rotation, unless you're explicitely mapping them to a field first (and server side operations would be preferable)

teolemon avatar Aug 16 '22 16:08 teolemon

thanks +1 I was indeed expecting a grid of squares for unselected images, like in v1 (for extreme cases, and also because you shouldn't be able to do all the same operations on an unselected image as on a selected one, eg client or server side cropping, rotation, unless you're explicitely mapping them to a field first (and server side operations would be preferable)

So we can keep the list for the selected images and a grid for the unselected images? Even keeping a list we would be able to make some actions doable only for selected images

VaiTon avatar Aug 16 '22 16:08 VaiTon

I don't know the V1, but from what I see in the website it's a bit by chapter: front, ingredients, ...

Let's imagine what we should display for each chapter (selected image with special power, and all the images).

Something like that:

FRONT
selected:
 000000
 000000
 000000

select another image:
 123456
 ABCDEF
 GHIJKL

Take another picture

Btw @VaiTon I would happily (not happily, but seriously) review your code once we agree on the display and your generated screenshots.

monsieurtanuki avatar Aug 16 '22 16:08 monsieurtanuki

@VaiTon @monsieurtanuki here's what I have in Figma image image

teolemon avatar Aug 16 '22 16:08 teolemon

@monsieurtanuki would that be in a single page? Because unselected images do not have a field so we should display every unselected image for every field

VaiTon avatar Aug 16 '22 16:08 VaiTon

@teolemon which is what we have on android.

I don't think that's really what we want because it does not separate the selected images from the unselected ones.

VaiTon avatar Aug 16 '22 16:08 VaiTon

So we could use that in 2 places:

  • one as a server side photo picker (where it makes sense)
  • and as a variation below the list of selected images, that could stay tiles, like it currently is.

teolemon avatar Aug 16 '22 16:08 teolemon

Personally I had no expectations, except a grid, so I'm not really the person to ask. @VaiTon You seem to be right regarding "unknown" pictures: on the website there are tons of pictures in a grid, and the same ton for each "chapter". In French we say "vrac", which is a dutch word that sounds perfect to say that pictures are just put somewhere.

monsieurtanuki avatar Aug 16 '22 16:08 monsieurtanuki