smooth-app
smooth-app copied to clipboard
feat: image list gallery
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
Codecov Report
Merging #2724 (0b580a3) into develop (2ea0da3) will decrease coverage by
1.82%
. The diff coverage isn/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
@monsieurtanuki @M123-dev @g123k if you could give me an initial code review it would be great!
@VaiTon For the record it's a "draft": not something reviewers spend time on spontaneously. Unless instructed to :)
@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.
@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!
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
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.
Do we need to show more then that
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",
- Part of this is #2351. The server is sending the IDs of all stored images.
@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 Add ProductField.images
to ProductQuery.fields
, and find the results in Product.images
.
@VaiTon Add
ProductField.images
toProductQuery.fields
, and find the results inProduct.images
.
Where should I do this? The idea was to query for all the images only in the gallery view
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 async
ly 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 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)
/** * 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 😆
Now it should display every image. I'm not understanding why they're not opening in full screen anymore though..
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 ?
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,
})
https://static.openfoodfacts.org/images/products/359/671/046/2858/1.jpg where 1 is img_id
@VaiTon do you have an updated screenshot ?
Updated screenshot
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)
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
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.
@VaiTon @monsieurtanuki here's what I have in Figma
@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
@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.
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.
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.