reviewed thumbnail requests & cached thumbnail usage

This commit is contained in:
Thibault Deckers 2021-06-07 16:11:54 +09:00
parent b332739eac
commit a81e934fbe
8 changed files with 64 additions and 49 deletions

View file

@ -4,7 +4,16 @@ import 'package:aves/image_providers/thumbnail_provider.dart';
import 'package:aves/image_providers/uri_image_provider.dart';
class EntryCache {
static final requestExtents = <double>{};
// ordered descending
static final thumbnailRequestExtents = <double>[];
static void markThumbnailExtent(double extent) {
if (!thumbnailRequestExtents.contains(extent)) {
thumbnailRequestExtents
..add(extent)
..sort((a, b) => b.compareTo(a));
}
}
static Future<void> evict(
String uri,
@ -36,7 +45,7 @@ class EntryCache {
)).evict();
await Future.forEach<double>(
requestExtents,
thumbnailRequestExtents,
(extent) => ThumbnailProvider(ThumbnailProviderKey(
uri: uri,
mimeType: mimeType,

View file

@ -6,6 +6,7 @@ import 'package:aves/image_providers/thumbnail_provider.dart';
import 'package:aves/image_providers/uri_image_provider.dart';
import 'package:aves/model/entry.dart';
import 'package:aves/model/entry_cache.dart';
import 'package:collection/collection.dart';
import 'package:flutter/widgets.dart';
extension ExtraAvesEntry on AvesEntry {
@ -14,7 +15,7 @@ extension ExtraAvesEntry on AvesEntry {
}
ThumbnailProviderKey _getThumbnailProviderKey(double extent) {
EntryCache.requestExtents.add(extent);
EntryCache.markThumbnailExtent(extent);
return ThumbnailProviderKey(
uri: uri,
mimeType: mimeType,
@ -54,10 +55,10 @@ extension ExtraAvesEntry on AvesEntry {
bool _isReady(Object providerKey) => imageCache!.statusForKey(providerKey).keepAlive;
ImageProvider getBestThumbnail(double extent) {
final sizedThumbnailKey = _getThumbnailProviderKey(extent);
if (_isReady(sizedThumbnailKey)) return ThumbnailProvider(sizedThumbnailKey);
List<ThumbnailProvider> get cachedThumbnails => EntryCache.thumbnailRequestExtents.map(_getThumbnailProviderKey).where(_isReady).map((key) => ThumbnailProvider(key)).toList();
return getThumbnail();
ThumbnailProvider get bestCachedThumbnail {
final sizedThumbnailKey = EntryCache.thumbnailRequestExtents.map(_getThumbnailProviderKey).firstWhereOrNull(_isReady);
return sizedThumbnailKey != null ? ThumbnailProvider(sizedThumbnailKey) : getThumbnail();
}
}

View file

@ -204,11 +204,15 @@ class _CollectionScaler extends StatelessWidget {
),
scaledBuilder: (entry, extent) => ThumbnailTheme(
extent: extent,
child: DecoratedThumbnail(
entry: entry,
tileExtent: extent,
selectable: false,
highlightable: false,
child: Container(
width: extent,
height: extent,
child: DecoratedThumbnail(
entry: entry,
tileExtent: context.read<TileExtentController>().effectiveExtentMax,
selectable: false,
highlightable: false,
),
),
),
getScaledItemTileRect: (context, entry) {

View file

@ -13,6 +13,7 @@ import 'package:flutter/material.dart';
class RasterImageThumbnail extends StatefulWidget {
final AvesEntry entry;
final double extent;
final BoxFit fit;
final ValueNotifier<bool>? cancellableNotifier;
final Object? heroTag;
@ -20,6 +21,7 @@ class RasterImageThumbnail extends StatefulWidget {
Key? key,
required this.entry,
required this.extent,
this.fit = BoxFit.cover,
this.cancellableNotifier,
this.heroTag,
}) : super(key: key);
@ -182,7 +184,7 @@ class _RasterImageThumbnailState extends State<RasterImageThumbnail> {
width: extent,
height: extent,
scale: imageInfo.scale,
fit: BoxFit.cover,
fit: widget.fit,
);
return widget.heroTag != null
@ -190,7 +192,7 @@ class _RasterImageThumbnailState extends State<RasterImageThumbnail> {
tag: widget.heroTag!,
flightShuttleBuilder: (flight, animation, direction, fromHero, toHero) {
return TransitionImage(
image: entry.getBestThumbnail(extent),
image: entry.bestCachedThumbnail,
animation: animation,
);
},

View file

@ -117,37 +117,36 @@ class ViewerDebugPage extends StatelessWidget {
}
Widget _buildThumbnailsTabView() {
const extent = 128.0;
final children = <Widget>[];
if (entry.isSvg) {
const extent = 128.0;
children.addAll([
Text('SVG ($extent)'),
SvgPicture(
UriPicture(
uri: entry.uri,
mimeType: entry.mimeType,
),
width: extent,
height: extent,
)
]);
} else {
children.addAll(
entry.cachedThumbnails.expand((provider) => [
Text('Raster (${provider.key.extent})'),
Center(
child: Image(
image: provider,
),
),
SizedBox(height: 16),
]),
);
}
return ListView(
padding: EdgeInsets.all(16),
children: [
if (entry.isSvg) ...[
Text('SVG ($extent)'),
SvgPicture(
UriPicture(
uri: entry.uri,
mimeType: entry.mimeType,
),
width: extent,
height: extent,
)
],
if (!entry.isSvg) ...[
Text('Raster (fast)'),
Center(
child: Image(
image: entry.getThumbnail(),
),
),
SizedBox(height: 16),
Text('Raster ($extent)'),
Center(
child: Image(
image: entry.getThumbnail(extent: extent),
),
),
],
],
children: children,
);
}
}

View file

@ -16,7 +16,7 @@ import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:aves/widgets/dialogs/rename_entry_dialog.dart';
import 'package:aves/widgets/filter_grids/album_pick.dart';
import 'package:aves/widgets/viewer/debug_page.dart';
import 'package:aves/widgets/viewer/debug/debug_page.dart';
import 'package:aves/widgets/viewer/info/notifications.dart';
import 'package:aves/widgets/viewer/printer.dart';
import 'package:aves/widgets/viewer/source_viewer_page.dart';

View file

@ -2,12 +2,11 @@ import 'dart:async';
import 'package:aves/image_providers/uri_picture_provider.dart';
import 'package:aves/model/entry.dart';
import 'package:aves/model/entry_images.dart';
import 'package:aves/model/settings/entry_background.dart';
import 'package:aves/model/settings/enums.dart';
import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/durations.dart';
import 'package:aves/widgets/collection/collection_page.dart';
import 'package:aves/widgets/collection/thumbnail/raster.dart';
import 'package:aves/widgets/common/magnifier/controller/controller.dart';
import 'package:aves/widgets/common/magnifier/controller/state.dart';
import 'package:aves/widgets/common/magnifier/magnifier.dart';
@ -213,8 +212,9 @@ class _EntryPageViewState extends State<EntryPageView> {
duration: Durations.viewerVideoPlayerTransition,
child: GestureDetector(
onTap: _onTap,
child: Image(
image: entry.getBestThumbnail(settings.getTileExtent(CollectionPage.routeName)),
child: RasterImageThumbnail(
entry: entry,
extent: context.select<MediaQueryData, double>((mq) => mq.size.shortestSide),
fit: BoxFit.contain,
),
),

View file

@ -48,7 +48,7 @@ class _RasterImageViewState extends State<RasterImageView> {
ViewState get viewState => viewStateNotifier.value;
ImageProvider get thumbnailProvider => entry.getBestThumbnail(settings.getTileExtent(CollectionPage.routeName));
ImageProvider get thumbnailProvider => entry.bestCachedThumbnail;
ImageProvider get fullImageProvider {
if (entry.useTiles) {