Browse Source

neon: unify NeonCachedImage

pull/432/head
Nikolas Rimikis 1 year ago
parent
commit
11f48669fb
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 2
      packages/neon/neon/lib/neon.dart
  2. 32
      packages/neon/neon/lib/src/widgets/cached_api_image.dart
  3. 58
      packages/neon/neon/lib/src/widgets/cached_image.dart
  4. 15
      packages/neon/neon/lib/src/widgets/cached_url_image.dart
  5. 2
      packages/neon/neon/lib/src/widgets/drawer.dart
  6. 2
      packages/neon/neon/lib/src/widgets/user_avatar.dart
  7. 2
      packages/neon/neon_files/lib/widgets/file_preview.dart
  8. 2
      packages/neon/neon_news/lib/widgets/articles_view.dart
  9. 2
      packages/neon/neon_news/lib/widgets/feed_icon.dart
  10. 2
      packages/neon/neon_notifications/lib/pages/main.dart

2
packages/neon/neon/lib/neon.dart

@ -91,9 +91,7 @@ part 'src/utils/validators.dart';
part 'src/widgets/account_settings_tile.dart'; part 'src/widgets/account_settings_tile.dart';
part 'src/widgets/account_tile.dart'; part 'src/widgets/account_tile.dart';
part 'src/widgets/app_implementation_icon.dart'; part 'src/widgets/app_implementation_icon.dart';
part 'src/widgets/cached_api_image.dart';
part 'src/widgets/cached_image.dart'; part 'src/widgets/cached_image.dart';
part 'src/widgets/cached_url_image.dart';
part 'src/widgets/dialog.dart'; part 'src/widgets/dialog.dart';
part 'src/widgets/exception.dart'; part 'src/widgets/exception.dart';
part 'src/widgets/image_wrapper.dart'; part 'src/widgets/image_wrapper.dart';

32
packages/neon/neon/lib/src/widgets/cached_api_image.dart

@ -1,32 +0,0 @@
part of '../../neon.dart';
typedef APIImageDownloader = Future<Uint8List> Function();
class NeonCachedApiImage extends NeonCachedImage {
NeonCachedApiImage({
required final Account account,
required final String cacheKey,
required final APIImageDownloader download,
final String? etag,
super.size,
super.fit,
super.svgColor,
super.iconColor,
super.key,
}) : super(
getImageFile: () async {
final realKey = '${account.id}-$cacheKey';
final cacheFile = await _cacheManager.getFileFromCache(realKey);
if (cacheFile != null && cacheFile.validTill.isAfter(DateTime.now())) {
return cacheFile.file;
}
return _cacheManager.putFile(
realKey,
await download(),
maxAge: const Duration(days: 7),
eTag: etag,
);
},
);
}

58
packages/neon/neon/lib/src/widgets/cached_image.dart

