reviewed thumbnail requests & cached thumbnail usage
This commit is contained in:
parent
b332739eac
commit
a81e934fbe
8 changed files with 64 additions and 49 deletions
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
},
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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';
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue