multipage: faster default page

This commit is contained in:
Thibault Deckers 2021-01-22 14:52:19 +09:00
parent a6b99e7c2a
commit b0cccd7d2d
5 changed files with 51 additions and 51 deletions

View file

@ -98,21 +98,26 @@ class AvesEntry {
AvesEntry getPageEntry(SinglePageInfo pageInfo) { AvesEntry getPageEntry(SinglePageInfo pageInfo) {
if (pageInfo == null) return this; if (pageInfo == null) return this;
return AvesPageEntry(
pageInfo: pageInfo, // do not provide the page ID for the default page,
// so that we can treat this page like the main entry
// and retrieve cached images for it
final pageId = pageInfo.isDefault ? null : pageInfo.pageId;
return AvesEntry(
uri: uri, uri: uri,
path: path, path: path,
contentId: contentId, contentId: contentId,
pageId: pageInfo.pageId, pageId: pageId,
sourceMimeType: sourceMimeType, sourceMimeType: pageInfo.mimeType ?? sourceMimeType,
width: width, width: pageInfo.width ?? width,
height: height, height: pageInfo.height ?? height,
sourceRotationDegrees: sourceRotationDegrees, sourceRotationDegrees: sourceRotationDegrees,
sizeBytes: sizeBytes, sizeBytes: sizeBytes,
sourceTitle: sourceTitle, sourceTitle: sourceTitle,
dateModifiedSecs: dateModifiedSecs, dateModifiedSecs: dateModifiedSecs,
sourceDateTakenMillis: sourceDateTakenMillis, sourceDateTakenMillis: sourceDateTakenMillis,
durationMillis: durationMillis, durationMillis: pageInfo.durationMillis ?? durationMillis,
) )
..catalogMetadata = _catalogMetadata?.copyWith( ..catalogMetadata = _catalogMetadata?.copyWith(
mimeType: pageInfo.mimeType, mimeType: pageInfo.mimeType,

View file

@ -9,7 +9,9 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
extension ExtraAvesEntry on AvesEntry { extension ExtraAvesEntry on AvesEntry {
ThumbnailProvider getThumbnail({double extent = 0}) => ThumbnailProvider(_getThumbnailProviderKey(extent)); ThumbnailProvider getThumbnail({double extent = 0}) {
return ThumbnailProvider(_getThumbnailProviderKey(extent));
}
ThumbnailProviderKey _getThumbnailProviderKey(double extent) { ThumbnailProviderKey _getThumbnailProviderKey(double extent) {
// we standardize the thumbnail loading dimension by taking the nearest larger power of 2 // we standardize the thumbnail loading dimension by taking the nearest larger power of 2
@ -28,9 +30,11 @@ extension ExtraAvesEntry on AvesEntry {
); );
} }
RegionProvider getRegion({@required int sampleSize, Rectangle<int> region}) => RegionProvider(getRegionProviderKey(sampleSize, region)); RegionProvider getRegion({@required int sampleSize, Rectangle<int> region}) {
return RegionProvider(_getRegionProviderKey(sampleSize, region));
}
RegionProviderKey getRegionProviderKey(int sampleSize, Rectangle<int> region) { RegionProviderKey _getRegionProviderKey(int sampleSize, Rectangle<int> region) {
return RegionProviderKey( return RegionProviderKey(
uri: uri, uri: uri,
mimeType: mimeType, mimeType: mimeType,

View file

@ -1,4 +1,3 @@
import 'package:aves/model/entry.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
class MultiPageInfo { class MultiPageInfo {
@ -8,12 +7,23 @@ class MultiPageInfo {
MultiPageInfo({ MultiPageInfo({
this.pages, this.pages,
}); }) {
if (pages.isNotEmpty) {
pages.sort();
// make sure there is a page marked as default
if (defaultPage == null) {
final firstPage = pages.removeAt(0);
pages.insert(0, firstPage.copyWith(isDefault: true));
}
}
}
factory MultiPageInfo.fromPageMaps(List<Map> pageMaps) { factory MultiPageInfo.fromPageMaps(List<Map> pageMaps) {
return MultiPageInfo(pages: pageMaps.map((page) => SinglePageInfo.fromMap(page)).toList()); return MultiPageInfo(pages: pageMaps.map((page) => SinglePageInfo.fromMap(page)).toList());
} }
SinglePageInfo get defaultPage => pages.firstWhere((page) => page.isDefault, orElse: () => null);
SinglePageInfo getByIndex(int index) => pages.firstWhere((page) => page.index == index, orElse: () => null); SinglePageInfo getByIndex(int index) => pages.firstWhere((page) => page.index == index, orElse: () => null);
SinglePageInfo getById(int pageId) => pages.firstWhere((page) => page.pageId == pageId, orElse: () => null); SinglePageInfo getById(int pageId) => pages.firstWhere((page) => page.pageId == pageId, orElse: () => null);
@ -22,13 +32,13 @@ class MultiPageInfo {
String toString() => '$runtimeType#${shortHash(this)}{pages=$pages}'; String toString() => '$runtimeType#${shortHash(this)}{pages=$pages}';
} }
class SinglePageInfo { class SinglePageInfo implements Comparable<SinglePageInfo> {
final int index, pageId; final int index, pageId;
final String mimeType; final String mimeType;
final bool isDefault; final bool isDefault;
final int width, height, durationMillis; final int width, height, durationMillis;
SinglePageInfo({ const SinglePageInfo({
this.index, this.index,
this.pageId, this.pageId,
this.mimeType, this.mimeType,
@ -38,6 +48,20 @@ class SinglePageInfo {
this.durationMillis, this.durationMillis,
}); });
SinglePageInfo copyWith({
bool isDefault,
}) {
return SinglePageInfo(
index: index,
pageId: pageId,
mimeType: mimeType,
isDefault: isDefault ?? this.isDefault,
width: width,
height: height,
durationMillis: durationMillis,
);
}
factory SinglePageInfo.fromMap(Map map) { factory SinglePageInfo.fromMap(Map map) {
final index = map['page'] as int; final index = map['page'] as int;
return SinglePageInfo( return SinglePageInfo(
@ -53,39 +77,7 @@ class SinglePageInfo {
@override @override
String toString() => '$runtimeType#${shortHash(this)}{index=$index, pageId=$pageId, mimeType=$mimeType, isDefault=$isDefault, width=$width, height=$height, durationMillis=$durationMillis}'; String toString() => '$runtimeType#${shortHash(this)}{index=$index, pageId=$pageId, mimeType=$mimeType, isDefault=$isDefault, width=$width, height=$height, durationMillis=$durationMillis}';
}
class AvesPageEntry extends AvesEntry { @override
final SinglePageInfo pageInfo; int compareTo(SinglePageInfo other) => index.compareTo(other.index);
AvesPageEntry({
@required this.pageInfo,
String uri,
String path,
int contentId,
int pageId,
String sourceMimeType,
int width,
int height,
int sourceRotationDegrees,
int sizeBytes,
String sourceTitle,
int dateModifiedSecs,
int sourceDateTakenMillis,
int durationMillis,
}) : super(
uri: uri,
path: path,
contentId: contentId,
pageId: pageId,
sourceMimeType: pageInfo.mimeType ?? sourceMimeType,
width: pageInfo.width ?? width,
height: pageInfo.height ?? height,
sourceRotationDegrees: sourceRotationDegrees,
sizeBytes: sizeBytes,
sourceTitle: sourceTitle,
dateModifiedSecs: dateModifiedSecs,
sourceDateTakenMillis: sourceDateTakenMillis,
durationMillis: pageInfo.durationMillis ?? durationMillis,
);
} }

View file

@ -12,8 +12,7 @@ class MultiPageController extends ChangeNotifier {
MultiPageController(AvesEntry entry) { MultiPageController(AvesEntry entry) {
info = MetadataService.getMultiPageInfo(entry).then((value) { info = MetadataService.getMultiPageInfo(entry).then((value) {
final defaultPage = value.pages.firstWhere((page) => page.isDefault, orElse: () => null); pageNotifier.value = value.defaultPage.index;
pageNotifier.value = defaultPage?.index ?? 0;
return value; return value;
}); });
} }

View file

@ -363,7 +363,7 @@ class _PositionTitleRow extends StatelessWidget {
// but fail to get information about these pages // but fail to get information about these pages
final pageCount = multiPageInfo.pageCount; final pageCount = multiPageInfo.pageCount;
if (pageCount > 0) { if (pageCount > 0) {
final page = multiPageInfo.getById(entry.pageId); final page = multiPageInfo.getById(entry.pageId) ?? multiPageInfo.defaultPage;
pagePosition = '${(page?.index ?? 0) + 1}/$pageCount'; pagePosition = '${(page?.index ?? 0) + 1}/$pageCount';
} }
} }