💄 Improve the image don't animated the opacity if cached
This commit is contained in:
@@ -7,10 +7,9 @@ import 'package:island/models/chat.dart';
|
|||||||
import 'package:island/widgets/chat/message_item.dart';
|
import 'package:island/widgets/chat/message_item.dart';
|
||||||
|
|
||||||
// Provider to track animated messages to prevent replay
|
// Provider to track animated messages to prevent replay
|
||||||
final animatedMessagesProvider =
|
final animatedMessagesProvider = NotifierProvider.autoDispose(
|
||||||
NotifierProvider<AnimatedMessagesNotifier, Set<String>>(
|
AnimatedMessagesNotifier.new,
|
||||||
AnimatedMessagesNotifier.new,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
class AnimatedMessagesNotifier extends Notifier<Set<String>> {
|
class AnimatedMessagesNotifier extends Notifier<Set<String>> {
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_blurhash/flutter_blurhash.dart';
|
import 'package:flutter_blurhash/flutter_blurhash.dart';
|
||||||
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
|
||||||
@@ -29,8 +30,16 @@ class UniversalImage extends HookWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final loaded = useState(false);
|
final loaded = useState(false);
|
||||||
|
final isCached = useState<bool?>(null);
|
||||||
final isSvgImage = isSvg || uri.toLowerCase().endsWith('.svg');
|
final isSvgImage = isSvg || uri.toLowerCase().endsWith('.svg');
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
DefaultCacheManager().getFileFromCache(uri).then((fileInfo) {
|
||||||
|
isCached.value = fileInfo != null;
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}, [uri]);
|
||||||
|
|
||||||
if (isSvgImage) {
|
if (isSvgImage) {
|
||||||
return SvgPicture.network(
|
return SvgPicture.network(
|
||||||
uri,
|
uri,
|
||||||
@@ -59,44 +68,69 @@ class UniversalImage extends HookWidget {
|
|||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: [
|
||||||
if (blurHash != null) BlurHash(hash: blurHash!),
|
if (blurHash != null) BlurHash(hash: blurHash!),
|
||||||
CachedNetworkImage(
|
if (isCached.value == null)
|
||||||
imageUrl: uri,
|
Center(child: CircularProgressIndicator())
|
||||||
fit: fit,
|
else if (isCached.value!)
|
||||||
width: width,
|
CachedNetworkImage(
|
||||||
height: height,
|
imageUrl: uri,
|
||||||
memCacheHeight: cacheHeight,
|
fit: fit,
|
||||||
memCacheWidth: cacheWidth,
|
width: width,
|
||||||
progressIndicatorBuilder: (context, url, progress) {
|
height: height,
|
||||||
return Center(
|
memCacheHeight: cacheHeight,
|
||||||
child: AnimatedCircularProgressIndicator(
|
memCacheWidth: cacheWidth,
|
||||||
value: progress.progress,
|
imageBuilder: (context, imageProvider) => Image(
|
||||||
color: Colors.white.withOpacity(0.5),
|
image: imageProvider,
|
||||||
),
|
fit: fit,
|
||||||
);
|
width: width,
|
||||||
},
|
height: height,
|
||||||
imageBuilder: (context, imageProvider) {
|
),
|
||||||
Future(() {
|
errorWidget: (context, url, error) => useFallbackImage
|
||||||
if (context.mounted) return loaded.value = true;
|
? Image.asset(
|
||||||
});
|
'assets/images/media-offline.jpg',
|
||||||
return AnimatedOpacity(
|
fit: BoxFit.cover,
|
||||||
opacity: loaded.value ? 1.0 : 0.0,
|
key: Key('image-broke-$uri'),
|
||||||
duration: const Duration(milliseconds: 300),
|
)
|
||||||
child: Image(
|
: SizedBox.shrink(),
|
||||||
image: imageProvider,
|
)
|
||||||
fit: fit,
|
else
|
||||||
width: width,
|
CachedNetworkImage(
|
||||||
height: height,
|
imageUrl: uri,
|
||||||
),
|
fit: fit,
|
||||||
);
|
width: width,
|
||||||
},
|
height: height,
|
||||||
errorWidget: (context, url, error) => useFallbackImage
|
memCacheHeight: cacheHeight,
|
||||||
? Image.asset(
|
memCacheWidth: cacheWidth,
|
||||||
'assets/images/media-offline.jpg',
|
progressIndicatorBuilder: (context, url, progress) {
|
||||||
fit: BoxFit.cover,
|
return Center(
|
||||||
key: Key('image-broke-$uri'),
|
child: AnimatedCircularProgressIndicator(
|
||||||
)
|
value: progress.progress,
|
||||||
: SizedBox.shrink(),
|
color: Colors.white.withOpacity(0.5),
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
imageBuilder: (context, imageProvider) {
|
||||||
|
Future(() {
|
||||||
|
if (context.mounted) loaded.value = true;
|
||||||
|
});
|
||||||
|
return AnimatedOpacity(
|
||||||
|
opacity: loaded.value ? 1.0 : 0.0,
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
child: Image(
|
||||||
|
image: imageProvider,
|
||||||
|
fit: fit,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
errorWidget: (context, url, error) => useFallbackImage
|
||||||
|
? Image.asset(
|
||||||
|
'assets/images/media-offline.jpg',
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
key: Key('image-broke-$uri'),
|
||||||
|
)
|
||||||
|
: SizedBox.shrink(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -138,4 +172,4 @@ class AnimatedCircularProgressIndicator extends HookWidget {
|
|||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user