diff --git a/packages/neon/neon/lib/src/widgets/cached_image.dart b/packages/neon/neon/lib/src/widgets/cached_image.dart index 0d6f6496..4b02d603 100644 --- a/packages/neon/neon/lib/src/widgets/cached_image.dart +++ b/packages/neon/neon/lib/src/widgets/cached_image.dart @@ -11,6 +11,7 @@ import 'package:neon/src/widgets/linear_progress_indicator.dart'; typedef CacheReviver = FutureOr Function(CacheManager cacheManager); typedef ImageDownloader = FutureOr Function(); typedef CacheWriter = Future Function(CacheManager cacheManager, Uint8List image); +typedef ErrorWidgetBuilder = Widget? Function(BuildContext, dynamic); class NeonCachedImage extends StatefulWidget { const NeonCachedImage({ @@ -21,6 +22,7 @@ class NeonCachedImage extends StatefulWidget { this.fit, this.svgColor, this.iconColor, + this.errorBuilder, }); NeonCachedImage.url({ @@ -31,6 +33,7 @@ class NeonCachedImage extends StatefulWidget { this.fit, this.svgColor, this.iconColor, + this.errorBuilder, }) : image = _getImageFromUrl(url), super(key: key ?? Key(url)); @@ -44,6 +47,7 @@ class NeonCachedImage extends StatefulWidget { this.fit, this.svgColor, this.iconColor, + this.errorBuilder, }) : image = _customImageGetter( reviver, getImage, @@ -61,6 +65,8 @@ class NeonCachedImage extends StatefulWidget { final Color? svgColor; final Color? iconColor; + final ErrorWidgetBuilder? errorBuilder; + static Future _getImageFromUrl(final String url) async { final file = await _cacheManager.getSingleFile(url); return file.readAsBytes(); @@ -116,6 +122,10 @@ class _NeonCachedImageState extends State { child: FutureBuilder( future: widget.image, builder: (final context, final fileSnapshot) { + if (fileSnapshot.hasError) { + return _buildError(fileSnapshot.error); + } + if (!fileSnapshot.hasData) { return SizedBox( width: widget.size?.width, @@ -125,18 +135,6 @@ class _NeonCachedImageState extends State { ); } - if (fileSnapshot.hasError) { - return NeonException( - fileSnapshot.error, - onRetry: () { - setState(() {}); - }, - onlyIcon: true, - iconSize: widget.size?.shortestSide, - color: widget.iconColor ?? Theme.of(context).colorScheme.error, - ); - } - final content = fileSnapshot.requireData; try { @@ -160,8 +158,20 @@ class _NeonCachedImageState extends State { width: widget.size?.width, fit: widget.fit, gaplessPlayback: true, + errorBuilder: (final context, final error, final stacktrace) => _buildError(error), ); }, ), ); + + Widget _buildError(final dynamic error) => + widget.errorBuilder?.call(context, error) ?? + NeonException( + error, + onRetry: () { + setState(() {}); + }, + onlyIcon: true, + iconSize: widget.size?.shortestSide, + ); }