This commit is contained in:
Thibault Deckers 2021-01-21 12:20:31 +09:00
parent c9fa903309
commit c252ce7828
82 changed files with 325 additions and 325 deletions

View file

@ -27,7 +27,7 @@ class ImageFileHandler(private val activity: Activity) : MethodCallHandler {
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) { when (call.method) {
"getObsoleteEntries" -> GlobalScope.launch(Dispatchers.IO) { getObsoleteEntries(call, Coresult(result)) } "getObsoleteEntries" -> GlobalScope.launch(Dispatchers.IO) { getObsoleteEntries(call, Coresult(result)) }
"getImageEntry" -> GlobalScope.launch(Dispatchers.IO) { getImageEntry(call, Coresult(result)) } "getEntry" -> GlobalScope.launch(Dispatchers.IO) { getEntry(call, Coresult(result)) }
"getThumbnail" -> GlobalScope.launch(Dispatchers.IO) { getThumbnail(call, Coresult(result)) } "getThumbnail" -> GlobalScope.launch(Dispatchers.IO) { getThumbnail(call, Coresult(result)) }
"getRegion" -> GlobalScope.launch(Dispatchers.IO) { getRegion(call, Coresult(result)) } "getRegion" -> GlobalScope.launch(Dispatchers.IO) { getRegion(call, Coresult(result)) }
"clearSizedThumbnailDiskCache" -> { "clearSizedThumbnailDiskCache" -> {
@ -119,23 +119,23 @@ class ImageFileHandler(private val activity: Activity) : MethodCallHandler {
} }
} }
private suspend fun getImageEntry(call: MethodCall, result: MethodChannel.Result) { private suspend fun getEntry(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") // MIME type is optional val mimeType = call.argument<String>("mimeType") // MIME type is optional
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.let { Uri.parse(it) }
if (uri == null) { if (uri == null) {
result.error("getImageEntry-args", "failed because of missing arguments", null) result.error("getEntry-args", "failed because of missing arguments", null)
return return
} }
val provider = getProvider(uri) val provider = getProvider(uri)
if (provider == null) { if (provider == null) {
result.error("getImageEntry-provider", "failed to find provider for uri=$uri", null) result.error("getEntry-provider", "failed to find provider for uri=$uri", null)
return return
} }
provider.fetchSingle(activity, uri, mimeType, object : ImageOpCallback { provider.fetchSingle(activity, uri, mimeType, object : ImageOpCallback {
override fun onSuccess(fields: FieldMap) = result.success(fields) override fun onSuccess(fields: FieldMap) = result.success(fields)
override fun onFailure(throwable: Throwable) = result.error("getImageEntry-failure", "failed to get entry for uri=$uri", throwable.message) override fun onFailure(throwable: Throwable) = result.error("getEntry-failure", "failed to get entry for uri=$uri", throwable.message)
}) })
} }

View file

@ -5,7 +5,7 @@ import android.net.Uri
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.Log import android.util.Log
import deckers.thibault.aves.model.AvesImageEntry import deckers.thibault.aves.model.AvesEntry
import deckers.thibault.aves.model.provider.FieldMap import deckers.thibault.aves.model.provider.FieldMap
import deckers.thibault.aves.model.provider.ImageProvider.ImageOpCallback import deckers.thibault.aves.model.provider.ImageProvider.ImageOpCallback
import deckers.thibault.aves.model.provider.ImageProviderFactory.getProvider import deckers.thibault.aves.model.provider.ImageProviderFactory.getProvider
@ -102,7 +102,7 @@ class ImageOpStreamHandler(private val context: Context, private val arguments:
} }
destinationDir = StorageUtils.ensureTrailingSeparator(destinationDir) destinationDir = StorageUtils.ensureTrailingSeparator(destinationDir)
val entries = entryMapList.map(::AvesImageEntry) val entries = entryMapList.map(::AvesEntry)
provider.moveMultiple(context, copy, destinationDir, entries, object : ImageOpCallback { provider.moveMultiple(context, copy, destinationDir, entries, object : ImageOpCallback {
override fun onSuccess(fields: FieldMap) = success(fields) override fun onSuccess(fields: FieldMap) = success(fields)
override fun onFailure(throwable: Throwable) = error("move-failure", "failed to move entries", throwable) override fun onFailure(throwable: Throwable) = error("move-failure", "failed to move entries", throwable)

View file

@ -3,7 +3,7 @@ package deckers.thibault.aves.model
import android.net.Uri import android.net.Uri
import deckers.thibault.aves.model.provider.FieldMap import deckers.thibault.aves.model.provider.FieldMap
class AvesImageEntry(map: FieldMap) { class AvesEntry(map: FieldMap) {
val uri: Uri = Uri.parse(map["uri"] as String) // content or file URI val uri: Uri = Uri.parse(map["uri"] as String) // content or file URI
val path = map["path"] as String? // best effort to get local path val path = map["path"] as String? // best effort to get local path
val mimeType = map["mimeType"] as String val mimeType = map["mimeType"] as String

View file

@ -31,7 +31,7 @@ import deckers.thibault.aves.utils.StorageUtils
import org.beyka.tiffbitmapfactory.TiffBitmapFactory import org.beyka.tiffbitmapfactory.TiffBitmapFactory
import java.io.IOException import java.io.IOException
class SourceImageEntry { class SourceEntry {
val uri: Uri // content or file URI val uri: Uri // content or file URI
var path: String? = null // best effort to get local path var path: String? = null // best effort to get local path
private val sourceMimeType: String private val sourceMimeType: String
@ -119,7 +119,7 @@ class SourceImageEntry {
// metadata retrieval // metadata retrieval
// expects entry with: uri, mimeType // expects entry with: uri, mimeType
// finds: width, height, orientation/rotation, date, title, duration // finds: width, height, orientation/rotation, date, title, duration
fun fillPreCatalogMetadata(context: Context): SourceImageEntry { fun fillPreCatalogMetadata(context: Context): SourceEntry {
if (isSvg) return this if (isSvg) return this
if (isVideo) { if (isVideo) {
fillVideoByMediaMetadataRetriever(context) fillVideoByMediaMetadataRetriever(context)

View file

@ -3,7 +3,7 @@ package deckers.thibault.aves.model.provider
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.provider.MediaStore import android.provider.MediaStore
import deckers.thibault.aves.model.SourceImageEntry import deckers.thibault.aves.model.SourceEntry
internal class ContentImageProvider : ImageProvider() { internal class ContentImageProvider : ImageProvider() {
override suspend fun fetchSingle(context: Context, uri: Uri, mimeType: String?, callback: ImageOpCallback) { override suspend fun fetchSingle(context: Context, uri: Uri, mimeType: String?, callback: ImageOpCallback) {
@ -28,7 +28,7 @@ internal class ContentImageProvider : ImageProvider() {
return return
} }
val entry = SourceImageEntry(map).fillPreCatalogMetadata(context) val entry = SourceEntry(map).fillPreCatalogMetadata(context)
if (entry.isSized || entry.isSvg) { if (entry.isSized || entry.isSvg) {
callback.onSuccess(entry.toMap()) callback.onSuccess(entry.toMap())
} else { } else {

View file

@ -2,7 +2,7 @@ package deckers.thibault.aves.model.provider
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import deckers.thibault.aves.model.SourceImageEntry import deckers.thibault.aves.model.SourceEntry
import java.io.File import java.io.File
internal class FileImageProvider : ImageProvider() { internal class FileImageProvider : ImageProvider() {
@ -12,7 +12,7 @@ internal class FileImageProvider : ImageProvider() {
return return
} }
val entry = SourceImageEntry(uri, mimeType) val entry = SourceEntry(uri, mimeType)
val path = uri.path val path = uri.path
if (path != null) { if (path != null) {

View file

@ -8,7 +8,7 @@ import android.provider.MediaStore
import android.util.Log import android.util.Log
import androidx.exifinterface.media.ExifInterface import androidx.exifinterface.media.ExifInterface
import com.commonsware.cwac.document.DocumentFileCompat import com.commonsware.cwac.document.DocumentFileCompat
import deckers.thibault.aves.model.AvesImageEntry import deckers.thibault.aves.model.AvesEntry
import deckers.thibault.aves.model.ExifOrientationOp import deckers.thibault.aves.model.ExifOrientationOp
import deckers.thibault.aves.utils.LogUtils import deckers.thibault.aves.utils.LogUtils
import deckers.thibault.aves.utils.MimeTypes.isImage import deckers.thibault.aves.utils.MimeTypes.isImage
@ -32,7 +32,7 @@ abstract class ImageProvider {
throw UnsupportedOperationException() throw UnsupportedOperationException()
} }
open suspend fun moveMultiple(context: Context, copy: Boolean, destinationDir: String, entries: List<AvesImageEntry>, callback: ImageOpCallback) { open suspend fun moveMultiple(context: Context, copy: Boolean, destinationDir: String, entries: List<AvesEntry>, callback: ImageOpCallback) {
callback.onFailure(UnsupportedOperationException()) callback.onFailure(UnsupportedOperationException())
} }

View file

@ -8,8 +8,8 @@ import android.os.Build
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Log import android.util.Log
import com.commonsware.cwac.document.DocumentFileCompat import com.commonsware.cwac.document.DocumentFileCompat
import deckers.thibault.aves.model.AvesImageEntry import deckers.thibault.aves.model.AvesEntry
import deckers.thibault.aves.model.SourceImageEntry import deckers.thibault.aves.model.SourceEntry
import deckers.thibault.aves.utils.LogUtils import deckers.thibault.aves.utils.LogUtils
import deckers.thibault.aves.utils.MimeTypes import deckers.thibault.aves.utils.MimeTypes
import deckers.thibault.aves.utils.MimeTypes.isImage import deckers.thibault.aves.utils.MimeTypes.isImage
@ -158,7 +158,7 @@ class MediaStoreImageProvider : ImageProvider() {
// missing some attributes such as width, height, orientation. // missing some attributes such as width, height, orientation.
// Also, the reported size of raw images is inconsistent across devices // Also, the reported size of raw images is inconsistent across devices
// and Android versions (sometimes the raw size, sometimes the decoded size). // and Android versions (sometimes the raw size, sometimes the decoded size).
val entry = SourceImageEntry(entryMap).fillPreCatalogMetadata(context) val entry = SourceEntry(entryMap).fillPreCatalogMetadata(context)
entryMap = entry.toMap() entryMap = entry.toMap()
} }
@ -203,7 +203,7 @@ class MediaStoreImageProvider : ImageProvider() {
context: Context, context: Context,
copy: Boolean, copy: Boolean,
destinationDir: String, destinationDir: String,
entries: List<AvesImageEntry>, entries: List<AvesEntry>,
callback: ImageOpCallback, callback: ImageOpCallback,
) { ) {
val destinationDirDocFile = createDirectoryIfAbsent(context, destinationDir) val destinationDirDocFile = createDirectoryIfAbsent(context, destinationDir)

View file

@ -2,7 +2,7 @@ import 'dart:async';
import 'package:aves/model/entry_cache.dart'; import 'package:aves/model/entry_cache.dart';
import 'package:aves/model/favourite_repo.dart'; import 'package:aves/model/favourite_repo.dart';
import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/metadata.dart';
import 'package:aves/model/metadata_db.dart'; import 'package:aves/model/metadata_db.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/services/image_file_service.dart'; import 'package:aves/services/image_file_service.dart';
@ -21,7 +21,7 @@ import 'package:path/path.dart' as ppath;
import '../ref/mime_types.dart'; import '../ref/mime_types.dart';
class ImageEntry { class AvesEntry {
String uri; String uri;
String _path, _directory, _filename, _extension; String _path, _directory, _filename, _extension;
int page, contentId; int page, contentId;
@ -45,7 +45,7 @@ class ImageEntry {
// TODO TLAD make it dynamic if it depends on OS/lib versions // TODO TLAD make it dynamic if it depends on OS/lib versions
static const List<String> undecodable = [MimeTypes.crw, MimeTypes.psd]; static const List<String> undecodable = [MimeTypes.crw, MimeTypes.psd];
ImageEntry({ AvesEntry({
this.uri, this.uri,
String path, String path,
this.contentId, this.contentId,
@ -69,14 +69,14 @@ class ImageEntry {
bool get canHaveAlpha => MimeTypes.alphaImages.contains(mimeType); bool get canHaveAlpha => MimeTypes.alphaImages.contains(mimeType);
ImageEntry copyWith({ AvesEntry copyWith({
@required String uri, @required String uri,
@required String path, @required String path,
@required int contentId, @required int contentId,
@required int dateModifiedSecs, @required int dateModifiedSecs,
}) { }) {
final copyContentId = contentId ?? this.contentId; final copyContentId = contentId ?? this.contentId;
final copied = ImageEntry( final copied = AvesEntry(
uri: uri ?? uri, uri: uri ?? uri,
path: path ?? this.path, path: path ?? this.path,
contentId: copyContentId, contentId: copyContentId,
@ -96,7 +96,7 @@ class ImageEntry {
return copied; return copied;
} }
ImageEntry getPageEntry({ AvesEntry getPageEntry({
@required MultiPageInfo multiPageInfo, @required MultiPageInfo multiPageInfo,
@required int page, @required int page,
}) { }) {
@ -126,8 +126,8 @@ class ImageEntry {
} }
// from DB or platform source entry // from DB or platform source entry
factory ImageEntry.fromMap(Map map) { factory AvesEntry.fromMap(Map map) {
return ImageEntry( return AvesEntry(
uri: map['uri'] as String, uri: map['uri'] as String,
path: map['path'] as String, path: map['path'] as String,
contentId: map['contentId'] as int, contentId: map['contentId'] as int,
@ -619,7 +619,7 @@ class ImageEntry {
// compare by: // compare by:
// 1) title ascending // 1) title ascending
// 2) extension ascending // 2) extension ascending
static int compareByName(ImageEntry a, ImageEntry b) { static int compareByName(AvesEntry a, AvesEntry b) {
final c = compareAsciiUpperCase(a.bestTitle, b.bestTitle); final c = compareAsciiUpperCase(a.bestTitle, b.bestTitle);
return c != 0 ? c : compareAsciiUpperCase(a.extension, b.extension); return c != 0 ? c : compareAsciiUpperCase(a.extension, b.extension);
} }
@ -627,7 +627,7 @@ class ImageEntry {
// compare by: // compare by:
// 1) size descending // 1) size descending
// 2) name ascending // 2) name ascending
static int compareBySize(ImageEntry a, ImageEntry b) { static int compareBySize(AvesEntry a, AvesEntry b) {
final c = b.sizeBytes.compareTo(a.sizeBytes); final c = b.sizeBytes.compareTo(a.sizeBytes);
return c != 0 ? c : compareByName(a, b); return c != 0 ? c : compareByName(a, b);
} }
@ -637,7 +637,7 @@ class ImageEntry {
// compare by: // compare by:
// 1) date descending // 1) date descending
// 2) name ascending // 2) name ascending
static int compareByDate(ImageEntry a, ImageEntry b) { static int compareByDate(AvesEntry a, AvesEntry b) {
final c = (b.bestDate ?? _epoch).compareTo(a.bestDate ?? _epoch); final c = (b.bestDate ?? _epoch).compareTo(a.bestDate ?? _epoch);
return c != 0 ? c : compareByName(a, b); return c != 0 ? c : compareByName(a, b);
} }

View file

@ -4,11 +4,11 @@ import 'dart:ui';
import 'package:aves/image_providers/region_provider.dart'; import 'package:aves/image_providers/region_provider.dart';
import 'package:aves/image_providers/thumbnail_provider.dart'; import 'package:aves/image_providers/thumbnail_provider.dart';
import 'package:aves/image_providers/uri_image_provider.dart'; import 'package:aves/image_providers/uri_image_provider.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
extension ExtraAvesEntry on ImageEntry { extension ExtraAvesEntry on AvesEntry {
ThumbnailProvider getThumbnail({double extent = 0}) => ThumbnailProvider(_getThumbnailProviderKey(extent)); ThumbnailProvider getThumbnail({double extent = 0}) => ThumbnailProvider(_getThumbnailProviderKey(extent));
ThumbnailProviderKey _getThumbnailProviderKey(double extent) { ThumbnailProviderKey _getThumbnailProviderKey(double extent) {

View file

@ -1,5 +1,5 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/metadata.dart';
import 'package:aves/model/metadata_db.dart'; import 'package:aves/model/metadata_db.dart';
import 'package:aves/utils/change_notifier.dart'; import 'package:aves/utils/change_notifier.dart';
@ -18,25 +18,25 @@ class FavouriteRepo {
int get count => _rows.length; int get count => _rows.length;
bool isFavourite(ImageEntry entry) => _rows.any((row) => row.contentId == entry.contentId); bool isFavourite(AvesEntry entry) => _rows.any((row) => row.contentId == entry.contentId);
FavouriteRow _entryToRow(ImageEntry entry) => FavouriteRow(contentId: entry.contentId, path: entry.path); FavouriteRow _entryToRow(AvesEntry entry) => FavouriteRow(contentId: entry.contentId, path: entry.path);
Future<void> add(Iterable<ImageEntry> entries) async { Future<void> add(Iterable<AvesEntry> entries) async {
final newRows = entries.map(_entryToRow); final newRows = entries.map(_entryToRow);
await metadataDb.addFavourites(newRows); await metadataDb.addFavourites(newRows);
_rows.addAll(newRows); _rows.addAll(newRows);
changeNotifier.notifyListeners(); changeNotifier.notifyListeners();
} }
Future<void> remove(Iterable<ImageEntry> entries) async { Future<void> remove(Iterable<AvesEntry> entries) async {
final removedRows = entries.map(_entryToRow); final removedRows = entries.map(_entryToRow);
await metadataDb.removeFavourites(removedRows); await metadataDb.removeFavourites(removedRows);
removedRows.forEach(_rows.remove); removedRows.forEach(_rows.remove);
changeNotifier.notifyListeners(); changeNotifier.notifyListeners();
} }
Future<void> move(int oldContentId, ImageEntry entry) async { Future<void> move(int oldContentId, AvesEntry entry) async {
final oldRow = _rows.firstWhere((row) => row.contentId == oldContentId, orElse: () => null); final oldRow = _rows.firstWhere((row) => row.contentId == oldContentId, orElse: () => null);
if (oldRow != null) { if (oldRow != null) {
_rows.remove(oldRow); _rows.remove(oldRow);

View file

@ -1,6 +1,6 @@
import 'package:aves/image_providers/app_icon_image_provider.dart'; import 'package:aves/image_providers/app_icon_image_provider.dart';
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/widgets/common/identity/aves_icons.dart'; import 'package:aves/widgets/common/identity/aves_icons.dart';
@ -33,7 +33,7 @@ class AlbumFilter extends CollectionFilter {
}; };
@override @override
bool filter(ImageEntry entry) => entry.directory == album; bool filter(AvesEntry entry) => entry.directory == album;
@override @override
String get label => uniqueName ?? album.split(separator).last; String get label => uniqueName ?? album.split(separator).last;

View file

@ -1,5 +1,5 @@
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -13,7 +13,7 @@ class FavouriteFilter extends CollectionFilter {
}; };
@override @override
bool filter(ImageEntry entry) => entry.isFavourite; bool filter(AvesEntry entry) => entry.isFavourite;
@override @override
String get label => 'Favourite'; String get label => 'Favourite';

View file

@ -1,12 +1,12 @@
import 'dart:convert'; import 'dart:convert';
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/album.dart'; import 'package:aves/model/filters/album.dart';
import 'package:aves/model/filters/favourite.dart'; import 'package:aves/model/filters/favourite.dart';
import 'package:aves/model/filters/location.dart'; import 'package:aves/model/filters/location.dart';
import 'package:aves/model/filters/mime.dart'; import 'package:aves/model/filters/mime.dart';
import 'package:aves/model/filters/query.dart'; import 'package:aves/model/filters/query.dart';
import 'package:aves/model/filters/tag.dart'; import 'package:aves/model/filters/tag.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/utils/color_utils.dart'; import 'package:aves/utils/color_utils.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -49,7 +49,7 @@ abstract class CollectionFilter implements Comparable<CollectionFilter> {
String toJson() => jsonEncode(toMap()); String toJson() => jsonEncode(toMap());
bool filter(ImageEntry entry); bool filter(AvesEntry entry);
bool get isUnique => true; bool get isUnique => true;
@ -78,7 +78,7 @@ abstract class CollectionFilter implements Comparable<CollectionFilter> {
// TODO TLAD replace this by adding getters to CollectionFilter, with cached entry/count coming from Source // TODO TLAD replace this by adding getters to CollectionFilter, with cached entry/count coming from Source
class FilterGridItem<T extends CollectionFilter> { class FilterGridItem<T extends CollectionFilter> {
final T filter; final T filter;
final ImageEntry entry; final AvesEntry entry;
const FilterGridItem(this.filter, this.entry); const FilterGridItem(this.filter, this.entry);

View file

@ -1,5 +1,5 @@
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -35,7 +35,7 @@ class LocationFilter extends CollectionFilter {
String get countryNameAndCode => '$_location$locationSeparator$_countryCode'; String get countryNameAndCode => '$_location$locationSeparator$_countryCode';
@override @override
bool filter(ImageEntry entry) => _location.isEmpty ? !entry.isLocated : entry.isLocated && ((level == LocationLevel.country && entry.addressDetails.countryCode == _countryCode) || (level == LocationLevel.place && entry.addressDetails.place == _location)); bool filter(AvesEntry entry) => _location.isEmpty ? !entry.isLocated : entry.isLocated && ((level == LocationLevel.country && entry.addressDetails.countryCode == _countryCode) || (level == LocationLevel.place && entry.addressDetails.place == _location));
@override @override
String get label => _location.isEmpty ? emptyLabel : _location; String get label => _location.isEmpty ? emptyLabel : _location;

View file

@ -1,5 +1,5 @@
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/mime_utils.dart'; import 'package:aves/utils/mime_utils.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -15,7 +15,7 @@ class MimeFilter extends CollectionFilter {
static const geotiff = 'aves/geotiff'; // subset of `image/tiff` static const geotiff = 'aves/geotiff'; // subset of `image/tiff`
final String mime; final String mime;
bool Function(ImageEntry) _filter; bool Function(AvesEntry) _filter;
String _label; String _label;
IconData _icon; IconData _icon;
@ -67,7 +67,7 @@ class MimeFilter extends CollectionFilter {
}; };
@override @override
bool filter(ImageEntry entry) => _filter(entry); bool filter(AvesEntry entry) => _filter(entry);
@override @override
String get label => _label; String get label => _label;

View file

@ -1,5 +1,5 @@
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -12,7 +12,7 @@ class QueryFilter extends CollectionFilter {
final String query; final String query;
final bool colorful; final bool colorful;
bool Function(ImageEntry) _filter; bool Function(AvesEntry) _filter;
QueryFilter(this.query, {this.colorful = true}) { QueryFilter(this.query, {this.colorful = true}) {
var upQuery = query.toUpperCase(); var upQuery = query.toUpperCase();
@ -44,7 +44,7 @@ class QueryFilter extends CollectionFilter {
}; };
@override @override
bool filter(ImageEntry entry) => _filter(entry); bool filter(AvesEntry entry) => _filter(entry);
@override @override
bool get isUnique => false; bool get isUnique => false;

View file

@ -1,5 +1,5 @@
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -24,7 +24,7 @@ class TagFilter extends CollectionFilter {
}; };
@override @override
bool filter(ImageEntry entry) => tag.isEmpty ? entry.xmpSubjects.isEmpty : entry.xmpSubjects.contains(tag); bool filter(AvesEntry entry) => tag.isEmpty ? entry.xmpSubjects.isEmpty : entry.xmpSubjects.contains(tag);
@override @override
bool get isUnique => false; bool get isUnique => false;

View file

@ -1,7 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/metadata.dart';
import 'package:aves/model/metadata_db_upgrade.dart'; import 'package:aves/model/metadata_db_upgrade.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:path/path.dart'; import 'package:path/path.dart';
@ -116,16 +116,16 @@ class MetadataDb {
debugPrint('$runtimeType clearEntries deleted $count entries'); debugPrint('$runtimeType clearEntries deleted $count entries');
} }
Future<List<ImageEntry>> loadEntries() async { Future<List<AvesEntry>> loadEntries() async {
final stopwatch = Stopwatch()..start(); final stopwatch = Stopwatch()..start();
final db = await _database; final db = await _database;
final maps = await db.query(entryTable); final maps = await db.query(entryTable);
final entries = maps.map((map) => ImageEntry.fromMap(map)).toList(); final entries = maps.map((map) => AvesEntry.fromMap(map)).toList();
debugPrint('$runtimeType loadEntries complete in ${stopwatch.elapsed.inMilliseconds}ms for ${entries.length} entries'); debugPrint('$runtimeType loadEntries complete in ${stopwatch.elapsed.inMilliseconds}ms for ${entries.length} entries');
return entries; return entries;
} }
Future<void> saveEntries(Iterable<ImageEntry> entries) async { Future<void> saveEntries(Iterable<AvesEntry> entries) async {
if (entries == null || entries.isEmpty) return; if (entries == null || entries.isEmpty) return;
final stopwatch = Stopwatch()..start(); final stopwatch = Stopwatch()..start();
final db = await _database; final db = await _database;
@ -135,7 +135,7 @@ class MetadataDb {
debugPrint('$runtimeType saveEntries complete in ${stopwatch.elapsed.inMilliseconds}ms for ${entries.length} entries'); debugPrint('$runtimeType saveEntries complete in ${stopwatch.elapsed.inMilliseconds}ms for ${entries.length} entries');
} }
Future<void> updateEntryId(int oldId, ImageEntry entry) async { Future<void> updateEntryId(int oldId, AvesEntry entry) async {
final db = await _database; final db = await _database;
final batch = db.batch(); final batch = db.batch();
batch.delete(entryTable, where: 'contentId = ?', whereArgs: [oldId]); batch.delete(entryTable, where: 'contentId = ?', whereArgs: [oldId]);
@ -143,7 +143,7 @@ class MetadataDb {
await batch.commit(noResult: true); await batch.commit(noResult: true);
} }
void _batchInsertEntry(Batch batch, ImageEntry entry) { void _batchInsertEntry(Batch batch, AvesEntry entry) {
if (entry == null) return; if (entry == null) return;
batch.insert( batch.insert(
entryTable, entryTable,

View file

@ -1,4 +1,4 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
class MultiPageInfo { class MultiPageInfo {
@ -50,7 +50,7 @@ class SinglePageInfo {
String toString() => '$runtimeType#${shortHash(this)}{mimeType=$mimeType, width=$width, height=$height, trackId=$trackId, durationMillis=$durationMillis}'; String toString() => '$runtimeType#${shortHash(this)}{mimeType=$mimeType, width=$width, height=$height, trackId=$trackId, durationMillis=$durationMillis}';
} }
class AvesPageEntry extends ImageEntry { class AvesPageEntry extends AvesEntry {
final SinglePageInfo pageInfo; final SinglePageInfo pageInfo;
AvesPageEntry({ AvesPageEntry({

View file

@ -1,5 +1,5 @@
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/album.dart'; import 'package:aves/model/filters/album.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
@ -50,7 +50,7 @@ mixin AlbumMixin on SourceBase {
} }
} }
Map<String, ImageEntry> getAlbumEntries() { Map<String, AvesEntry> getAlbumEntries() {
final entries = sortedEntriesForFilterList; final entries = sortedEntriesForFilterList;
final regularAlbums = <String>[], appAlbums = <String>[], specialAlbums = <String>[]; final regularAlbums = <String>[], appAlbums = <String>[], specialAlbums = <String>[];
for (var album in sortedAlbums) { for (var album in sortedAlbums) {

View file

@ -1,9 +1,9 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/album.dart'; import 'package:aves/model/filters/album.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/model/source/section_keys.dart'; import 'package:aves/model/source/section_keys.dart';
import 'package:aves/model/source/tag.dart'; import 'package:aves/model/source/tag.dart';
@ -20,10 +20,10 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel
EntrySortFactor sortFactor; EntrySortFactor sortFactor;
final AChangeNotifier filterChangeNotifier = AChangeNotifier(); final AChangeNotifier filterChangeNotifier = AChangeNotifier();
List<ImageEntry> _filteredEntries; List<AvesEntry> _filteredEntries;
List<StreamSubscription> _subscriptions = []; List<StreamSubscription> _subscriptions = [];
Map<SectionKey, List<ImageEntry>> sections = Map.unmodifiable({}); Map<SectionKey, List<AvesEntry>> sections = Map.unmodifiable({});
CollectionLens({ CollectionLens({
@required this.source, @required this.source,
@ -63,9 +63,9 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel
int get entryCount => _filteredEntries.length; int get entryCount => _filteredEntries.length;
// sorted as displayed to the user, i.e. sorted then grouped, not an absolute order on all entries // sorted as displayed to the user, i.e. sorted then grouped, not an absolute order on all entries
List<ImageEntry> _sortedEntries; List<AvesEntry> _sortedEntries;
List<ImageEntry> get sortedEntries { List<AvesEntry> get sortedEntries {
_sortedEntries ??= List.of(sections.entries.expand((e) => e.value)); _sortedEntries ??= List.of(sections.entries.expand((e) => e.value));
return _sortedEntries; return _sortedEntries;
} }
@ -82,7 +82,7 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel
return true; return true;
} }
Object heroTag(ImageEntry entry) => '$hashCode${entry.uri}'; Object heroTag(AvesEntry entry) => '$hashCode${entry.uri}';
void addFilter(CollectionFilter filter) { void addFilter(CollectionFilter filter) {
if (filter == null || filters.contains(filter)) return; if (filter == null || filters.contains(filter)) return;
@ -123,13 +123,13 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel
void _applySort() { void _applySort() {
switch (sortFactor) { switch (sortFactor) {
case EntrySortFactor.date: case EntrySortFactor.date:
_filteredEntries.sort(ImageEntry.compareByDate); _filteredEntries.sort(AvesEntry.compareByDate);
break; break;
case EntrySortFactor.size: case EntrySortFactor.size:
_filteredEntries.sort(ImageEntry.compareBySize); _filteredEntries.sort(AvesEntry.compareBySize);
break; break;
case EntrySortFactor.name: case EntrySortFactor.name:
_filteredEntries.sort(ImageEntry.compareByName); _filteredEntries.sort(AvesEntry.compareByName);
break; break;
} }
} }
@ -139,13 +139,13 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel
case EntrySortFactor.date: case EntrySortFactor.date:
switch (groupFactor) { switch (groupFactor) {
case EntryGroupFactor.album: case EntryGroupFactor.album:
sections = groupBy<ImageEntry, EntryAlbumSectionKey>(_filteredEntries, (entry) => EntryAlbumSectionKey(entry.directory)); sections = groupBy<AvesEntry, EntryAlbumSectionKey>(_filteredEntries, (entry) => EntryAlbumSectionKey(entry.directory));
break; break;
case EntryGroupFactor.month: case EntryGroupFactor.month:
sections = groupBy<ImageEntry, EntryDateSectionKey>(_filteredEntries, (entry) => EntryDateSectionKey(entry.monthTaken)); sections = groupBy<AvesEntry, EntryDateSectionKey>(_filteredEntries, (entry) => EntryDateSectionKey(entry.monthTaken));
break; break;
case EntryGroupFactor.day: case EntryGroupFactor.day:
sections = groupBy<ImageEntry, EntryDateSectionKey>(_filteredEntries, (entry) => EntryDateSectionKey(entry.dayTaken)); sections = groupBy<AvesEntry, EntryDateSectionKey>(_filteredEntries, (entry) => EntryDateSectionKey(entry.dayTaken));
break; break;
case EntryGroupFactor.none: case EntryGroupFactor.none:
sections = Map.fromEntries([ sections = Map.fromEntries([
@ -160,8 +160,8 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel
]); ]);
break; break;
case EntrySortFactor.name: case EntrySortFactor.name:
final byAlbum = groupBy<ImageEntry, EntryAlbumSectionKey>(_filteredEntries, (entry) => EntryAlbumSectionKey(entry.directory)); final byAlbum = groupBy<AvesEntry, EntryAlbumSectionKey>(_filteredEntries, (entry) => EntryAlbumSectionKey(entry.directory));
sections = SplayTreeMap<EntryAlbumSectionKey, List<ImageEntry>>.of(byAlbum, (a, b) => source.compareAlbumsByName(a.folderPath, b.folderPath)); sections = SplayTreeMap<EntryAlbumSectionKey, List<AvesEntry>>.of(byAlbum, (a, b) => source.compareAlbumsByName(a.folderPath, b.folderPath));
break; break;
} }
sections = Map.unmodifiable(sections); sections = Map.unmodifiable(sections);
@ -177,7 +177,7 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel
_applyGroup(); _applyGroup();
} }
void onEntryRemoved(Iterable<ImageEntry> entries) { void onEntryRemoved(Iterable<AvesEntry> entries) {
// we should remove obsolete entries and sections // we should remove obsolete entries and sections
// but do not apply sort/group // but do not apply sort/group
// as section order change would surprise the user while browsing // as section order change would surprise the user while browsing
@ -207,18 +207,18 @@ mixin CollectionActivityMixin {
mixin CollectionSelectionMixin on CollectionActivityMixin { mixin CollectionSelectionMixin on CollectionActivityMixin {
final AChangeNotifier selectionChangeNotifier = AChangeNotifier(); final AChangeNotifier selectionChangeNotifier = AChangeNotifier();
final Set<ImageEntry> _selection = {}; final Set<AvesEntry> _selection = {};
Set<ImageEntry> get selection => _selection; Set<AvesEntry> get selection => _selection;
bool isSelected(Iterable<ImageEntry> entries) => entries.every(selection.contains); bool isSelected(Iterable<AvesEntry> entries) => entries.every(selection.contains);
void addToSelection(Iterable<ImageEntry> entries) { void addToSelection(Iterable<AvesEntry> entries) {
_selection.addAll(entries); _selection.addAll(entries);
selectionChangeNotifier.notifyListeners(); selectionChangeNotifier.notifyListeners();
} }
void removeFromSelection(Iterable<ImageEntry> entries) { void removeFromSelection(Iterable<AvesEntry> entries) {
_selection.removeAll(entries); _selection.removeAll(entries);
selectionChangeNotifier.notifyListeners(); selectionChangeNotifier.notifyListeners();
} }
@ -228,7 +228,7 @@ mixin CollectionSelectionMixin on CollectionActivityMixin {
selectionChangeNotifier.notifyListeners(); selectionChangeNotifier.notifyListeners();
} }
void toggleSelection(ImageEntry entry) { void toggleSelection(AvesEntry entry) {
if (_selection.isEmpty) select(); if (_selection.isEmpty) select();
if (!_selection.remove(entry)) _selection.add(entry); if (!_selection.remove(entry)) _selection.add(entry);
selectionChangeNotifier.notifyListeners(); selectionChangeNotifier.notifyListeners();

View file

@ -2,8 +2,8 @@ import 'dart:async';
import 'package:aves/model/favourite_repo.dart'; import 'package:aves/model/favourite_repo.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/metadata.dart';
import 'package:aves/model/metadata_db.dart'; import 'package:aves/model/metadata_db.dart';
import 'package:aves/model/source/album.dart'; import 'package:aves/model/source/album.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
@ -16,15 +16,15 @@ import 'package:flutter/foundation.dart';
import 'enums.dart'; import 'enums.dart';
mixin SourceBase { mixin SourceBase {
final List<ImageEntry> _rawEntries = []; final List<AvesEntry> _rawEntries = [];
List<ImageEntry> get rawEntries => List.unmodifiable(_rawEntries); List<AvesEntry> get rawEntries => List.unmodifiable(_rawEntries);
final EventBus _eventBus = EventBus(); final EventBus _eventBus = EventBus();
EventBus get eventBus => _eventBus; EventBus get eventBus => _eventBus;
List<ImageEntry> get sortedEntriesForFilterList; List<AvesEntry> get sortedEntriesForFilterList;
final Map<CollectionFilter, int> _filterEntryCountMap = {}; final Map<CollectionFilter, int> _filterEntryCountMap = {};
@ -39,7 +39,7 @@ mixin SourceBase {
abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagMixin { abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagMixin {
@override @override
List<ImageEntry> get sortedEntriesForFilterList => CollectionLens( List<AvesEntry> get sortedEntriesForFilterList => CollectionLens(
source: this, source: this,
groupFactor: EntryGroupFactor.none, groupFactor: EntryGroupFactor.none,
sortFactor: EntrySortFactor.date, sortFactor: EntrySortFactor.date,
@ -55,7 +55,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
debugPrint('$runtimeType loadDates complete in ${stopwatch.elapsed.inMilliseconds}ms for ${_savedDates.length} entries'); debugPrint('$runtimeType loadDates complete in ${stopwatch.elapsed.inMilliseconds}ms for ${_savedDates.length} entries');
} }
void addAll(Iterable<ImageEntry> entries) { void addAll(Iterable<AvesEntry> entries) {
if (_rawEntries.isNotEmpty) { if (_rawEntries.isNotEmpty) {
final newContentIds = entries.map((entry) => entry.contentId).toList(); final newContentIds = entries.map((entry) => entry.contentId).toList();
_rawEntries.removeWhere((entry) => newContentIds.contains(entry.contentId)); _rawEntries.removeWhere((entry) => newContentIds.contains(entry.contentId));
@ -70,7 +70,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
eventBus.fire(EntryAddedEvent()); eventBus.fire(EntryAddedEvent());
} }
void removeEntries(List<ImageEntry> entries) { void removeEntries(List<AvesEntry> entries) {
entries.forEach((entry) => entry.removeFromFavourites()); entries.forEach((entry) => entry.removeFromFavourites());
_rawEntries.removeWhere(entries.contains); _rawEntries.removeWhere(entries.contains);
cleanEmptyAlbums(entries.map((entry) => entry.directory).toSet()); cleanEmptyAlbums(entries.map((entry) => entry.directory).toSet());
@ -91,7 +91,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
// `dateModifiedSecs` changes when moving entries to another directory, // `dateModifiedSecs` changes when moving entries to another directory,
// but it does not change when renaming the containing directory // but it does not change when renaming the containing directory
Future<void> moveEntry(ImageEntry entry, Map newFields) async { Future<void> moveEntry(AvesEntry entry, Map newFields) async {
final oldContentId = entry.contentId; final oldContentId = entry.contentId;
final newContentId = newFields['contentId'] as int; final newContentId = newFields['contentId'] as int;
final newDateModifiedSecs = newFields['dateModifiedSecs'] as int; final newDateModifiedSecs = newFields['dateModifiedSecs'] as int;
@ -109,7 +109,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
} }
void updateAfterMove({ void updateAfterMove({
@required Set<ImageEntry> selection, @required Set<AvesEntry> selection,
@required bool copy, @required bool copy,
@required String destinationAlbum, @required String destinationAlbum,
@required Iterable<MoveOpEvent> movedOps, @required Iterable<MoveOpEvent> movedOps,
@ -117,7 +117,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
if (movedOps.isEmpty) return; if (movedOps.isEmpty) return;
final fromAlbums = <String>{}; final fromAlbums = <String>{};
final movedEntries = <ImageEntry>[]; final movedEntries = <AvesEntry>[];
if (copy) { if (copy) {
movedOps.forEach((movedOp) { movedOps.forEach((movedOp) {
final sourceUri = movedOp.uri; final sourceUri = movedOp.uri;
@ -166,25 +166,25 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
Future<void> refresh(); Future<void> refresh();
Future<void> refreshMetadata(Set<ImageEntry> entries); Future<void> refreshMetadata(Set<AvesEntry> entries);
} }
enum SourceState { loading, cataloguing, locating, ready } enum SourceState { loading, cataloguing, locating, ready }
class EntryAddedEvent { class EntryAddedEvent {
final ImageEntry entry; final AvesEntry entry;
const EntryAddedEvent([this.entry]); const EntryAddedEvent([this.entry]);
} }
class EntryRemovedEvent { class EntryRemovedEvent {
final Iterable<ImageEntry> entries; final Iterable<AvesEntry> entries;
const EntryRemovedEvent(this.entries); const EntryRemovedEvent(this.entries);
} }
class EntryMovedEvent { class EntryMovedEvent {
final Iterable<ImageEntry> entries; final Iterable<AvesEntry> entries;
const EntryMovedEvent(this.entries); const EntryMovedEvent(this.entries);
} }

View file

@ -1,8 +1,8 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/model/filters/location.dart'; import 'package:aves/model/filters/location.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/metadata.dart';
import 'package:aves/model/metadata_db.dart'; import 'package:aves/model/metadata_db.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
@ -28,7 +28,7 @@ mixin LocationMixin on SourceBase {
Future<void> locateEntries() async { Future<void> locateEntries() async {
// final stopwatch = Stopwatch()..start(); // final stopwatch = Stopwatch()..start();
final byLocated = groupBy<ImageEntry, bool>(rawEntries.where((entry) => entry.hasGps), (entry) => entry.isLocated); final byLocated = groupBy<AvesEntry, bool>(rawEntries.where((entry) => entry.hasGps), (entry) => entry.isLocated);
final todo = byLocated[false] ?? []; final todo = byLocated[false] ?? [];
if (todo.isEmpty) return; if (todo.isEmpty) return;
@ -42,7 +42,7 @@ mixin LocationMixin on SourceBase {
// - 652 calls (22%) when approximating to 2 decimal places (~1km - town or village) // - 652 calls (22%) when approximating to 2 decimal places (~1km - town or village)
// cf https://en.wikipedia.org/wiki/Decimal_degrees#Precision // cf https://en.wikipedia.org/wiki/Decimal_degrees#Precision
final latLngFactor = pow(10, 2); final latLngFactor = pow(10, 2);
Tuple2 approximateLatLng(ImageEntry entry) { Tuple2 approximateLatLng(AvesEntry entry) {
final lat = entry.catalogMetadata?.latitude; final lat = entry.catalogMetadata?.latitude;
final lng = entry.catalogMetadata?.longitude; final lng = entry.catalogMetadata?.longitude;
if (lat == null || lng == null) return null; if (lat == null || lng == null) return null;
@ -57,7 +57,7 @@ mixin LocationMixin on SourceBase {
setProgress(done: progressDone, total: progressTotal); setProgress(done: progressDone, total: progressTotal);
final newAddresses = <AddressDetails>[]; final newAddresses = <AddressDetails>[];
await Future.forEach<ImageEntry>(todo, (entry) async { await Future.forEach<AvesEntry>(todo, (entry) async {
final latLng = approximateLatLng(entry); final latLng = approximateLatLng(entry);
if (knownLocations.containsKey(latLng)) { if (knownLocations.containsKey(latLng)) {
entry.addressDetails = knownLocations[latLng]?.copyWith(contentId: entry.contentId); entry.addressDetails = knownLocations[latLng]?.copyWith(contentId: entry.contentId);

View file

@ -1,7 +1,7 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/model/entry.dart';
import 'package:aves/model/favourite_repo.dart'; import 'package:aves/model/favourite_repo.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/model/metadata_db.dart'; import 'package:aves/model/metadata_db.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
@ -55,14 +55,14 @@ class MediaStoreSource extends CollectionSource {
// fetch new entries // fetch new entries
var refreshCount = 10; var refreshCount = 10;
const refreshCountMax = 1000; const refreshCountMax = 1000;
final allNewEntries = <ImageEntry>[], pendingNewEntries = <ImageEntry>[]; final allNewEntries = <AvesEntry>[], pendingNewEntries = <AvesEntry>[];
void addPendingEntries() { void addPendingEntries() {
allNewEntries.addAll(pendingNewEntries); allNewEntries.addAll(pendingNewEntries);
addAll(pendingNewEntries); addAll(pendingNewEntries);
pendingNewEntries.clear(); pendingNewEntries.clear();
} }
ImageFileService.getImageEntries(knownEntryMap).listen( ImageFileService.getEntries(knownEntryMap).listen(
(entry) { (entry) {
pendingNewEntries.add(entry); pendingNewEntries.add(entry);
if (pendingNewEntries.length >= refreshCount) { if (pendingNewEntries.length >= refreshCount) {
@ -96,7 +96,7 @@ class MediaStoreSource extends CollectionSource {
} }
@override @override
Future<void> refreshMetadata(Set<ImageEntry> entries) { Future<void> refreshMetadata(Set<AvesEntry> entries) {
final contentIds = entries.map((entry) => entry.contentId).toSet(); final contentIds = entries.map((entry) => entry.contentId).toSet();
metadataDb.removeIds(contentIds, updateFavourites: false); metadataDb.removeIds(contentIds, updateFavourites: false);
return refresh(); return refresh();

View file

@ -1,5 +1,5 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/metadata.dart';
import 'package:aves/model/metadata_db.dart'; import 'package:aves/model/metadata_db.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
@ -31,7 +31,7 @@ mixin TagMixin on SourceBase {
setProgress(done: progressDone, total: progressTotal); setProgress(done: progressDone, total: progressTotal);
final newMetadata = <CatalogMetadata>[]; final newMetadata = <CatalogMetadata>[];
await Future.forEach<ImageEntry>(todo, (entry) async { await Future.forEach<AvesEntry>(todo, (entry) async {
await entry.catalog(background: true); await entry.catalog(background: true);
if (entry.isCatalogued) { if (entry.isCatalogued) {
newMetadata.add(entry.catalogMetadata); newMetadata.add(entry.catalogMetadata);

View file

@ -1,6 +1,6 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -81,10 +81,10 @@ class AndroidAppService {
return false; return false;
} }
static Future<bool> shareEntries(Iterable<ImageEntry> entries) async { static Future<bool> shareEntries(Iterable<AvesEntry> entries) async {
// loosen mime type to a generic one, so we can share with badly defined apps // loosen mime type to a generic one, so we can share with badly defined apps
// e.g. Google Lens declares receiving "image/jpeg" only, but it can actually handle more formats // e.g. Google Lens declares receiving "image/jpeg" only, but it can actually handle more formats
final urisByMimeType = groupBy<ImageEntry, String>(entries, (e) => e.mimeTypeAnySubtype).map((k, v) => MapEntry(k, v.map((e) => e.uri).toList())); final urisByMimeType = groupBy<AvesEntry, String>(entries, (e) => e.mimeTypeAnySubtype).map((k, v) => MapEntry(k, v.map((e) => e.uri).toList()));
try { try {
return await platform.invokeMethod('share', <String, dynamic>{ return await platform.invokeMethod('share', <String, dynamic>{
'title': 'Share via:', 'title': 'Share via:',

View file

@ -1,4 +1,4 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/ref/mime_types.dart'; import 'package:aves/ref/mime_types.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -26,7 +26,7 @@ class AndroidDebugService {
return {}; return {};
} }
static Future<Map> getBitmapFactoryInfo(ImageEntry entry) async { static Future<Map> getBitmapFactoryInfo(AvesEntry entry) async {
try { try {
// return map with all data available when decoding image bounds with `BitmapFactory` // return map with all data available when decoding image bounds with `BitmapFactory`
final result = await platform.invokeMethod('getBitmapFactoryInfo', <String, dynamic>{ final result = await platform.invokeMethod('getBitmapFactoryInfo', <String, dynamic>{
@ -39,7 +39,7 @@ class AndroidDebugService {
return {}; return {};
} }
static Future<Map> getContentResolverMetadata(ImageEntry entry) async { static Future<Map> getContentResolverMetadata(AvesEntry entry) async {
try { try {
// return map with all data available from the content resolver // return map with all data available from the content resolver
final result = await platform.invokeMethod('getContentResolverMetadata', <String, dynamic>{ final result = await platform.invokeMethod('getContentResolverMetadata', <String, dynamic>{
@ -53,7 +53,7 @@ class AndroidDebugService {
return {}; return {};
} }
static Future<Map> getExifInterfaceMetadata(ImageEntry entry) async { static Future<Map> getExifInterfaceMetadata(AvesEntry entry) async {
try { try {
// return map with all data available from the `ExifInterface` library // return map with all data available from the `ExifInterface` library
final result = await platform.invokeMethod('getExifInterfaceMetadata', <String, dynamic>{ final result = await platform.invokeMethod('getExifInterfaceMetadata', <String, dynamic>{
@ -68,7 +68,7 @@ class AndroidDebugService {
return {}; return {};
} }
static Future<Map> getMediaMetadataRetrieverMetadata(ImageEntry entry) async { static Future<Map> getMediaMetadataRetrieverMetadata(AvesEntry entry) async {
try { try {
// return map with all data available from `MediaMetadataRetriever` // return map with all data available from `MediaMetadataRetriever`
final result = await platform.invokeMethod('getMediaMetadataRetrieverMetadata', <String, dynamic>{ final result = await platform.invokeMethod('getMediaMetadataRetrieverMetadata', <String, dynamic>{
@ -81,7 +81,7 @@ class AndroidDebugService {
return {}; return {};
} }
static Future<Map> getMetadataExtractorSummary(ImageEntry entry) async { static Future<Map> getMetadataExtractorSummary(AvesEntry entry) async {
try { try {
// return map with the mime type and tag count for each directory found by `metadata-extractor` // return map with the mime type and tag count for each directory found by `metadata-extractor`
final result = await platform.invokeMethod('getMetadataExtractorSummary', <String, dynamic>{ final result = await platform.invokeMethod('getMetadataExtractorSummary', <String, dynamic>{
@ -96,7 +96,7 @@ class AndroidDebugService {
return {}; return {};
} }
static Future<Map> getTiffStructure(ImageEntry entry) async { static Future<Map> getTiffStructure(AvesEntry entry) async {
if (entry.mimeType != MimeTypes.tiff) return {}; if (entry.mimeType != MimeTypes.tiff) return {};
try { try {

View file

@ -1,7 +1,7 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/services/image_file_service.dart'; import 'package:aves/services/image_file_service.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -26,7 +26,7 @@ class AppShortcutService {
return false; return false;
} }
static Future<void> pin(String label, ImageEntry entry, Set<CollectionFilter> filters) async { static Future<void> pin(String label, AvesEntry entry, Set<CollectionFilter> filters) async {
Uint8List iconBytes; Uint8List iconBytes;
if (entry != null) { if (entry != null) {
final size = entry.isVideo ? 0.0 : 256.0; final size = entry.isVideo ? 0.0 : 256.0;

View file

@ -3,7 +3,7 @@ import 'dart:convert';
import 'dart:math'; import 'dart:math';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/ref/mime_types.dart'; import 'package:aves/ref/mime_types.dart';
import 'package:aves/services/service_policy.dart'; import 'package:aves/services/service_policy.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -18,7 +18,7 @@ class ImageFileService {
static final StreamsChannel opChannel = StreamsChannel('deckers.thibault/aves/imageopstream'); static final StreamsChannel opChannel = StreamsChannel('deckers.thibault/aves/imageopstream');
static const double thumbnailDefaultSize = 64.0; static const double thumbnailDefaultSize = 64.0;
static Map<String, dynamic> _toPlatformEntryMap(ImageEntry entry) { static Map<String, dynamic> _toPlatformEntryMap(AvesEntry entry) {
return { return {
'uri': entry.uri, 'uri': entry.uri,
'path': entry.path, 'path': entry.path,
@ -32,13 +32,13 @@ class ImageFileService {
} }
// knownEntries: map of contentId -> dateModifiedSecs // knownEntries: map of contentId -> dateModifiedSecs
static Stream<ImageEntry> getImageEntries(Map<int, int> knownEntries) { static Stream<AvesEntry> getEntries(Map<int, int> knownEntries) {
try { try {
return mediaStoreChannel.receiveBroadcastStream(<String, dynamic>{ return mediaStoreChannel.receiveBroadcastStream(<String, dynamic>{
'knownEntries': knownEntries, 'knownEntries': knownEntries,
}).map((event) => ImageEntry.fromMap(event)); }).map((event) => AvesEntry.fromMap(event));
} on PlatformException catch (e) { } on PlatformException catch (e) {
debugPrint('getImageEntries failed with code=${e.code}, exception=${e.message}, details=${e.details}'); debugPrint('getEntries failed with code=${e.code}, exception=${e.message}, details=${e.details}');
return Stream.error(e); return Stream.error(e);
} }
} }
@ -55,16 +55,16 @@ class ImageFileService {
return []; return [];
} }
static Future<ImageEntry> getImageEntry(String uri, String mimeType) async { static Future<AvesEntry> getEntry(String uri, String mimeType) async {
debugPrint('getImageEntry for uri=$uri, mimeType=$mimeType'); debugPrint('getEntry for uri=$uri, mimeType=$mimeType');
try { try {
final result = await platform.invokeMethod('getImageEntry', <String, dynamic>{ final result = await platform.invokeMethod('getEntry', <String, dynamic>{
'uri': uri, 'uri': uri,
'mimeType': mimeType, 'mimeType': mimeType,
}) as Map; }) as Map;
return ImageEntry.fromMap(result); return AvesEntry.fromMap(result);
} on PlatformException catch (e) { } on PlatformException catch (e) {
debugPrint('getImageEntry failed with code=${e.code}, exception=${e.message}, details=${e.details}'); debugPrint('getEntry failed with code=${e.code}, exception=${e.message}, details=${e.details}');
} }
return null; return null;
} }
@ -224,7 +224,7 @@ class ImageFileService {
static Future<T> resumeLoading<T>(Object taskKey) => servicePolicy.resume<T>(taskKey); static Future<T> resumeLoading<T>(Object taskKey) => servicePolicy.resume<T>(taskKey);
static Stream<ImageOpEvent> delete(Iterable<ImageEntry> entries) { static Stream<ImageOpEvent> delete(Iterable<AvesEntry> entries) {
try { try {
return opChannel.receiveBroadcastStream(<String, dynamic>{ return opChannel.receiveBroadcastStream(<String, dynamic>{
'op': 'delete', 'op': 'delete',
@ -236,7 +236,7 @@ class ImageFileService {
} }
} }
static Stream<MoveOpEvent> move(Iterable<ImageEntry> entries, {@required bool copy, @required String destinationAlbum}) { static Stream<MoveOpEvent> move(Iterable<AvesEntry> entries, {@required bool copy, @required String destinationAlbum}) {
try { try {
return opChannel.receiveBroadcastStream(<String, dynamic>{ return opChannel.receiveBroadcastStream(<String, dynamic>{
'op': 'move', 'op': 'move',
@ -250,7 +250,7 @@ class ImageFileService {
} }
} }
static Future<Map> rename(ImageEntry entry, String newName) async { static Future<Map> rename(AvesEntry entry, String newName) async {
try { try {
// return map with: 'contentId' 'path' 'title' 'uri' (all optional) // return map with: 'contentId' 'path' 'title' 'uri' (all optional)
final result = await platform.invokeMethod('rename', <String, dynamic>{ final result = await platform.invokeMethod('rename', <String, dynamic>{
@ -264,7 +264,7 @@ class ImageFileService {
return {}; return {};
} }
static Future<Map> rotate(ImageEntry entry, {@required bool clockwise}) async { static Future<Map> rotate(AvesEntry entry, {@required bool clockwise}) async {
try { try {
// return map with: 'rotationDegrees' 'isFlipped' // return map with: 'rotationDegrees' 'isFlipped'
final result = await platform.invokeMethod('rotate', <String, dynamic>{ final result = await platform.invokeMethod('rotate', <String, dynamic>{
@ -278,7 +278,7 @@ class ImageFileService {
return {}; return {};
} }
static Future<Map> flip(ImageEntry entry) async { static Future<Map> flip(AvesEntry entry) async {
try { try {
// return map with: 'rotationDegrees' 'isFlipped' // return map with: 'rotationDegrees' 'isFlipped'
final result = await platform.invokeMethod('flip', <String, dynamic>{ final result = await platform.invokeMethod('flip', <String, dynamic>{

View file

@ -1,7 +1,7 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/metadata.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/model/panorama.dart'; import 'package:aves/model/panorama.dart';
import 'package:aves/services/service_policy.dart'; import 'package:aves/services/service_policy.dart';
@ -12,7 +12,7 @@ class MetadataService {
static const platform = MethodChannel('deckers.thibault/aves/metadata'); static const platform = MethodChannel('deckers.thibault/aves/metadata');
// return Map<Map<Key, Value>> (map of directories, each directory being a map of metadata label and value description) // return Map<Map<Key, Value>> (map of directories, each directory being a map of metadata label and value description)
static Future<Map> getAllMetadata(ImageEntry entry) async { static Future<Map> getAllMetadata(AvesEntry entry) async {
if (entry.isSvg) return null; if (entry.isSvg) return null;
try { try {
@ -28,7 +28,7 @@ class MetadataService {
return {}; return {};
} }
static Future<CatalogMetadata> getCatalogMetadata(ImageEntry entry, {bool background = false}) async { static Future<CatalogMetadata> getCatalogMetadata(AvesEntry entry, {bool background = false}) async {
if (entry.isSvg) return null; if (entry.isSvg) return null;
Future<CatalogMetadata> call() async { Future<CatalogMetadata> call() async {
@ -65,7 +65,7 @@ class MetadataService {
: call(); : call();
} }
static Future<OverlayMetadata> getOverlayMetadata(ImageEntry entry) async { static Future<OverlayMetadata> getOverlayMetadata(AvesEntry entry) async {
if (entry.isSvg) return null; if (entry.isSvg) return null;
try { try {
@ -82,7 +82,7 @@ class MetadataService {
return null; return null;
} }
static Future<MultiPageInfo> getMultiPageInfo(ImageEntry entry) async { static Future<MultiPageInfo> getMultiPageInfo(AvesEntry entry) async {
try { try {
final result = await platform.invokeMethod('getMultiPageInfo', <String, dynamic>{ final result = await platform.invokeMethod('getMultiPageInfo', <String, dynamic>{
'mimeType': entry.mimeType, 'mimeType': entry.mimeType,
@ -95,7 +95,7 @@ class MetadataService {
return null; return null;
} }
static Future<PanoramaInfo> getPanoramaInfo(ImageEntry entry) async { static Future<PanoramaInfo> getPanoramaInfo(AvesEntry entry) async {
try { try {
// return map with values for: // return map with values for:
// 'croppedAreaLeft' (int), 'croppedAreaTop' (int), 'croppedAreaWidth' (int), 'croppedAreaHeight' (int), // 'croppedAreaLeft' (int), 'croppedAreaTop' (int), 'croppedAreaWidth' (int), 'croppedAreaHeight' (int),
@ -124,7 +124,7 @@ class MetadataService {
return []; return [];
} }
static Future<List<Uint8List>> getExifThumbnails(ImageEntry entry) async { static Future<List<Uint8List>> getExifThumbnails(AvesEntry entry) async {
try { try {
final result = await platform.invokeMethod('getExifThumbnails', <String, dynamic>{ final result = await platform.invokeMethod('getExifThumbnails', <String, dynamic>{
'mimeType': entry.mimeType, 'mimeType': entry.mimeType,
@ -138,7 +138,7 @@ class MetadataService {
return []; return [];
} }
static Future<Map> extractXmpDataProp(ImageEntry entry, String propPath, String propMimeType) async { static Future<Map> extractXmpDataProp(AvesEntry entry, String propPath, String propMimeType) async {
try { try {
final result = await platform.invokeMethod('extractXmpDataProp', <String, dynamic>{ final result = await platform.invokeMethod('extractXmpDataProp', <String, dynamic>{
'mimeType': entry.mimeType, 'mimeType': entry.mimeType,

View file

@ -1,6 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/services/image_file_service.dart'; import 'package:aves/services/image_file_service.dart';
import 'package:aves/utils/string_utils.dart'; import 'package:aves/utils/string_utils.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -15,7 +15,7 @@ class SvgMetadataService {
static const _textElements = ['title', 'desc']; static const _textElements = ['title', 'desc'];
static const _metadataElement = 'metadata'; static const _metadataElement = 'metadata';
static Future<Size> getSize(ImageEntry entry) async { static Future<Size> getSize(AvesEntry entry) async {
try { try {
final data = await ImageFileService.getSvg(entry.uri, entry.mimeType); final data = await ImageFileService.getSvg(entry.uri, entry.mimeType);
@ -48,7 +48,7 @@ class SvgMetadataService {
return null; return null;
} }
static Future<Map<String, Map<String, String>>> getAllMetadata(ImageEntry entry) async { static Future<Map<String, Map<String, String>>> getAllMetadata(AvesEntry entry) async {
String formatKey(String key) { String formatKey(String key) {
switch (key) { switch (key) {
case 'desc': case 'desc':

View file

@ -2,7 +2,7 @@ import 'dart:async';
import 'package:aves/model/actions/collection_actions.dart'; import 'package:aves/model/actions/collection_actions.dart';
import 'package:aves/model/actions/entry_actions.dart'; import 'package:aves/model/actions/entry_actions.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/services/android_app_service.dart'; import 'package:aves/services/android_app_service.dart';
@ -22,7 +22,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
CollectionSource get source => collection.source; CollectionSource get source => collection.source;
Set<ImageEntry> get selection => collection.selection; Set<AvesEntry> get selection => collection.selection;
EntrySetActionDelegate({ EntrySetActionDelegate({
@required this.collection, @required this.collection,

View file

@ -1,4 +1,4 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/model/source/section_keys.dart'; import 'package:aves/model/source/section_keys.dart';
import 'package:aves/widgets/collection/grid/headers/any.dart'; import 'package:aves/widgets/collection/grid/headers/any.dart';
@ -6,7 +6,7 @@ import 'package:aves/widgets/common/grid/section_layout.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SectionedEntryListLayoutProvider extends SectionedListLayoutProvider<ImageEntry> { class SectionedEntryListLayoutProvider extends SectionedListLayoutProvider<AvesEntry> {
final CollectionLens collection; final CollectionLens collection;
const SectionedEntryListLayoutProvider({ const SectionedEntryListLayoutProvider({
@ -14,7 +14,7 @@ class SectionedEntryListLayoutProvider extends SectionedListLayoutProvider<Image
@required double scrollableWidth, @required double scrollableWidth,
@required int columnCount, @required int columnCount,
@required double tileExtent, @required double tileExtent,
@required Widget Function(ImageEntry entry) tileBuilder, @required Widget Function(AvesEntry entry) tileBuilder,
@required Widget child, @required Widget child,
}) : super( }) : super(
scrollableWidth: scrollableWidth, scrollableWidth: scrollableWidth,
@ -28,7 +28,7 @@ class SectionedEntryListLayoutProvider extends SectionedListLayoutProvider<Image
bool get showHeaders => collection.showHeaders; bool get showHeaders => collection.showHeaders;
@override @override
Map<SectionKey, List<ImageEntry>> get sections => collection.sections; Map<SectionKey, List<AvesEntry>> get sections => collection.sections;
@override @override
double getHeaderExtent(BuildContext context, SectionKey sectionKey) { double getHeaderExtent(BuildContext context, SectionKey sectionKey) {

View file

@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:math'; import 'dart:math';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/utils/math_utils.dart'; import 'package:aves/utils/math_utils.dart';
import 'package:aves/widgets/common/extensions/media_query.dart'; import 'package:aves/widgets/common/extensions/media_query.dart';
@ -39,7 +39,7 @@ class _GridSelectionGestureDetectorState extends State<GridSelectionGestureDetec
CollectionLens get collection => widget.collection; CollectionLens get collection => widget.collection;
List<ImageEntry> get entries => collection.sortedEntries; List<AvesEntry> get entries => collection.sortedEntries;
ScrollController get scrollController => widget.scrollController; ScrollController get scrollController => widget.scrollController;
@ -131,12 +131,12 @@ class _GridSelectionGestureDetectorState extends State<GridSelectionGestureDetec
} }
} }
ImageEntry _getEntryAt(Offset localPosition) { AvesEntry _getEntryAt(Offset localPosition) {
// as of Flutter v1.22.5, `hitTest` on the `ScrollView` render object works fine when it is static, // as of Flutter v1.22.5, `hitTest` on the `ScrollView` render object works fine when it is static,
// but when it is scrolling (through controller animation), result is incomplete and children are missing, // but when it is scrolling (through controller animation), result is incomplete and children are missing,
// so we use custom layout computation instead to find the entry. // so we use custom layout computation instead to find the entry.
final offset = Offset(0, scrollController.offset - appBarHeight) + localPosition; final offset = Offset(0, scrollController.offset - appBarHeight) + localPosition;
final sectionedListLayout = context.read<SectionedListLayout<ImageEntry>>(); final sectionedListLayout = context.read<SectionedListLayout<AvesEntry>>();
return sectionedListLayout.getItemAt(offset); return sectionedListLayout.getItemAt(offset);
} }

View file

@ -1,5 +1,5 @@
import 'package:aves/main.dart'; import 'package:aves/main.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/services/viewer_service.dart'; import 'package:aves/services/viewer_service.dart';
import 'package:aves/widgets/collection/thumbnail/decorated.dart'; import 'package:aves/widgets/collection/thumbnail/decorated.dart';
@ -10,7 +10,7 @@ import 'package:flutter/material.dart';
class InteractiveThumbnail extends StatelessWidget { class InteractiveThumbnail extends StatelessWidget {
final CollectionLens collection; final CollectionLens collection;
final ImageEntry entry; final AvesEntry entry;
final double tileExtent; final double tileExtent;
final ValueNotifier<bool> isScrollingNotifier; final ValueNotifier<bool> isScrollingNotifier;

View file

@ -1,4 +1,4 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/widgets/collection/thumbnail/overlay.dart'; import 'package:aves/widgets/collection/thumbnail/overlay.dart';
import 'package:aves/widgets/collection/thumbnail/raster.dart'; import 'package:aves/widgets/collection/thumbnail/raster.dart';
@ -6,7 +6,7 @@ import 'package:aves/widgets/collection/thumbnail/vector.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DecoratedThumbnail extends StatelessWidget { class DecoratedThumbnail extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final double extent; final double extent;
final CollectionLens collection; final CollectionLens collection;
final ValueNotifier<bool> isScrollingNotifier; final ValueNotifier<bool> isScrollingNotifier;

View file

@ -1,9 +1,9 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/utils/mime_utils.dart'; import 'package:aves/utils/mime_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class ErrorThumbnail extends StatelessWidget { class ErrorThumbnail extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final double extent; final double extent;
final String tooltip; final String tooltip;

View file

@ -1,7 +1,7 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/model/highlight.dart'; import 'package:aves/model/highlight.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/model/source/enums.dart'; import 'package:aves/model/source/enums.dart';
@ -14,7 +14,7 @@ import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class ThumbnailEntryOverlay extends StatelessWidget { class ThumbnailEntryOverlay extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final double extent; final double extent;
const ThumbnailEntryOverlay({ const ThumbnailEntryOverlay({
@ -61,7 +61,7 @@ class ThumbnailEntryOverlay extends StatelessWidget {
} }
class ThumbnailSelectionOverlay extends StatelessWidget { class ThumbnailSelectionOverlay extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final double extent; final double extent;
const ThumbnailSelectionOverlay({ const ThumbnailSelectionOverlay({
@ -121,7 +121,7 @@ class ThumbnailSelectionOverlay extends StatelessWidget {
} }
class ThumbnailHighlightOverlay extends StatefulWidget { class ThumbnailHighlightOverlay extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
final double extent; final double extent;
const ThumbnailHighlightOverlay({ const ThumbnailHighlightOverlay({
@ -137,7 +137,7 @@ class ThumbnailHighlightOverlay extends StatefulWidget {
class _ThumbnailHighlightOverlayState extends State<ThumbnailHighlightOverlay> { class _ThumbnailHighlightOverlayState extends State<ThumbnailHighlightOverlay> {
final ValueNotifier<bool> _highlightedNotifier = ValueNotifier(false); final ValueNotifier<bool> _highlightedNotifier = ValueNotifier(false);
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -1,13 +1,13 @@
import 'package:aves/image_providers/thumbnail_provider.dart'; import 'package:aves/image_providers/thumbnail_provider.dart';
import 'package:aves/model/entry.dart';
import 'package:aves/model/entry_images.dart'; import 'package:aves/model/entry_images.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/widgets/collection/thumbnail/error.dart'; import 'package:aves/widgets/collection/thumbnail/error.dart';
import 'package:aves/widgets/common/fx/transition_image.dart'; import 'package:aves/widgets/common/fx/transition_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class RasterImageThumbnail extends StatefulWidget { class RasterImageThumbnail extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
final double extent; final double extent;
final int page; final int page;
final ValueNotifier<bool> isScrollingNotifier; final ValueNotifier<bool> isScrollingNotifier;
@ -29,7 +29,7 @@ class RasterImageThumbnail extends StatefulWidget {
class _RasterImageThumbnailState extends State<RasterImageThumbnail> { class _RasterImageThumbnailState extends State<RasterImageThumbnail> {
ThumbnailProvider _fastThumbnailProvider, _sizedThumbnailProvider; ThumbnailProvider _fastThumbnailProvider, _sizedThumbnailProvider;
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
double get extent => widget.extent; double get extent => widget.extent;

View file

@ -1,5 +1,5 @@
import 'package:aves/image_providers/uri_picture_provider.dart'; import 'package:aves/image_providers/uri_picture_provider.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/settings/entry_background.dart'; import 'package:aves/model/settings/entry_background.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/widgets/common/fx/checkered_decoration.dart'; import 'package:aves/widgets/common/fx/checkered_decoration.dart';
@ -8,7 +8,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class VectorImageThumbnail extends StatelessWidget { class VectorImageThumbnail extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final double extent; final double extent;
final Object heroTag; final Object heroTag;

View file

@ -4,7 +4,7 @@ import 'package:aves/main.dart';
import 'package:aves/model/filters/favourite.dart'; import 'package:aves/model/filters/favourite.dart';
import 'package:aves/model/filters/mime.dart'; import 'package:aves/model/filters/mime.dart';
import 'package:aves/model/highlight.dart'; import 'package:aves/model/highlight.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/ref/mime_types.dart'; import 'package:aves/ref/mime_types.dart';
@ -82,7 +82,7 @@ class ThumbnailCollection extends StatelessWidget {
), ),
); );
final scaler = GridScaleGestureDetector<ImageEntry>( final scaler = GridScaleGestureDetector<AvesEntry>(
tileExtentManager: tileExtentManager, tileExtentManager: tileExtentManager,
scrollableKey: _scrollableKey, scrollableKey: _scrollableKey,
appBarHeightNotifier: _appBarHeightNotifier, appBarHeightNotifier: _appBarHeightNotifier,
@ -106,7 +106,7 @@ class ThumbnailCollection extends StatelessWidget {
highlightable: false, highlightable: false,
), ),
getScaledItemTileRect: (context, entry) { getScaledItemTileRect: (context, entry) {
final sectionedListLayout = context.read<SectionedListLayout<ImageEntry>>(); final sectionedListLayout = context.read<SectionedListLayout<AvesEntry>>();
return sectionedListLayout.getTileRect(entry) ?? Rect.zero; return sectionedListLayout.getTileRect(entry) ?? Rect.zero;
}, },
onScaled: (entry) => Provider.of<HighlightInfo>(context, listen: false).add(entry), onScaled: (entry) => Provider.of<HighlightInfo>(context, listen: false).add(entry),
@ -225,7 +225,7 @@ class _CollectionScrollViewState extends State<CollectionScrollView> {
child: _buildEmptyCollectionPlaceholder(collection), child: _buildEmptyCollectionPlaceholder(collection),
hasScrollBody: false, hasScrollBody: false,
) )
: SectionedListSliver<ImageEntry>(), : SectionedListSliver<AvesEntry>(),
BottomPaddingSliver(), BottomPaddingSliver(),
], ],
); );

View file

@ -1,4 +1,4 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/services/image_file_service.dart'; import 'package:aves/services/image_file_service.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:flushbar/flushbar.dart'; import 'package:flushbar/flushbar.dart';
@ -31,7 +31,7 @@ mixin FeedbackMixin {
void showOpReport<T extends ImageOpEvent>({ void showOpReport<T extends ImageOpEvent>({
@required BuildContext context, @required BuildContext context,
@required Set<ImageEntry> selection, @required Set<AvesEntry> selection,
@required Stream<T> opStream, @required Stream<T> opStream,
@required void Function(Set<T> processed) onDone, @required void Function(Set<T> processed) onDone,
}) { }) {

View file

@ -1,10 +1,10 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/services/android_file_service.dart'; import 'package:aves/services/android_file_service.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
mixin PermissionAwareMixin { mixin PermissionAwareMixin {
Future<bool> checkStoragePermission(BuildContext context, Set<ImageEntry> entries) { Future<bool> checkStoragePermission(BuildContext context, Set<AvesEntry> entries) {
return checkStoragePermissionForAlbums(context, entries.where((e) => e.path != null).map((e) => e.directory).toSet()); return checkStoragePermissionForAlbums(context, entries.where((e) => e.path != null).map((e) => e.directory).toSet());
} }

View file

@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:math'; import 'dart:math';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/services/android_file_service.dart'; import 'package:aves/services/android_file_service.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/file_utils.dart'; import 'package:aves/utils/file_utils.dart';
@ -11,7 +11,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
mixin SizeAwareMixin { mixin SizeAwareMixin {
Future<bool> checkFreeSpaceForMove(BuildContext context, Set<ImageEntry> selection, String destinationAlbum, bool copy) async { Future<bool> checkFreeSpaceForMove(BuildContext context, Set<AvesEntry> selection, String destinationAlbum, bool copy) async {
final destinationVolume = androidFileUtils.getStorageVolume(destinationAlbum); final destinationVolume = androidFileUtils.getStorageVolume(destinationAlbum);
final free = await AndroidFileService.getFreeSpace(destinationVolume); final free = await AndroidFileService.getFreeSpace(destinationVolume);
int needed; int needed;
@ -20,7 +20,7 @@ mixin SizeAwareMixin {
needed = selection.fold(0, sumSize); needed = selection.fold(0, sumSize);
} else { } else {
// when moving, we only need space for the entries that are not already on the destination volume // when moving, we only need space for the entries that are not already on the destination volume
final byVolume = groupBy<ImageEntry, StorageVolume>(selection, (entry) => androidFileUtils.getStorageVolume(entry.path)); final byVolume = groupBy<AvesEntry, StorageVolume>(selection, (entry) => androidFileUtils.getStorageVolume(entry.path));
final otherVolumes = byVolume.keys.where((volume) => volume != destinationVolume); final otherVolumes = byVolume.keys.where((volume) => volume != destinationVolume);
final fromOtherVolumes = otherVolumes.fold<int>(0, (sum, volume) => sum + byVolume[volume].fold(0, sumSize)); final fromOtherVolumes = otherVolumes.fold<int>(0, (sum, volume) => sum + byVolume[volume].fold(0, sumSize));
// and we need at least as much space as the largest entry because individual entries are copied then deleted // and we need at least as much space as the largest entry because individual entries are copied then deleted

View file

@ -1,7 +1,7 @@
import 'dart:ui'; import 'dart:ui';
import 'package:aves/image_providers/app_icon_image_provider.dart'; import 'package:aves/image_providers/app_icon_image_provider.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
@ -9,7 +9,7 @@ import 'package:decorated_icon/decorated_icon.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class VideoIcon extends StatelessWidget { class VideoIcon extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final double iconSize; final double iconSize;
final bool showDuration; final bool showDuration;

View file

@ -1,4 +1,4 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
@ -26,7 +26,7 @@ class AppDebugPage extends StatefulWidget {
} }
class _AppDebugPageState extends State<AppDebugPage> { class _AppDebugPageState extends State<AppDebugPage> {
List<ImageEntry> get entries => widget.source.rawEntries; List<AvesEntry> get entries => widget.source.rawEntries;
static OverlayEntry _taskQueueOverlayEntry; static OverlayEntry _taskQueueOverlayEntry;

View file

@ -1,6 +1,6 @@
import 'package:aves/model/entry.dart';
import 'package:aves/model/favourite_repo.dart'; import 'package:aves/model/favourite_repo.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/metadata.dart';
import 'package:aves/model/image_metadata.dart';
import 'package:aves/model/metadata_db.dart'; import 'package:aves/model/metadata_db.dart';
import 'package:aves/utils/file_utils.dart'; import 'package:aves/utils/file_utils.dart';
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
@ -13,7 +13,7 @@ class DebugAppDatabaseSection extends StatefulWidget {
class _DebugAppDatabaseSectionState extends State<DebugAppDatabaseSection> with AutomaticKeepAliveClientMixin { class _DebugAppDatabaseSectionState extends State<DebugAppDatabaseSection> with AutomaticKeepAliveClientMixin {
Future<int> _dbFileSizeLoader; Future<int> _dbFileSizeLoader;
Future<List<ImageEntry>> _dbEntryLoader; Future<List<AvesEntry>> _dbEntryLoader;
Future<List<DateMetadata>> _dbDateLoader; Future<List<DateMetadata>> _dbDateLoader;
Future<List<CatalogMetadata>> _dbMetadataLoader; Future<List<CatalogMetadata>> _dbMetadataLoader;
Future<List<AddressDetails>> _dbAddressLoader; Future<List<AddressDetails>> _dbAddressLoader;

View file

@ -1,13 +1,13 @@
import 'dart:io'; import 'dart:io';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'aves_dialog.dart'; import 'aves_dialog.dart';
class RenameEntryDialog extends StatefulWidget { class RenameEntryDialog extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
const RenameEntryDialog(this.entry); const RenameEntryDialog(this.entry);
@ -19,7 +19,7 @@ class _RenameEntryDialogState extends State<RenameEntryDialog> {
final TextEditingController _nameController = TextEditingController(); final TextEditingController _nameController = TextEditingController();
final ValueNotifier<bool> _isValidNotifier = ValueNotifier(false); final ValueNotifier<bool> _isValidNotifier = ValueNotifier(false);
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
@override @override
void initState() { void initState() {

View file

@ -3,7 +3,7 @@ import 'dart:ui';
import 'package:aves/model/filters/album.dart'; import 'package:aves/model/filters/album.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
@ -20,7 +20,7 @@ import 'package:flutter/material.dart';
class DecoratedFilterChip extends StatelessWidget { class DecoratedFilterChip extends StatelessWidget {
final CollectionSource source; final CollectionSource source;
final CollectionFilter filter; final CollectionFilter filter;
final ImageEntry entry; final AvesEntry entry;
final double extent; final double extent;
final bool pinned, highlightable; final bool pinned, highlightable;
final FilterCallback onTap; final FilterCallback onTap;

View file

@ -1,6 +1,6 @@
import 'package:aves/main.dart'; import 'package:aves/main.dart';
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/model/settings/home_page.dart'; import 'package:aves/model/settings/home_page.dart';
import 'package:aves/model/settings/screen_on.dart'; import 'package:aves/model/settings/screen_on.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
@ -35,7 +35,7 @@ class HomePage extends StatefulWidget {
class _HomePageState extends State<HomePage> { class _HomePageState extends State<HomePage> {
MediaStoreSource _mediaStore; MediaStoreSource _mediaStore;
ImageEntry _viewerEntry; AvesEntry _viewerEntry;
String _shortcutRouteName; String _shortcutRouteName;
List<String> _shortcutFilters; List<String> _shortcutFilters;
@ -108,8 +108,8 @@ class _HomePageState extends State<HomePage> {
unawaited(Navigator.pushReplacement(context, _getRedirectRoute())); unawaited(Navigator.pushReplacement(context, _getRedirectRoute()));
} }
Future<ImageEntry> _initViewerEntry({@required String uri, @required String mimeType}) async { Future<AvesEntry> _initViewerEntry({@required String uri, @required String mimeType}) async {
final entry = await ImageFileService.getImageEntry(uri, mimeType); final entry = await ImageFileService.getEntry(uri, mimeType);
if (entry != null) { if (entry != null) {
// cataloguing is essential for geolocation and video rotation // cataloguing is essential for geolocation and video rotation
await entry.catalog(); await entry.catalog();

View file

@ -4,7 +4,7 @@ import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/filters/location.dart'; import 'package:aves/model/filters/location.dart';
import 'package:aves/model/filters/mime.dart'; import 'package:aves/model/filters/mime.dart';
import 'package:aves/model/filters/tag.dart'; import 'package:aves/model/filters/tag.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
@ -30,7 +30,7 @@ class StatsPage extends StatelessWidget {
final CollectionLens parentCollection; final CollectionLens parentCollection;
final Map<String, int> entryCountPerCountry = {}, entryCountPerPlace = {}, entryCountPerTag = {}; final Map<String, int> entryCountPerCountry = {}, entryCountPerPlace = {}, entryCountPerTag = {};
List<ImageEntry> get entries => parentCollection?.sortedEntries ?? source.rawEntries; List<AvesEntry> get entries => parentCollection?.sortedEntries ?? source.rawEntries;
static const mimeDonutMinWidth = 124.0; static const mimeDonutMinWidth = 124.0;
@ -66,7 +66,7 @@ class StatsPage extends StatelessWidget {
text: 'No images', text: 'No images',
); );
} else { } else {
final byMimeTypes = groupBy<ImageEntry, String>(entries, (entry) => entry.mimeType).map<String, int>((k, v) => MapEntry(k, v.length)); final byMimeTypes = groupBy<AvesEntry, String>(entries, (entry) => entry.mimeType).map<String, int>((k, v) => MapEntry(k, v.length));
final imagesByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('image/'))); final imagesByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('image/')));
final videoByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('video/'))); final videoByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('video/')));
final mimeDonuts = Wrap( final mimeDonuts = Wrap(

View file

@ -1,11 +1,11 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/metadata.dart';
import 'package:aves/model/metadata_db.dart'; import 'package:aves/model/metadata_db.dart';
import 'package:aves/widgets/viewer/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DbTab extends StatefulWidget { class DbTab extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
const DbTab({@required this.entry}); const DbTab({@required this.entry});
@ -15,11 +15,11 @@ class DbTab extends StatefulWidget {
class _DbTabState extends State<DbTab> { class _DbTabState extends State<DbTab> {
Future<DateMetadata> _dbDateLoader; Future<DateMetadata> _dbDateLoader;
Future<ImageEntry> _dbEntryLoader; Future<AvesEntry> _dbEntryLoader;
Future<CatalogMetadata> _dbMetadataLoader; Future<CatalogMetadata> _dbMetadataLoader;
Future<AddressDetails> _dbAddressLoader; Future<AddressDetails> _dbAddressLoader;
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
@override @override
void initState() { void initState() {
@ -60,7 +60,7 @@ class _DbTabState extends State<DbTab> {
}, },
), ),
SizedBox(height: 16), SizedBox(height: 16),
FutureBuilder<ImageEntry>( FutureBuilder<AvesEntry>(
future: _dbEntryLoader, future: _dbEntryLoader,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());

View file

@ -1,7 +1,7 @@
import 'dart:collection'; import 'dart:collection';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/ref/mime_types.dart'; import 'package:aves/ref/mime_types.dart';
import 'package:aves/services/android_debug_service.dart'; import 'package:aves/services/android_debug_service.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
@ -10,7 +10,7 @@ import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MetadataTab extends StatefulWidget { class MetadataTab extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
const MetadataTab({@required this.entry}); const MetadataTab({@required this.entry});
@ -25,7 +25,7 @@ class _MetadataTabState extends State<MetadataTab> {
static const secondTimestampKeys = ['date_added', 'date_modified', 'date_expires', 'isPlayed']; static const secondTimestampKeys = ['date_added', 'date_modified', 'date_expires', 'isPlayed'];
static const millisecondTimestampKeys = ['datetaken', 'datetime']; static const millisecondTimestampKeys = ['datetaken', 'datetime'];
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
@override @override
void initState() { void initState() {

View file

@ -1,7 +1,7 @@
import 'package:aves/image_providers/uri_picture_provider.dart'; import 'package:aves/image_providers/uri_picture_provider.dart';
import 'package:aves/main.dart'; import 'package:aves/main.dart';
import 'package:aves/model/entry_images.dart'; import 'package:aves/model/entry_images.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/viewer/debug/db.dart'; import 'package:aves/widgets/viewer/debug/db.dart';
import 'package:aves/widgets/viewer/debug/metadata.dart'; import 'package:aves/widgets/viewer/debug/metadata.dart';
@ -13,7 +13,7 @@ import 'package:tuple/tuple.dart';
class ViewerDebugPage extends StatelessWidget { class ViewerDebugPage extends StatelessWidget {
static const routeName = '/viewer/debug'; static const routeName = '/viewer/debug';
final ImageEntry entry; final AvesEntry entry;
const ViewerDebugPage({@required this.entry}); const ViewerDebugPage({@required this.entry});

View file

@ -1,7 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:aves/model/actions/entry_actions.dart'; import 'package:aves/model/actions/entry_actions.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/services/android_app_service.dart'; import 'package:aves/services/android_app_service.dart';
import 'package:aves/services/image_file_service.dart'; import 'package:aves/services/image_file_service.dart';
@ -28,7 +28,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin {
bool get hasCollection => collection != null; bool get hasCollection => collection != null;
void onActionSelected(BuildContext context, ImageEntry entry, EntryAction action) { void onActionSelected(BuildContext context, AvesEntry entry, EntryAction action) {
switch (action) { switch (action) {
case EntryAction.toggleFavourite: case EntryAction.toggleFavourite:
entry.toggleFavourite(); entry.toggleFavourite();
@ -88,21 +88,21 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin {
} }
} }
Future<void> _flip(BuildContext context, ImageEntry entry) async { Future<void> _flip(BuildContext context, AvesEntry entry) async {
if (!await checkStoragePermission(context, {entry})) return; if (!await checkStoragePermission(context, {entry})) return;
final success = await entry.flip(); final success = await entry.flip();
if (!success) showFeedback(context, 'Failed'); if (!success) showFeedback(context, 'Failed');
} }
Future<void> _rotate(BuildContext context, ImageEntry entry, {@required bool clockwise}) async { Future<void> _rotate(BuildContext context, AvesEntry entry, {@required bool clockwise}) async {
if (!await checkStoragePermission(context, {entry})) return; if (!await checkStoragePermission(context, {entry})) return;
final success = await entry.rotate(clockwise: clockwise); final success = await entry.rotate(clockwise: clockwise);
if (!success) showFeedback(context, 'Failed'); if (!success) showFeedback(context, 'Failed');
} }
Future<void> _showDeleteDialog(BuildContext context, ImageEntry entry) async { Future<void> _showDeleteDialog(BuildContext context, AvesEntry entry) async {
final confirmed = await showDialog<bool>( final confirmed = await showDialog<bool>(
context: context, context: context,
builder: (context) { builder: (context) {
@ -140,7 +140,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin {
} }
} }
Future<void> _showRenameDialog(BuildContext context, ImageEntry entry) async { Future<void> _showRenameDialog(BuildContext context, AvesEntry entry) async {
final newName = await showDialog<String>( final newName = await showDialog<String>(
context: context, context: context,
builder: (context) => RenameEntryDialog(entry), builder: (context) => RenameEntryDialog(entry),
@ -152,7 +152,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin {
showFeedback(context, await entry.rename(newName) ? 'Done!' : 'Failed'); showFeedback(context, await entry.rename(newName) ? 'Done!' : 'Failed');
} }
void _goToSourceViewer(BuildContext context, ImageEntry entry) { void _goToSourceViewer(BuildContext context, AvesEntry entry) {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
@ -164,7 +164,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin {
); );
} }
void _goToDebug(BuildContext context, ImageEntry entry) { void _goToDebug(BuildContext context, AvesEntry entry) {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(

View file

@ -1,4 +1,4 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/widgets/common/magnifier/pan/gesture_detector_scope.dart'; import 'package:aves/widgets/common/magnifier/pan/gesture_detector_scope.dart';
@ -34,7 +34,7 @@ class MultiEntryScroller extends StatefulWidget {
} }
class _MultiEntryScrollerState extends State<MultiEntryScroller> with AutomaticKeepAliveClientMixin { class _MultiEntryScrollerState extends State<MultiEntryScroller> with AutomaticKeepAliveClientMixin {
List<ImageEntry> get entries => widget.collection.sortedEntries; List<AvesEntry> get entries => widget.collection.sortedEntries;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -80,7 +80,7 @@ class _MultiEntryScrollerState extends State<MultiEntryScroller> with AutomaticK
); );
} }
Widget _buildViewer(ImageEntry entry, {MultiPageInfo multiPageInfo, int page}) { Widget _buildViewer(AvesEntry entry, {MultiPageInfo multiPageInfo, int page}) {
return Selector<MediaQueryData, Size>( return Selector<MediaQueryData, Size>(
selector: (c, mq) => mq.size, selector: (c, mq) => mq.size,
builder: (c, mqSize, child) { builder: (c, mqSize, child) {
@ -99,7 +99,7 @@ class _MultiEntryScrollerState extends State<MultiEntryScroller> with AutomaticK
); );
} }
MultiPageController _getMultiPageController(ImageEntry entry) { MultiPageController _getMultiPageController(AvesEntry entry) {
return widget.multiPageControllers.firstWhere((kv) => kv.item1 == entry.uri, orElse: () => null)?.item2; return widget.multiPageControllers.firstWhere((kv) => kv.item1 == entry.uri, orElse: () => null)?.item2;
} }
@ -108,7 +108,7 @@ class _MultiEntryScrollerState extends State<MultiEntryScroller> with AutomaticK
} }
class SingleEntryScroller extends StatefulWidget { class SingleEntryScroller extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
final VoidCallback onTap; final VoidCallback onTap;
final List<Tuple2<String, IjkMediaController>> videoControllers; final List<Tuple2<String, IjkMediaController>> videoControllers;
final List<Tuple2<String, MultiPageController>> multiPageControllers; final List<Tuple2<String, MultiPageController>> multiPageControllers;
@ -125,7 +125,7 @@ class SingleEntryScroller extends StatefulWidget {
} }
class _SingleEntryScrollerState extends State<SingleEntryScroller> with AutomaticKeepAliveClientMixin { class _SingleEntryScrollerState extends State<SingleEntryScroller> with AutomaticKeepAliveClientMixin {
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -173,7 +173,7 @@ class _SingleEntryScrollerState extends State<SingleEntryScroller> with Automati
); );
} }
MultiPageController _getMultiPageController(ImageEntry entry) { MultiPageController _getMultiPageController(AvesEntry entry) {
return widget.multiPageControllers.firstWhere((kv) => kv.item1 == entry.uri, orElse: () => null)?.item2; return widget.multiPageControllers.firstWhere((kv) => kv.item1 == entry.uri, orElse: () => null)?.item2;
} }

View file

@ -1,4 +1,4 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
import 'package:aves/widgets/viewer/entry_viewer_stack.dart'; import 'package:aves/widgets/viewer/entry_viewer_stack.dart';
@ -8,7 +8,7 @@ class MultiEntryViewerPage extends AnimatedWidget {
static const routeName = '/viewer'; static const routeName = '/viewer';
final CollectionLens collection; final CollectionLens collection;
final ImageEntry initialEntry; final AvesEntry initialEntry;
const MultiEntryViewerPage({ const MultiEntryViewerPage({
Key key, Key key,
@ -34,7 +34,7 @@ class MultiEntryViewerPage extends AnimatedWidget {
class SingleEntryViewerPage extends StatelessWidget { class SingleEntryViewerPage extends StatelessWidget {
static const routeName = '/viewer'; static const routeName = '/viewer';
final ImageEntry entry; final AvesEntry entry;
const SingleEntryViewerPage({ const SingleEntryViewerPage({
Key key, Key key,

View file

@ -1,7 +1,7 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/settings/screen_on.dart'; import 'package:aves/model/settings/screen_on.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
@ -31,7 +31,7 @@ import 'package:tuple/tuple.dart';
class EntryViewerStack extends StatefulWidget { class EntryViewerStack extends StatefulWidget {
final CollectionLens collection; final CollectionLens collection;
final ImageEntry initialEntry; final AvesEntry initialEntry;
const EntryViewerStack({ const EntryViewerStack({
Key key, Key key,
@ -44,7 +44,7 @@ class EntryViewerStack extends StatefulWidget {
} }
class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerProviderStateMixin, WidgetsBindingObserver { class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerProviderStateMixin, WidgetsBindingObserver {
final ValueNotifier<ImageEntry> _entryNotifier = ValueNotifier(null); final ValueNotifier<AvesEntry> _entryNotifier = ValueNotifier(null);
int _currentHorizontalPage; int _currentHorizontalPage;
ValueNotifier<int> _currentVerticalPage; ValueNotifier<int> _currentVerticalPage;
PageController _horizontalPager, _verticalPager; PageController _horizontalPager, _verticalPager;
@ -63,7 +63,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
bool get hasCollection => collection != null; bool get hasCollection => collection != null;
List<ImageEntry> get entries => hasCollection ? collection.sortedEntries : [widget.initialEntry]; List<AvesEntry> get entries => hasCollection ? collection.sortedEntries : [widget.initialEntry];
static const int transitionPage = 0; static const int transitionPage = 0;
@ -199,7 +199,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
} }
Widget _buildTopOverlay() { Widget _buildTopOverlay() {
final child = ValueListenableBuilder<ImageEntry>( final child = ValueListenableBuilder<AvesEntry>(
valueListenable: _entryNotifier, valueListenable: _entryNotifier,
builder: (context, entry, child) { builder: (context, entry, child) {
if (entry == null) return SizedBox.shrink(); if (entry == null) return SizedBox.shrink();
@ -232,7 +232,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
} }
Widget _buildBottomOverlay() { Widget _buildBottomOverlay() {
Widget bottomOverlay = ValueListenableBuilder<ImageEntry>( Widget bottomOverlay = ValueListenableBuilder<AvesEntry>(
valueListenable: _entryNotifier, valueListenable: _entryNotifier,
builder: (context, entry, child) { builder: (context, entry, child) {
if (entry == null) return SizedBox.shrink(); if (entry == null) return SizedBox.shrink();
@ -312,7 +312,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
return bottomOverlay; return bottomOverlay;
} }
MultiPageController _getMultiPageController(ImageEntry entry) { MultiPageController _getMultiPageController(AvesEntry entry) {
return entry.isMultipage ? _multiPageControllers.firstWhere((kv) => kv.item1 == entry.uri, orElse: () => null)?.item2 : null; return entry.isMultipage ? _multiPageControllers.firstWhere((kv) => kv.item1 == entry.uri, orElse: () => null)?.item2 : null;
} }
@ -478,7 +478,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
class ViewerVerticalPageView extends StatefulWidget { class ViewerVerticalPageView extends StatefulWidget {
final CollectionLens collection; final CollectionLens collection;
final ValueNotifier<ImageEntry> entryNotifier; final ValueNotifier<AvesEntry> entryNotifier;
final List<Tuple2<String, IjkMediaController>> videoControllers; final List<Tuple2<String, IjkMediaController>> videoControllers;
final List<Tuple2<String, MultiPageController>> multiPageControllers; final List<Tuple2<String, MultiPageController>> multiPageControllers;
final PageController horizontalPager, verticalPager; final PageController horizontalPager, verticalPager;
@ -507,13 +507,13 @@ class ViewerVerticalPageView extends StatefulWidget {
class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> { class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
final ValueNotifier<Color> _backgroundColorNotifier = ValueNotifier(Colors.black); final ValueNotifier<Color> _backgroundColorNotifier = ValueNotifier(Colors.black);
final ValueNotifier<bool> _infoPageVisibleNotifier = ValueNotifier(false); final ValueNotifier<bool> _infoPageVisibleNotifier = ValueNotifier(false);
ImageEntry _oldEntry; AvesEntry _oldEntry;
CollectionLens get collection => widget.collection; CollectionLens get collection => widget.collection;
bool get hasCollection => collection != null; bool get hasCollection => collection != null;
ImageEntry get entry => widget.entryNotifier.value; AvesEntry get entry => widget.entryNotifier.value;
@override @override
void initState() { void initState() {

View file

@ -3,7 +3,7 @@ import 'package:aves/model/filters/album.dart';
import 'package:aves/model/filters/favourite.dart'; import 'package:aves/model/filters/favourite.dart';
import 'package:aves/model/filters/mime.dart'; import 'package:aves/model/filters/mime.dart';
import 'package:aves/model/filters/tag.dart'; import 'package:aves/model/filters/tag.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/ref/mime_types.dart'; import 'package:aves/ref/mime_types.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
@ -15,7 +15,7 @@ import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
class BasicSection extends StatelessWidget { class BasicSection extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final CollectionLens collection; final CollectionLens collection;
final FilterCallback onFilter; final FilterCallback onFilter;

View file

@ -1,4 +1,4 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/app_bar_title.dart'; import 'package:aves/widgets/common/app_bar_title.dart';
import 'package:aves/widgets/viewer/info/info_search.dart'; import 'package:aves/widgets/viewer/info/info_search.dart';
@ -6,7 +6,7 @@ import 'package:aves/widgets/viewer/info/metadata/metadata_section.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class InfoAppBar extends StatelessWidget { class InfoAppBar extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final ValueNotifier<Map<String, MetadataDirectory>> metadataNotifier; final ValueNotifier<Map<String, MetadataDirectory>> metadataNotifier;
final VoidCallback onBackPressed; final VoidCallback onBackPressed;

View file

@ -1,5 +1,5 @@
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/widgets/common/basic/insets.dart'; import 'package:aves/widgets/common/basic/insets.dart';
@ -14,7 +14,7 @@ import 'package:provider/provider.dart';
class InfoPage extends StatefulWidget { class InfoPage extends StatefulWidget {
final CollectionLens collection; final CollectionLens collection;
final ValueNotifier<ImageEntry> entryNotifier; final ValueNotifier<AvesEntry> entryNotifier;
final ValueNotifier<bool> visibleNotifier; final ValueNotifier<bool> visibleNotifier;
const InfoPage({ const InfoPage({
@ -34,7 +34,7 @@ class _InfoPageState extends State<InfoPage> {
CollectionLens get collection => widget.collection; CollectionLens get collection => widget.collection;
ImageEntry get entry => widget.entryNotifier.value; AvesEntry get entry => widget.entryNotifier.value;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -48,7 +48,7 @@ class _InfoPageState extends State<InfoPage> {
child: Selector<MediaQueryData, double>( child: Selector<MediaQueryData, double>(
selector: (c, mq) => mq.size.width, selector: (c, mq) => mq.size.width,
builder: (c, mqWidth, child) { builder: (c, mqWidth, child) {
return ValueListenableBuilder<ImageEntry>( return ValueListenableBuilder<AvesEntry>(
valueListenable: widget.entryNotifier, valueListenable: widget.entryNotifier,
builder: (context, entry, child) { builder: (context, entry, child) {
return entry != null return entry != null
@ -107,7 +107,7 @@ class _InfoPageState extends State<InfoPage> {
class _InfoPageContent extends StatefulWidget { class _InfoPageContent extends StatefulWidget {
final CollectionLens collection; final CollectionLens collection;
final ImageEntry entry; final AvesEntry entry;
final ValueNotifier<bool> visibleNotifier; final ValueNotifier<bool> visibleNotifier;
final ScrollController scrollController; final ScrollController scrollController;
final bool split; final bool split;
@ -134,7 +134,7 @@ class _InfoPageContentState extends State<_InfoPageContent> {
CollectionLens get collection => widget.collection; CollectionLens get collection => widget.collection;
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -1,4 +1,4 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/collection/empty.dart'; import 'package:aves/widgets/collection/empty.dart';
import 'package:aves/widgets/viewer/info/metadata/metadata_dir_tile.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_dir_tile.dart';
@ -7,7 +7,7 @@ import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class InfoSearchDelegate extends SearchDelegate { class InfoSearchDelegate extends SearchDelegate {
final ImageEntry entry; final AvesEntry entry;
final ValueNotifier<Map<String, MetadataDirectory>> metadataNotifier; final ValueNotifier<Map<String, MetadataDirectory>> metadataNotifier;
Map<String, MetadataDirectory> get metadata => metadataNotifier.value; Map<String, MetadataDirectory> get metadata => metadataNotifier.value;

View file

@ -1,5 +1,5 @@
import 'package:aves/model/filters/location.dart'; import 'package:aves/model/filters/location.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/settings/coordinate_format.dart'; import 'package:aves/model/settings/coordinate_format.dart';
import 'package:aves/model/settings/map_style.dart'; import 'package:aves/model/settings/map_style.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
@ -17,7 +17,7 @@ import 'package:tuple/tuple.dart';
class LocationSection extends StatefulWidget { class LocationSection extends StatefulWidget {
final CollectionLens collection; final CollectionLens collection;
final ImageEntry entry; final AvesEntry entry;
final bool showTitle; final bool showTitle;
final ValueNotifier<bool> visibleNotifier; final ValueNotifier<bool> visibleNotifier;
final FilterCallback onFilter; final FilterCallback onFilter;
@ -43,7 +43,7 @@ class _LocationSectionState extends State<LocationSection> with TickerProviderSt
CollectionLens get collection => widget.collection; CollectionLens get collection => widget.collection;
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
@override @override
void initState() { void initState() {
@ -158,7 +158,7 @@ class _LocationSectionState extends State<LocationSection> with TickerProviderSt
} }
class _AddressInfoGroup extends StatefulWidget { class _AddressInfoGroup extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
const _AddressInfoGroup({@required this.entry}); const _AddressInfoGroup({@required this.entry});
@ -169,7 +169,7 @@ class _AddressInfoGroup extends StatefulWidget {
class _AddressInfoGroupState extends State<_AddressInfoGroup> { class _AddressInfoGroupState extends State<_AddressInfoGroup> {
Future<String> _addressLineLoader; Future<String> _addressLineLoader;
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
@override @override
void initState() { void initState() {

View file

@ -1,14 +1,14 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/widgets/collection/thumbnail/raster.dart'; import 'package:aves/widgets/collection/thumbnail/raster.dart';
import 'package:aves/widgets/collection/thumbnail/vector.dart'; import 'package:aves/widgets/collection/thumbnail/vector.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
class ImageMarker extends StatelessWidget { class ImageMarker extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final double extent; final double extent;
final Size pointerSize; final Size pointerSize;

View file

@ -1,6 +1,6 @@
import 'dart:collection'; import 'dart:collection';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/ref/brand_colors.dart'; import 'package:aves/ref/brand_colors.dart';
import 'package:aves/services/svg_metadata_service.dart'; import 'package:aves/services/svg_metadata_service.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
@ -16,7 +16,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MetadataDirTile extends StatelessWidget { class MetadataDirTile extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final String title; final String title;
final MetadataDirectory dir; final MetadataDirectory dir;
final ValueNotifier<String> expandedDirectoryNotifier; final ValueNotifier<String> expandedDirectoryNotifier;

View file

@ -1,6 +1,6 @@
import 'dart:collection'; import 'dart:collection';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/services/metadata_service.dart'; import 'package:aves/services/metadata_service.dart';
import 'package:aves/services/svg_metadata_service.dart'; import 'package:aves/services/svg_metadata_service.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
@ -13,7 +13,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
class MetadataSectionSliver extends StatefulWidget { class MetadataSectionSliver extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
final ValueNotifier<bool> visibleNotifier; final ValueNotifier<bool> visibleNotifier;
final ValueNotifier<Map<String, MetadataDirectory>> metadataNotifier; final ValueNotifier<Map<String, MetadataDirectory>> metadataNotifier;
@ -31,7 +31,7 @@ class _MetadataSectionSliverState extends State<MetadataSectionSliver> with Auto
final ValueNotifier<String> _loadedMetadataUri = ValueNotifier(null); final ValueNotifier<String> _loadedMetadataUri = ValueNotifier(null);
final ValueNotifier<String> _expandedDirectoryNotifier = ValueNotifier(null); final ValueNotifier<String> _expandedDirectoryNotifier = ValueNotifier(null);
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
bool get isVisible => widget.visibleNotifier.value; bool get isVisible => widget.visibleNotifier.value;

View file

@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/services/metadata_service.dart'; import 'package:aves/services/metadata_service.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -9,7 +9,7 @@ enum MetadataThumbnailSource { embedded, exif }
class MetadataThumbnails extends StatefulWidget { class MetadataThumbnails extends StatefulWidget {
final MetadataThumbnailSource source; final MetadataThumbnailSource source;
final ImageEntry entry; final AvesEntry entry;
const MetadataThumbnails({ const MetadataThumbnails({
Key key, Key key,
@ -24,7 +24,7 @@ class MetadataThumbnails extends StatefulWidget {
class _MetadataThumbnailsState extends State<MetadataThumbnails> { class _MetadataThumbnailsState extends State<MetadataThumbnails> {
Future<List<Uint8List>> _loader; Future<List<Uint8List>> _loader;
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
String get uri => entry.uri; String get uri => entry.uri;

View file

@ -1,6 +1,6 @@
import 'dart:collection'; import 'dart:collection';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/ref/mime_types.dart'; import 'package:aves/ref/mime_types.dart';
import 'package:aves/ref/xmp.dart'; import 'package:aves/ref/xmp.dart';
import 'package:aves/services/android_app_service.dart'; import 'package:aves/services/android_app_service.dart';
@ -22,7 +22,7 @@ import 'package:flutter/material.dart';
import 'package:pedantic/pedantic.dart'; import 'package:pedantic/pedantic.dart';
class XmpDirTile extends StatefulWidget { class XmpDirTile extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
final SplayTreeMap<String, String> tags; final SplayTreeMap<String, String> tags;
final ValueNotifier<String> expandedNotifier; final ValueNotifier<String> expandedNotifier;
final bool initiallyExpanded; final bool initiallyExpanded;
@ -39,7 +39,7 @@ class XmpDirTile extends StatefulWidget {
} }
class _XmpDirTileState extends State<XmpDirTile> with FeedbackMixin { class _XmpDirTileState extends State<XmpDirTile> with FeedbackMixin {
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -123,7 +123,7 @@ class _XmpDirTileState extends State<XmpDirTile> with FeedbackMixin {
return; return;
} }
final embedEntry = ImageEntry.fromMap(fields); final embedEntry = AvesEntry.fromMap(fields);
unawaited(Navigator.push( unawaited(Navigator.push(
context, context,
TransparentMaterialPageRoute( TransparentMaterialPageRoute(

View file

@ -1,6 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/services/metadata_service.dart'; import 'package:aves/services/metadata_service.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -10,7 +10,7 @@ class MultiPageController extends ChangeNotifier {
final Future<MultiPageInfo> info; final Future<MultiPageInfo> info;
final ValueNotifier<int> pageNotifier = ValueNotifier(0); final ValueNotifier<int> pageNotifier = ValueNotifier(0);
MultiPageController(ImageEntry entry) : info = MetadataService.getMultiPageInfo(entry); MultiPageController(AvesEntry entry) : info = MetadataService.getMultiPageInfo(entry);
int get page => pageNotifier.value; int get page => pageNotifier.value;

View file

@ -1,7 +1,7 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/metadata.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/model/settings/coordinate_format.dart'; import 'package:aves/model/settings/coordinate_format.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
@ -20,7 +20,7 @@ import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class ViewerBottomOverlay extends StatefulWidget { class ViewerBottomOverlay extends StatefulWidget {
final List<ImageEntry> entries; final List<AvesEntry> entries;
final int index; final int index;
final bool showPosition; final bool showPosition;
final EdgeInsets viewInsets, viewPadding; final EdgeInsets viewInsets, viewPadding;
@ -42,10 +42,10 @@ class ViewerBottomOverlay extends StatefulWidget {
class _ViewerBottomOverlayState extends State<ViewerBottomOverlay> { class _ViewerBottomOverlayState extends State<ViewerBottomOverlay> {
Future<OverlayMetadata> _detailLoader; Future<OverlayMetadata> _detailLoader;
ImageEntry _lastEntry; AvesEntry _lastEntry;
OverlayMetadata _lastDetails; OverlayMetadata _lastDetails;
ImageEntry get entry { AvesEntry get entry {
final entries = widget.entries; final entries = widget.entries;
final index = widget.index; final index = widget.index;
return index < entries.length ? entries[index] : null; return index < entries.length ? entries[index] : null;
@ -138,7 +138,7 @@ const double _interRowPadding = 2.0;
const double _subRowMinWidth = 300.0; const double _subRowMinWidth = 300.0;
class _BottomOverlayContent extends AnimatedWidget { class _BottomOverlayContent extends AnimatedWidget {
final ImageEntry mainEntry, entry; final AvesEntry mainEntry, entry;
final MultiPageInfo multiPageInfo; final MultiPageInfo multiPageInfo;
final int page; final int page;
final OverlayMetadata details; final OverlayMetadata details;
@ -302,7 +302,7 @@ class _BottomOverlayContent extends AnimatedWidget {
} }
class _LocationRow extends AnimatedWidget { class _LocationRow extends AnimatedWidget {
final ImageEntry entry; final AvesEntry entry;
_LocationRow({ _LocationRow({
Key key, Key key,
@ -328,7 +328,7 @@ class _LocationRow extends AnimatedWidget {
} }
class _PositionTitleRow extends StatelessWidget { class _PositionTitleRow extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final String collectionPosition; final String collectionPosition;
final MultiPageController multiPageController; final MultiPageController multiPageController;
@ -369,7 +369,7 @@ class _PositionTitleRow extends StatelessWidget {
} }
class _DateRow extends StatelessWidget { class _DateRow extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final MultiPageController multiPageController; final MultiPageController multiPageController;
const _DateRow({ const _DateRow({

View file

@ -1,6 +1,6 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/widgets/viewer/multipage.dart'; import 'package:aves/widgets/viewer/multipage.dart';
import 'package:aves/widgets/viewer/visual/state.dart'; import 'package:aves/widgets/viewer/visual/state.dart';
@ -8,7 +8,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class Minimap extends StatelessWidget { class Minimap extends StatelessWidget {
final ImageEntry mainEntry; final AvesEntry mainEntry;
final ValueNotifier<ViewState> viewStateNotifier; final ValueNotifier<ViewState> viewStateNotifier;
final MultiPageController multiPageController; final MultiPageController multiPageController;
final Size size; final Size size;

View file

@ -1,6 +1,6 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/widgets/collection/thumbnail/overlay.dart'; import 'package:aves/widgets/collection/thumbnail/overlay.dart';
@ -10,7 +10,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MultiPageOverlay extends StatefulWidget { class MultiPageOverlay extends StatefulWidget {
final ImageEntry mainEntry; final AvesEntry mainEntry;
final MultiPageController controller; final MultiPageController controller;
final double availableWidth; final double availableWidth;
@ -34,7 +34,7 @@ class _MultiPageOverlayState extends State<MultiPageOverlay> {
static const double extent = 48; static const double extent = 48;
static const double separatorWidth = 2; static const double separatorWidth = 2;
ImageEntry get mainEntry => widget.mainEntry; AvesEntry get mainEntry => widget.mainEntry;
MultiPageController get controller => widget.controller; MultiPageController get controller => widget.controller;
@ -162,7 +162,7 @@ class _MultiPageOverlayState extends State<MultiPageOverlay> {
); );
} }
Widget _buildPageThumbnail(ImageEntry entry) { Widget _buildPageThumbnail(AvesEntry entry) {
Widget child = RasterImageThumbnail( Widget child = RasterImageThumbnail(
entry: entry, entry: entry,
extent: extent, extent: extent,

View file

@ -1,4 +1,4 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/services/metadata_service.dart'; import 'package:aves/services/metadata_service.dart';
import 'package:aves/widgets/viewer/overlay/common.dart'; import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:aves/widgets/viewer/panorama_page.dart'; import 'package:aves/widgets/viewer/panorama_page.dart';
@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
import 'package:pedantic/pedantic.dart'; import 'package:pedantic/pedantic.dart';
class PanoramaOverlay extends StatelessWidget { class PanoramaOverlay extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final Animation<double> scale; final Animation<double> scale;
const PanoramaOverlay({ const PanoramaOverlay({

View file

@ -2,7 +2,7 @@ import 'dart:math';
import 'package:aves/model/actions/entry_actions.dart'; import 'package:aves/model/actions/entry_actions.dart';
import 'package:aves/model/favourite_repo.dart'; import 'package:aves/model/favourite_repo.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
@ -19,7 +19,7 @@ import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class ViewerTopOverlay extends StatelessWidget { class ViewerTopOverlay extends StatelessWidget {
final ImageEntry entry; final AvesEntry entry;
final Animation<double> scale; final Animation<double> scale;
final EdgeInsets viewInsets, viewPadding; final EdgeInsets viewInsets, viewPadding;
final Function(EntryAction value) onActionSelected; final Function(EntryAction value) onActionSelected;
@ -135,7 +135,7 @@ class _TopOverlayRow extends StatelessWidget {
final List<EntryAction> inAppActions; final List<EntryAction> inAppActions;
final List<EntryAction> externalAppActions; final List<EntryAction> externalAppActions;
final Animation<double> scale; final Animation<double> scale;
final ImageEntry entry; final AvesEntry entry;
final Function(EntryAction value) onActionSelected; final Function(EntryAction value) onActionSelected;
const _TopOverlayRow({ const _TopOverlayRow({
@ -299,7 +299,7 @@ class _TopOverlayRow extends StatelessWidget {
} }
class _FavouriteToggler extends StatefulWidget { class _FavouriteToggler extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
final bool isMenuItem; final bool isMenuItem;
final VoidCallback onPressed; final VoidCallback onPressed;

View file

@ -1,6 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/services/android_app_service.dart'; import 'package:aves/services/android_app_service.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
@ -12,7 +12,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart'; import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
class VideoControlOverlay extends StatefulWidget { class VideoControlOverlay extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
final IjkMediaController controller; final IjkMediaController controller;
final Animation<double> scale; final Animation<double> scale;
@ -37,7 +37,7 @@ class _VideoControlOverlayState extends State<VideoControlOverlay> with SingleTi
// video info is not refreshed by default, so we use a timer to do so // video info is not refreshed by default, so we use a timer to do so
Timer _progressTimer; Timer _progressTimer;
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
Animation<double> get scale => widget.scale; Animation<double> get scale => widget.scale;

View file

@ -1,5 +1,5 @@
import 'package:aves/model/entry_images.dart'; import 'package:aves/model/entry_images.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/panorama.dart'; import 'package:aves/model/panorama.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/insets.dart'; import 'package:aves/widgets/common/basic/insets.dart';
@ -15,7 +15,7 @@ import 'package:provider/provider.dart';
class PanoramaPage extends StatefulWidget { class PanoramaPage extends StatefulWidget {
static const routeName = '/viewer/panorama'; static const routeName = '/viewer/panorama';
final ImageEntry entry; final AvesEntry entry;
final PanoramaInfo info; final PanoramaInfo info;
const PanoramaPage({ const PanoramaPage({
@ -31,7 +31,7 @@ class _PanoramaPageState extends State<PanoramaPage> {
final ValueNotifier<bool> _overlayVisible = ValueNotifier(true); final ValueNotifier<bool> _overlayVisible = ValueNotifier(true);
final ValueNotifier<SensorControl> _sensorControl = ValueNotifier(SensorControl.None); final ValueNotifier<SensorControl> _sensorControl = ValueNotifier(SensorControl.None);
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
PanoramaInfo get info => widget.info; PanoramaInfo get info => widget.info;

View file

@ -1,7 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:aves/model/entry.dart';
import 'package:aves/model/entry_images.dart'; import 'package:aves/model/entry_images.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/services/image_file_service.dart'; import 'package:aves/services/image_file_service.dart';
import 'package:aves/services/metadata_service.dart'; import 'package:aves/services/metadata_service.dart';
import 'package:pdf/widgets.dart' as pdf; import 'package:pdf/widgets.dart' as pdf;
@ -9,7 +9,7 @@ import 'package:pedantic/pedantic.dart';
import 'package:printing/printing.dart'; import 'package:printing/printing.dart';
class EntryPrinter { class EntryPrinter {
final ImageEntry entry; final AvesEntry entry;
const EntryPrinter(this.entry); const EntryPrinter(this.entry);
@ -58,7 +58,7 @@ class EntryPrinter {
return pages; return pages;
} }
Future<pdf.Widget> _buildPageImage(ImageEntry entry) async { Future<pdf.Widget> _buildPageImage(AvesEntry entry) async {
if (entry.isSvg) { if (entry.isSvg) {
final bytes = await ImageFileService.getSvg(entry.uri, entry.mimeType); final bytes = await ImageFileService.getSvg(entry.uri, entry.mimeType);
if (bytes != null && bytes.isNotEmpty) { if (bytes != null && bytes.isNotEmpty) {

View file

@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:aves/image_providers/uri_picture_provider.dart'; import 'package:aves/image_providers/uri_picture_provider.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/model/settings/entry_background.dart'; import 'package:aves/model/settings/entry_background.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
@ -23,7 +23,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class EntryPageView extends StatefulWidget { class EntryPageView extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
final MultiPageInfo multiPageInfo; final MultiPageInfo multiPageInfo;
final int page; final int page;
final Size viewportSize; final Size viewportSize;
@ -36,7 +36,7 @@ class EntryPageView extends StatefulWidget {
EntryPageView({ EntryPageView({
Key key, Key key,
ImageEntry mainEntry, AvesEntry mainEntry,
this.multiPageInfo, this.multiPageInfo,
this.page, this.page,
this.viewportSize, this.viewportSize,
@ -56,7 +56,7 @@ class _EntryPageViewState extends State<EntryPageView> {
final ValueNotifier<ViewState> _viewStateNotifier = ValueNotifier(ViewState.zero); final ValueNotifier<ViewState> _viewStateNotifier = ValueNotifier(ViewState.zero);
final List<StreamSubscription> _subscriptions = []; final List<StreamSubscription> _subscriptions = [];
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
Size get viewportSize => widget.viewportSize; Size get viewportSize => widget.viewportSize;

View file

@ -2,7 +2,7 @@ import 'dart:math';
import 'package:aves/image_providers/region_provider.dart'; import 'package:aves/image_providers/region_provider.dart';
import 'package:aves/model/entry_images.dart'; import 'package:aves/model/entry_images.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/settings/entry_background.dart'; import 'package:aves/model/settings/entry_background.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/utils/math_utils.dart'; import 'package:aves/utils/math_utils.dart';
@ -15,7 +15,7 @@ import 'package:flutter/material.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class RasterImageView extends StatefulWidget { class RasterImageView extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
final ValueNotifier<ViewState> viewStateNotifier; final ValueNotifier<ViewState> viewStateNotifier;
final ImageErrorWidgetBuilder errorBuilder; final ImageErrorWidgetBuilder errorBuilder;
@ -39,7 +39,7 @@ class _RasterImageViewState extends State<RasterImageView> {
ImageStreamListener _fullImageListener; ImageStreamListener _fullImageListener;
final ValueNotifier<bool> _fullImageLoaded = ValueNotifier(false); final ValueNotifier<bool> _fullImageLoaded = ValueNotifier(false);
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
ValueNotifier<ViewState> get viewStateNotifier => widget.viewStateNotifier; ValueNotifier<ViewState> get viewStateNotifier => widget.viewStateNotifier;
@ -323,7 +323,7 @@ class _RasterImageViewState extends State<RasterImageView> {
} }
class RegionTile extends StatefulWidget { class RegionTile extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
// `tileRect` uses Flutter view coordinates // `tileRect` uses Flutter view coordinates
// `regionRect` uses the raw image pixel coordinates // `regionRect` uses the raw image pixel coordinates
@ -354,7 +354,7 @@ class RegionTile extends StatefulWidget {
class _RegionTileState extends State<RegionTile> { class _RegionTileState extends State<RegionTile> {
RegionProvider _provider; RegionProvider _provider;
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
@override @override
void initState() { void initState() {

View file

@ -1,13 +1,13 @@
import 'dart:async'; import 'dart:async';
import 'dart:ui'; import 'dart:ui';
import 'package:aves/model/entry.dart';
import 'package:aves/model/entry_images.dart'; import 'package:aves/model/entry_images.dart';
import 'package:aves/model/image_entry.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart'; import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
class VideoView extends StatefulWidget { class VideoView extends StatefulWidget {
final ImageEntry entry; final AvesEntry entry;
final IjkMediaController controller; final IjkMediaController controller;
const VideoView({ const VideoView({
@ -23,7 +23,7 @@ class VideoView extends StatefulWidget {
class _VideoViewState extends State<VideoView> { class _VideoViewState extends State<VideoView> {
final List<StreamSubscription> _subscriptions = []; final List<StreamSubscription> _subscriptions = [];
ImageEntry get entry => widget.entry; AvesEntry get entry => widget.entry;
IjkMediaController get controller => widget.controller; IjkMediaController get controller => widget.controller;