Skip to content

Commit

Permalink
fix: Fix performances on the photos gallery (#5447)
Browse files Browse the repository at this point in the history
* Improve performances for the photos gallery

* Allow to pass an `ImageSize` to `ProductImageWidget`

* Update packages/smooth_app/lib/pages/image/product_image_gallery_other_view.dart

Co-authored-by: monsieurtanuki <[email protected]>

---------

Co-authored-by: monsieurtanuki <[email protected]>
  • Loading branch information
g123k and monsieurtanuki authored Jun 28, 2024
1 parent 099391d commit 1c4b959
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@ class SmoothImage extends StatelessWidget {
this.fit = BoxFit.cover,
this.rounded = true,
this.heroTag,
});
this.cacheWidth,
this.cacheHeight,
}) : assert(
cacheWidth == null || imageProvider is NetworkImage,
'cacheWidth requires a NetworkImage',
),
assert(
cacheHeight == null || imageProvider is NetworkImage,
'cacheHeight requires a NetworkImage',
);

final ImageProvider? imageProvider;
final double? height;
Expand All @@ -28,17 +37,28 @@ class SmoothImage extends StatelessWidget {
final BoxFit fit;
final String? heroTag;
final bool rounded;
final int? cacheWidth;
final int? cacheHeight;

@override
Widget build(BuildContext context) {
Widget child = imageProvider == null
? const PictureNotFound()
: Image(
image: imageProvider!,
fit: fit,
loadingBuilder: _loadingBuilder,
errorBuilder: _errorBuilder,
);
Widget child = switch (imageProvider) {
NetworkImage(url: final String url) => Image.network(
url,
fit: fit,
loadingBuilder: _loadingBuilder,
errorBuilder: _errorBuilder,
cacheWidth: cacheWidth,
cacheHeight: cacheHeight,
),
ImageProvider<Object>() => Image(
image: imageProvider!,
fit: fit,
loadingBuilder: _loadingBuilder,
errorBuilder: _errorBuilder,
),
_ => const PictureNotFound(),
};

if (heroTag != null) {
child = Hero(tag: heroTag!, child: child);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
Expand Down Expand Up @@ -108,6 +109,8 @@ class _RawGridGallery extends StatelessWidget {
@override
Widget build(BuildContext context) {
final double squareSize = _getSquareSize(context);
final ImageSize? imageSize = _computeImageSize(squareSize);

return SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: _columns,
Expand Down Expand Up @@ -137,6 +140,7 @@ class _RawGridGallery extends StatelessWidget {
productImage: productImage,
barcode: product.barcode!,
squareSize: squareSize,
imageSize: imageSize,
),
),
);
Expand All @@ -146,4 +150,12 @@ class _RawGridGallery extends StatelessWidget {
),
);
}

ImageSize? _computeImageSize(double squareSize) => <ImageSize>[
ImageSize.THUMB,
ImageSize.SMALL,
ImageSize.DISPLAY
].firstWhereOrNull(
(ImageSize element) => squareSize <= int.parse(element.number),
);
}
54 changes: 14 additions & 40 deletions packages/smooth_app/lib/pages/image/product_image_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,20 @@ import 'package:smooth_app/resources/app_icons.dart';
import 'package:smooth_app/themes/smooth_theme_colors.dart';

/// Displays a product image thumbnail with the upload date on top.
class ProductImageWidget extends StatefulWidget {
class ProductImageWidget extends StatelessWidget {
const ProductImageWidget({
required this.productImage,
required this.barcode,
required this.squareSize,
this.imageSize,
});

final ProductImage productImage;
final String barcode;
final double squareSize;

@override
State<ProductImageWidget> createState() => _ProductImageWidgetState();
}

class _ProductImageWidgetState extends State<ProductImageWidget> {
@override
void initState() {
super.initState();
_loadImagePalette();
}

Future<void> _loadImagePalette() async {
final ColorScheme palette = await ColorScheme.fromImageProvider(
provider: NetworkImage(widget.productImage.getUrl(
widget.barcode,
uriHelper: ProductQuery.uriProductHelper,
)));

setState(() {
backgroundColor = palette.primaryContainer;
darkBackground = backgroundColor!.computeLuminance() < 0.5;
});
}

Color? backgroundColor;
bool? darkBackground;
/// Allows to fetch the optimized version of the image
final ImageSize? imageSize;

@override
Widget build(BuildContext context) {
Expand All @@ -57,20 +34,21 @@ class _ProductImageWidgetState extends State<ProductImageWidget> {
final DateFormat dateFormat =
DateFormat.yMd(ProductQuery.getLanguage().offTag);

darkBackground = darkBackground ?? true;

final Widget image = SmoothImage(
width: widget.squareSize,
height: widget.squareSize,
cacheHeight:
(squareSize * MediaQuery.devicePixelRatioOf(context)).toInt(),
width: squareSize,
height: squareSize,
imageProvider: NetworkImage(
widget.productImage.getUrl(
widget.barcode,
productImage.getUrl(
barcode,
uriHelper: ProductQuery.uriProductHelper,
imageSize: imageSize,
),
),
rounded: false,
);
final DateTime? uploaded = widget.productImage.uploaded;
final DateTime? uploaded = productImage.uploaded;
if (uploaded == null) {
return image;
}
Expand All @@ -85,7 +63,7 @@ class _ProductImageWidgetState extends State<ProductImageWidget> {
button: true,
child: SmoothCard(
padding: EdgeInsets.zero,
color: backgroundColor ?? colors.primaryBlack,
color: colors.primaryBlack,
borderRadius: ANGULAR_BORDER_RADIUS,
margin: EdgeInsets.zero,
child: ClipRRect(
Expand All @@ -108,11 +86,7 @@ class _ProductImageWidgetState extends State<ProductImageWidget> {
child: AutoSizeText(
date,
maxLines: 1,
style: TextStyle(
color: darkBackground!
? Colors.white
: colors.primaryDark,
),
style: const TextStyle(color: Colors.white),
),
),
if (expired)
Expand Down

0 comments on commit 1c4b959

Please sign in to comment.