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: 4674 - new UI for main image page; fallback image only for product icon #4738

Merged
merged 2 commits into from
Oct 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ class ProductImageCarousel extends StatelessWidget {
final List<ProductImageData> productImagesData = getProductMainImagesData(
product,
ProductQuery.getLanguage(),
includeOther: true,
);
productImagesData.add(getEmptyProductImageData(ImageField.OTHER));
return SizedBox(
height: height,
child: ListView.builder(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/widgets/images/smooth_image.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_card.dart';
import 'package:smooth_app/themes/constant_icons.dart';

Expand All @@ -15,24 +13,6 @@ class SmoothListTileCard extends StatelessWidget {
Key? key,
}) : super(key: key);

/// Displays a [ListTile] inside a [SmoothCard] with a leading [Column]
/// containing the specified [imageProvider]
SmoothListTileCard.image({
required ImageProvider? imageProvider,
Widget? title,
GestureTapCallback? onTap,
String? heroTag,
}) : this(
title: title,
onTap: onTap,
leading: SmoothImage(
width: VERY_LARGE_SPACE * 5,
height: MEDIUM_SPACE * 5,
imageProvider: imageProvider,
heroTag: heroTag,
),
);

/// Displays a [ListTile] inside a [SmoothCard] with a leading [Column]
/// containing the specified [icon]
SmoothListTileCard.icon({
Expand All @@ -53,36 +33,6 @@ class SmoothListTileCard extends StatelessWidget {
),
);

/// Displays a loading card with a shimmering effect
SmoothListTileCard.loading()
: this(
title: Shimmer.fromColors(
baseColor: GREY_COLOR,
highlightColor: WHITE_COLOR,
child: Row(
children: <Widget>[
Expanded(
child: Container(
decoration: const BoxDecoration(
color: GREY_COLOR,
borderRadius: CIRCULAR_BORDER_RADIUS,
),
),
),
],
),
),
leading: Shimmer.fromColors(
baseColor: GREY_COLOR,
highlightColor: WHITE_COLOR,
child: const SmoothImage(
width: VERY_LARGE_SPACE * 5,
height: MEDIUM_SPACE * 5,
color: GREY_COLOR,
),
),
);

final Widget? title;
final Widget? subtitle;
final Widget? leading;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,18 @@ class SmoothMainProductImage extends StatelessWidget {
Widget build(BuildContext context) {
context.watch<LocalDatabase>();
final OpenFoodFactsLanguage language = ProductQuery.getLanguage();
final ImageProvider? imageProvider = TransientFile.fromProduct(
ImageProvider? imageProvider = TransientFile.fromProduct(
product,
ImageField.FRONT,
language,
).getImageProvider();
// if we couldn't find an image for that specific language, use the default.
if (imageProvider == null) {
final String? url = product.imageFrontUrl;
if (url != null) {
imageProvider = NetworkImage(url);
}
}

return SmoothImage(
width: width,
Expand Down
23 changes: 0 additions & 23 deletions packages/smooth_app/lib/helpers/image_field_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,6 @@ extension ImageFieldSmoothieExtension on ImageField {
ImageField.PACKAGING,
];

static const List<ImageField> orderedAll = <ImageField>[
ImageField.FRONT,
ImageField.INGREDIENTS,
ImageField.NUTRITION,
ImageField.PACKAGING,
ImageField.OTHER,
];

String? getUrl(final Product product) {
switch (this) {
case ImageField.FRONT:
return product.imageFrontUrl;
case ImageField.INGREDIENTS:
return product.imageIngredientsUrl;
case ImageField.NUTRITION:
return product.imageNutritionUrl;
case ImageField.PACKAGING:
return product.imagePackagingUrl;
case ImageField.OTHER:
return null;
}
}

void setUrl(final Product product, final String url) {
switch (this) {
case ImageField.FRONT:
Expand Down
75 changes: 23 additions & 52 deletions packages/smooth_app/lib/helpers/product_cards_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -213,59 +213,48 @@ Widget addPanelButton(

List<ProductImageData> getProductMainImagesData(
final Product product,
final OpenFoodFactsLanguage language, {
required final bool includeOther,
}) {
final List<ImageField> imageFields = List<ImageField>.of(
ImageFieldSmoothieExtension.orderedMain,
growable: true,
);
if (includeOther) {
imageFields.add(ImageField.OTHER);
}
final OpenFoodFactsLanguage language,
) {
final List<ProductImageData> result = <ProductImageData>[];
for (final ImageField element in imageFields) {
result.add(getProductImageData(product, element, language));
for (final ImageField imageField in ImageFieldSmoothieExtension.orderedMain) {
result.add(getProductImageData(product, imageField, language));
}
return result;
}

/// Returns data about the "best" image: for the language, or the default.
///
/// With [forceLanguage] you say you don't want the default as a fallback.
/// Returns data about the [imageField], for the [language].
ProductImageData getProductImageData(
final Product product,
final ImageField imageField,
final OpenFoodFactsLanguage language, {
final bool forceLanguage = false,
}) {
final OpenFoodFactsLanguage language,
) {
final ProductImage? productImage = getLocalizedProductImage(
product,
imageField,
language,
);
final String? imageUrl;
final OpenFoodFactsLanguage? imageLanguage;
if (productImage != null) {
// we found a localized version for this image
imageLanguage = language;
imageUrl = ImageHelper.getLocalizedProductImageUrl(
product.barcode!,
productImage,
imageSize: ImageSize.DISPLAY,
return ProductImageData(
imageField: imageField,
imageUrl: ImageHelper.getLocalizedProductImageUrl(
product.barcode!,
productImage,
imageSize: ImageSize.DISPLAY,
),
language: language,
);
} else {
imageLanguage = null;
imageUrl = forceLanguage ? null : imageField.getUrl(product);
}

return ProductImageData(
imageField: imageField,
imageUrl: imageUrl,
language: imageLanguage,
);
return getEmptyProductImageData(imageField);
}

ProductImageData getEmptyProductImageData(final ImageField imageField) =>
ProductImageData(
imageField: imageField,
imageUrl: null,
language: null,
);

ProductImage? getLocalizedProductImage(
final Product product,
final ImageField imageField,
Expand All @@ -285,24 +274,6 @@ ProductImage? getLocalizedProductImage(
return null;
}

List<MapEntry<ProductImageData, ImageProvider?>> getSelectedImages(
final Product product,
final OpenFoodFactsLanguage language,
) {
final Map<ProductImageData, ImageProvider?> result =
<ProductImageData, ImageProvider?>{};
final List<ProductImageData> allProductImagesData =
getProductMainImagesData(product, language, includeOther: false);
for (final ProductImageData imageData in allProductImagesData) {
result[imageData] = TransientFile.fromProductImageData(
imageData,
product.barcode!,
language,
).getImageProvider();
}
return result.entries.toList();
}

/// Returns the languages for which [imageField] has images for that [product].
Iterable<OpenFoodFactsLanguage> getProductImageLanguages(
final Product product,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ class AddNewProductHelper {
bool isOneMainImagePopulated(final Product product) {
final List<ProductImageData> productImagesData = getProductMainImagesData(
product,
// TODO(monsieurtanuki): check somehow with all languages
ProductQuery.getLanguage(),
includeOther: false,
);
for (final ProductImageData productImageData in productImagesData) {
if (isMainImagePopulated(productImageData, product.barcode!)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,6 @@ class _AddNewProductPageState extends State<AddNewProductPage>
final List<ProductImageData> productImagesData = getProductMainImagesData(
upToDateProduct,
ProductQuery.getLanguage(),
includeOther: false,
);
for (final ProductImageData data in productImagesData) {
// Everything else can only be uploaded once
Expand Down
Loading