@ -2,8 +2,10 @@ part of '../../neon.dart';
final _cacheManager = DefaultCacheManager(); final _cacheManager = DefaultCacheManager();
abstract class NeonCachedImage extends StatefulWidget { typedef APIImageDownloader = Future<Uint8List> Function();
const NeonCachedImage({
class NeonCachedImage extends StatefulWidget {
const NeonCachedImage._({
required this.getImageFile, required this.getImageFile,
this.isSvgHint = false, this.isSvgHint = false,
this.size, this.size,
@ -13,6 +15,58 @@ abstract class NeonCachedImage extends StatefulWidget {
super.key, super.key,
}); });
factory NeonCachedImage.url({
required final String url,
final Size? size,
final BoxFit? fit,
final Color? svgColor,
final Color? iconColor,
final Key? key,
}) =>
NeonCachedImage._(
getImageFile: () async => _cacheManager.getSingleFile(url),
isSvgHint: Uri.parse(url).path.endsWith('.svg'),
size: size,
fit: fit,
svgColor: svgColor,
iconColor: iconColor,
key: key,
);
factory NeonCachedImage.api({
required final Account account,
required final String cacheKey,
required final APIImageDownloader download,
final String? etag,
final Size? size,
final BoxFit? fit,
final Color? svgColor,
final Color? iconColor,
final Key? key,
}) =>
NeonCachedImage._(
getImageFile: () async {
final realKey = '${account.id}-$cacheKey';
final cacheFile = await _cacheManager.getFileFromCache(realKey);
if (cacheFile != null && cacheFile.validTill.isAfter(DateTime.now())) {
return cacheFile.file;
}
// TODO: don't await the image being written to disk
return _cacheManager.putFile(
realKey,
await download(),
maxAge: const Duration(days: 7),
eTag: etag,
);
},
size: size,
fit: fit,
svgColor: svgColor,
iconColor: iconColor,
key: key,
);
final Future<File> Function() getImageFile; final Future<File> Function() getImageFile;
final bool isSvgHint; final bool isSvgHint;

15
packages/neon/neon/lib/src/widgets/cached_url_image.dart

@ -1,15 +0,0 @@
part of '../../neon.dart';
class NeonCachedUrlImage extends NeonCachedImage {
NeonCachedUrlImage({
required final String url,
super.size,
super.fit,
super.svgColor,
super.iconColor,
super.key,
}) : super(
getImageFile: () => _cacheManager.getSingleFile(url),
isSvgHint: Uri.parse(url).path.endsWith('.svg'),
);
}

2
packages/neon/neon/lib/src/widgets/drawer.dart

@ -187,7 +187,7 @@ class NeonDrawerHeader extends StatelessWidget {
], ],
if (capabilities.requireData.capabilities.theming?.logo != null) ...[ if (capabilities.requireData.capabilities.theming?.logo != null) ...[
Flexible( Flexible(
child: NeonCachedUrlImage( child: NeonCachedImage.url(
url: capabilities.requireData.capabilities.theming!.logo!, url: capabilities.requireData.capabilities.theming!.logo!,
), ),
), ),

2
packages/neon/neon/lib/src/widgets/user_avatar.dart

@ -53,7 +53,7 @@ class _UserAvatarState extends State<NeonUserAvatar> {
radius: size / 2, radius: size / 2,
backgroundColor: widget.backgroundColor, backgroundColor: widget.backgroundColor,
child: ClipOval( child: ClipOval(
child: NeonCachedApiImage( child: NeonCachedImage.api(
account: widget.account, account: widget.account,
cacheKey: 'avatar-${widget.username}-${isDark ? 'dark' : 'light'}$pixelSize', cacheKey: 'avatar-${widget.username}-${isDark ? 'dark' : 'light'}$pixelSize',
download: () async { download: () async {

2
packages/neon/neon_files/lib/widgets/file_preview.dart

@ -34,7 +34,7 @@ class FilePreview extends StatelessWidget {
builder: (final context, final showPreviewsSnapshot) { builder: (final context, final showPreviewsSnapshot) {
if ((showPreviewsSnapshot.data ?? false) && (details.hasPreview ?? false)) { if ((showPreviewsSnapshot.data ?? false) && (details.hasPreview ?? false)) {
final account = Provider.of<AccountsBloc>(context, listen: false).activeAccount.value!; final account = Provider.of<AccountsBloc>(context, listen: false).activeAccount.value!;
final child = NeonCachedApiImage( final child = NeonCachedImage.api(
account: account, account: account,
cacheKey: 'preview-${details.path.join('/')}-$width-$height', cacheKey: 'preview-${details.path.join('/')}-$width-$height',
etag: details.etag, etag: details.etag,

2
packages/neon/neon_news/lib/widgets/articles_view.dart

@ -116,7 +116,7 @@ class _NewsArticlesViewState extends State<NewsArticlesView> {
), ),
), ),
if (article.mediaThumbnail != null) ...[ if (article.mediaThumbnail != null) ...[
NeonCachedUrlImage( NeonCachedImage.url(
url: article.mediaThumbnail!, url: article.mediaThumbnail!,
size: const Size(100, 50), size: const Size(100, 50),
fit: BoxFit.cover, fit: BoxFit.cover,

2
packages/neon/neon_news/lib/widgets/feed_icon.dart

@ -21,7 +21,7 @@ class NewsFeedIcon extends StatelessWidget {
size: Size.square(size), size: Size.square(size),
borderRadius: borderRadius, borderRadius: borderRadius,
child: faviconLink != null && faviconLink.isNotEmpty child: faviconLink != null && faviconLink.isNotEmpty
? NeonCachedUrlImage( ? NeonCachedImage.url(
url: faviconLink, url: faviconLink,
size: Size.square(size), size: Size.square(size),
iconColor: Theme.of(context).colorScheme.primary, iconColor: Theme.of(context).colorScheme.primary,

2
packages/neon/neon_notifications/lib/pages/main.dart

@ -78,7 +78,7 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
) )
: SizedBox.fromSize( : SizedBox.fromSize(
size: const Size.square(40), size: const Size.square(40),
child: NeonCachedUrlImage( child: NeonCachedImage.url(
url: notification.icon!, url: notification.icon!,
size: const Size.square(40), size: const Size.square(40),
svgColor: Theme.of(context).colorScheme.primary, svgColor: Theme.of(context).colorScheme.primary,

Loading…
Cancel
Save