diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b2c46b7b..7191c0a11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Added - Collection / Info: edit title via IPTC / XMP +- Albums / Countries / Tags: size displayed in list view details, sort by size - Greek translation (thanks Emmanouil Papavergis) ### Changed diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index b3d8fa79c..aaecf0c35 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -337,11 +337,6 @@ "collectionSearchTitlesHintText": "Titel suchen", - "collectionSortDate": "Nach Datum", - "collectionSortSize": "Nach Größe", - "collectionSortName": "Nach Album & Dateiname", - "collectionSortRating": "Nach Bewertung", - "collectionGroupAlbum": "Nach Album", "collectionGroupMonth": "Nach Monat", "collectionGroupDay": "Nach Tag", @@ -385,9 +380,12 @@ "drawerCountryPage": "Länder", "drawerTagPage": "Tags", - "chipSortDate": "Nach Datum", - "chipSortName": "Nach Name", - "chipSortCount": "Nach Anzahl", + "sortByDate": "Nach Datum", + "sortByName": "Nach Name", + "sortByItemCount": "Nach Anzahl", + "sortBySize": "Nach Größe", + "sortByAlbumFileName": "Nach Album & Dateiname", + "sortByRating": "Nach Bewertung", "albumGroupTier": "Nach Ebene", "albumGroupVolume": "Nach Speichervolumen", diff --git a/lib/l10n/app_el.arb b/lib/l10n/app_el.arb index ea5060fa3..44881d0ca 100644 --- a/lib/l10n/app_el.arb +++ b/lib/l10n/app_el.arb @@ -337,11 +337,6 @@ "collectionSearchTitlesHintText": "Αναζήτηση τίτλων", - "collectionSortDate": "Ανά ημερομηνία.", - "collectionSortSize": "Ανά μέγεθος", - "collectionSortName": "Ανά άλμπουμ και όνομα αρχείου", - "collectionSortRating": "Ανά βαθμολογία", - "collectionGroupAlbum": "Ανά άλμπουμ", "collectionGroupMonth": "Ανά μήνα", "collectionGroupDay": "Ανά ημέρα", @@ -385,9 +380,12 @@ "drawerCountryPage": "Χώρες", "drawerTagPage": "Ετικέτες", - "chipSortDate": "Ανά ημερομηνία", - "chipSortName": "Ανά όνομα", - "chipSortCount": "Ανά μέτρηση στοιχείων", + "sortByDate": "Ανά ημερομηνία", + "sortByName": "Ανά όνομα", + "sortByItemCount": "Ανά μέτρηση στοιχείων", + "sortBySize": "Ανά μέγεθος", + "sortByAlbumFileName": "Ανά άλμπουμ και όνομα αρχείου", + "sortByRating": "Ανά βαθμολογία", "albumGroupTier": "Ανά βαθμίδα", "albumGroupVolume": "Ανά αποθηκευτική μονάδα", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 1fe405dc7..408073802 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -468,11 +468,6 @@ "collectionSearchTitlesHintText": "Search titles", - "collectionSortDate": "By date", - "collectionSortSize": "By size", - "collectionSortName": "By album & file name", - "collectionSortRating": "By rating", - "collectionGroupAlbum": "By album", "collectionGroupMonth": "By month", "collectionGroupDay": "By day", @@ -566,9 +561,12 @@ "drawerCountryPage": "Countries", "drawerTagPage": "Tags", - "chipSortDate": "By date", - "chipSortName": "By name", - "chipSortCount": "By item count", + "sortByDate": "By date", + "sortByName": "By name", + "sortByItemCount": "By item count", + "sortBySize": "By size", + "sortByAlbumFileName": "By album & file name", + "sortByRating": "By rating", "albumGroupTier": "By tier", "albumGroupVolume": "By storage volume", diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index ef47000dc..8e9a662eb 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -336,11 +336,6 @@ "collectionSearchTitlesHintText": "Buscar títulos", - "collectionSortDate": "Por fecha", - "collectionSortSize": "Por tamaño", - "collectionSortName": "Por nombre de álbum y archivo", - "collectionSortRating": "Por clasificación", - "collectionGroupAlbum": "Por álbum", "collectionGroupMonth": "Por mes", "collectionGroupDay": "Por día", @@ -384,9 +379,12 @@ "drawerCountryPage": "Países", "drawerTagPage": "Etiquetas", - "chipSortDate": "Por fecha", - "chipSortName": "Por nombre", - "chipSortCount": "Por número de elementos", + "sortByDate": "Por fecha", + "sortByName": "Por nombre", + "sortByItemCount": "Por número de elementos", + "sortBySize": "Por tamaño", + "sortByAlbumFileName": "Por nombre de álbum y archivo", + "sortByRating": "Por clasificación", "albumGroupTier": "Por nivel", "albumGroupVolume": "Por volumen de almacenamiento", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 423b2cdf8..7c7414d17 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -338,11 +338,6 @@ "collectionSearchTitlesHintText": "Recherche de titres", - "collectionSortDate": "par date", - "collectionSortSize": "par taille", - "collectionSortName": "alphabétique", - "collectionSortRating": "par notation", - "collectionGroupAlbum": "par album", "collectionGroupMonth": "par mois", "collectionGroupDay": "par jour", @@ -386,9 +381,12 @@ "drawerCountryPage": "Pays", "drawerTagPage": "Libellés", - "chipSortDate": "par date", - "chipSortName": "alphabétique", - "chipSortCount": "par nombre d’éléments", + "sortByDate": "par date", + "sortByName": "alphabétique", + "sortByItemCount": "par nombre d’éléments", + "sortBySize": "par taille", + "sortByAlbumFileName": "alphabétique", + "sortByRating": "par notation", "albumGroupTier": "par importance", "albumGroupVolume": "par volume de stockage", diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index f0cb91fd9..beb9b1df0 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -336,11 +336,6 @@ "collectionSearchTitlesHintText": "Cari judul", - "collectionSortDate": "Lewat tanggal", - "collectionSortSize": "Lewat ukuran", - "collectionSortName": "Lewat nama album & file", - "collectionSortRating": "Lewat nilai", - "collectionGroupAlbum": "Lewat album", "collectionGroupMonth": "Lewat bulan", "collectionGroupDay": "Lewat hari", @@ -384,9 +379,12 @@ "drawerCountryPage": "Negara", "drawerTagPage": "Label", - "chipSortDate": "Lewat tanggal", - "chipSortName": "Lewat nama", - "chipSortCount": "Lewat jumlah benda", + "sortByDate": "Lewat tanggal", + "sortByName": "Lewat nama", + "sortByItemCount": "Lewat jumlah benda", + "sortBySize": "Lewat ukuran", + "sortByAlbumFileName": "Lewat nama album & file", + "sortByRating": "Lewat nilai", "albumGroupTier": "Lewat tingkat", "albumGroupVolume": "Lewat volume penyimpanan", diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index 404ac247f..6e534b460 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -337,11 +337,6 @@ "collectionSearchTitlesHintText": "Cerca titoli", - "collectionSortDate": "Per data", - "collectionSortSize": "Per dimensione", - "collectionSortName": "Per album e nome del file", - "collectionSortRating": "Per valutazione", - "collectionGroupAlbum": "Per album", "collectionGroupMonth": "Per mese", "collectionGroupDay": "Per giorno", @@ -385,9 +380,12 @@ "drawerCountryPage": "Paesi", "drawerTagPage": "Etichette", - "chipSortDate": "Per data", - "chipSortName": "Per nome", - "chipSortCount": "Per numero di elementi", + "sortByDate": "Per data", + "sortByName": "Per nome", + "sortByItemCount": "Per numero di elementi", + "sortBySize": "Per dimensione", + "sortByAlbumFileName": "Per album e nome del file", + "sortByRating": "Per valutazione", "albumGroupTier": "Per importanza", "albumGroupVolume": "Per volume di archiviazione", diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index 51e1696fe..25c97a0a0 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -336,11 +336,6 @@ "collectionSearchTitlesHintText": "タイトルを検索", - "collectionSortDate": "日付", - "collectionSortSize": "サイズ", - "collectionSortName": "アルバムとファイル名", - "collectionSortRating": "評価", - "collectionGroupAlbum": "アルバム別", "collectionGroupMonth": "月別", "collectionGroupDay": "日別", @@ -384,9 +379,12 @@ "drawerCountryPage": "国", "drawerTagPage": "タグ", - "chipSortDate": "日付", - "chipSortName": "名前", - "chipSortCount": "アイテム件数", + "sortByDate": "日付", + "sortByName": "名前", + "sortByItemCount": "アイテム件数", + "sortBySize": "サイズ", + "sortByAlbumFileName": "アルバムとファイル名", + "sortByRating": "評価", "albumGroupTier": "階層別", "albumGroupVolume": "ストレージ ボリューム別", diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb index 228a58757..aca6034aa 100644 --- a/lib/l10n/app_ko.arb +++ b/lib/l10n/app_ko.arb @@ -338,11 +338,6 @@ "collectionSearchTitlesHintText": "제목 검색", - "collectionSortDate": "날짜", - "collectionSortSize": "크기", - "collectionSortName": "이름", - "collectionSortRating": "별점", - "collectionGroupAlbum": "앨범별로", "collectionGroupMonth": "월별로", "collectionGroupDay": "날짜별로", @@ -386,9 +381,12 @@ "drawerCountryPage": "국가", "drawerTagPage": "태그", - "chipSortDate": "날짜", - "chipSortName": "이름", - "chipSortCount": "항목수", + "sortByDate": "날짜", + "sortByName": "이름", + "sortByItemCount": "항목수", + "sortBySize": "크기", + "sortByAlbumFileName": "이름", + "sortByRating": "별점", "albumGroupTier": "단계별로", "albumGroupVolume": "저장공간별로", diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index 87c066ee6..f32d80358 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -337,11 +337,6 @@ "collectionSearchTitlesHintText": "Zoek op titel", - "collectionSortDate": "Op datum", - "collectionSortSize": "Op grootte", - "collectionSortName": "Op album- en bestandsnaam", - "collectionSortRating": "Op rating", - "collectionGroupAlbum": "Op Albumnaam", "collectionGroupMonth": "Op maand", "collectionGroupDay": "Op dag", @@ -385,9 +380,12 @@ "drawerCountryPage": "Landen", "drawerTagPage": "Labels", - "chipSortDate": "Op datum", - "chipSortName": "Op naam", - "chipSortCount": "Op aantal items", + "sortByDate": "Op datum", + "sortByName": "Op naam", + "sortByItemCount": "Op aantal items", + "sortBySize": "Op grootte", + "sortByAlbumFileName": "Op album- en bestandsnaam", + "sortByRating": "Op rating", "albumGroupTier": "Op rang", "albumGroupVolume": "Op opslagvolume", diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index eab65bf19..f3f9f7cf0 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -337,11 +337,6 @@ "collectionSearchTitlesHintText": "Pesquisar títulos", - "collectionSortDate": "Por data", - "collectionSortSize": "Por tamanho", - "collectionSortName": "Por álbum e nome de arquivo", - "collectionSortRating": "Por classificação", - "collectionGroupAlbum": "Por álbum", "collectionGroupMonth": "Por mês", "collectionGroupDay": "Por dia", @@ -385,9 +380,12 @@ "drawerCountryPage": "Países", "drawerTagPage": "Etiquetas", - "chipSortDate": "Por data", - "chipSortName": "Por nome", - "chipSortCount": "Por contagem de itens", + "sortByDate": "Por data", + "sortByName": "Por nome", + "sortByItemCount": "Por contagem de itens", + "sortBySize": "Por tamanho", + "sortByAlbumFileName": "Por álbum e nome de arquivo", + "sortByRating": "Por classificação", "albumGroupTier": "Por nível", "albumGroupVolume": "Por volume de armazenamento", diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index 1973194c4..ceb54e7a9 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -335,11 +335,6 @@ "collectionSearchTitlesHintText": "Поиск заголовков", - "collectionSortDate": "По дате", - "collectionSortSize": "По размеру", - "collectionSortName": "По имени альбома и файла", - "collectionSortRating": "По рейтингу", - "collectionGroupAlbum": "По альбому", "collectionGroupMonth": "По месяцу", "collectionGroupDay": "По дню", @@ -383,9 +378,12 @@ "drawerCountryPage": "Страны", "drawerTagPage": "Теги", - "chipSortDate": "По дате", - "chipSortName": "По названию", - "chipSortCount": "По количеству объектов", + "sortByDate": "По дате", + "sortByName": "По названию", + "sortByItemCount": "По количеству объектов", + "sortBySize": "По размеру", + "sortByAlbumFileName": "По имени альбома и файла", + "sortByRating": "По рейтингу", "albumGroupTier": "По уровню", "albumGroupVolume": "По накопителю", diff --git a/lib/l10n/app_tr.arb b/lib/l10n/app_tr.arb index 3796e40b1..1b29050f2 100644 --- a/lib/l10n/app_tr.arb +++ b/lib/l10n/app_tr.arb @@ -323,11 +323,6 @@ "collectionSearchTitlesHintText": "Başlıkları ara", - "collectionSortDate": "Tarihe göre", - "collectionSortSize": "Boyuta göre", - "collectionSortName": "Albüm ve dosya adına göre", - "collectionSortRating": "Derecelendirmeye göre", - "collectionGroupAlbum": "Albüme göre", "collectionGroupMonth": "Aya göre", "collectionGroupDay": "Güne göre", @@ -380,9 +375,12 @@ "drawerCountryPage": "Ülkeler", "drawerTagPage": "Etiketler", - "chipSortDate": "Tarihe göre", - "chipSortName": "Adına göre", - "chipSortCount": "Öğe sayısına göre", + "sortByDate": "Tarihe göre", + "sortByName": "Adına göre", + "sortByItemCount": "Öğe sayısına göre", + "sortBySize": "Boyuta göre", + "sortByAlbumFileName": "Albüm ve dosya adına göre", + "sortByRating": "Derecelendirmeye göre", "albumGroupTier": "Kademeye göre", "albumGroupVolume": "Depolama hacmine göre", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index a500e58c1..88b4a4cce 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -337,11 +337,6 @@ "collectionSearchTitlesHintText": "搜索标题", - "collectionSortDate": "按日期", - "collectionSortSize": "按大小", - "collectionSortName": "按相册和文件名", - "collectionSortRating": "按评分", - "collectionGroupAlbum": "按相册", "collectionGroupMonth": "按月份", "collectionGroupDay": "按天", @@ -385,9 +380,12 @@ "drawerCountryPage": "国家", "drawerTagPage": "标签", - "chipSortDate": "按日期", - "chipSortName": "按名称", - "chipSortCount": "按数量", + "sortByDate": "按日期", + "sortByName": "按名称", + "sortByItemCount": "按数量", + "sortBySize": "按大小", + "sortByAlbumFileName": "按相册和文件名", + "sortByRating": "按评分", "albumGroupTier": "按层级", "albumGroupVolume": "按存储卷", diff --git a/lib/model/source/album.dart b/lib/model/source/album.dart index 2f91dccbc..65a5eb908 100644 --- a/lib/model/source/album.dart +++ b/lib/model/source/album.dart @@ -4,6 +4,7 @@ import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/utils/android_file_utils.dart'; +import 'package:aves/utils/collection_utils.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:collection/collection.dart'; import 'package:flutter/widgets.dart'; @@ -95,7 +96,7 @@ mixin AlbumMixin on SourceBase { // filter summary // by directory - final Map _filterEntryCountMap = {}; + final Map _filterEntryCountMap = {}, _filterSizeMap = {}; final Map _filterRecentEntryMap = {}; void invalidateAlbumFilterSummary({ @@ -103,10 +104,11 @@ mixin AlbumMixin on SourceBase { Set? directories, bool notify = true, }) { - if (_filterEntryCountMap.isEmpty && _filterRecentEntryMap.isEmpty) return; + if (_filterEntryCountMap.isEmpty && _filterSizeMap.isEmpty && _filterRecentEntryMap.isEmpty) return; if (entries == null && directories == null) { _filterEntryCountMap.clear(); + _filterSizeMap.clear(); _filterRecentEntryMap.clear(); } else { directories ??= {}; @@ -115,6 +117,7 @@ mixin AlbumMixin on SourceBase { } directories.forEach((directory) { _filterEntryCountMap.remove(directory); + _filterSizeMap.remove(directory); _filterRecentEntryMap.remove(directory); }); } @@ -127,6 +130,10 @@ mixin AlbumMixin on SourceBase { return _filterEntryCountMap.putIfAbsent(filter.album, () => visibleEntries.where(filter.test).length); } + int albumSize(AlbumFilter filter) { + return _filterSizeMap.putIfAbsent(filter.album, () => visibleEntries.where(filter.test).map((v) => v.sizeBytes).sum); + } + AvesEntry? albumRecentEntry(AlbumFilter filter) { return _filterRecentEntryMap.putIfAbsent(filter.album, () => sortedEntriesByDate.firstWhereOrNull(filter.test)); } diff --git a/lib/model/source/collection_source.dart b/lib/model/source/collection_source.dart index a9fd2886e..79dfc825f 100644 --- a/lib/model/source/collection_source.dart +++ b/lib/model/source/collection_source.dart @@ -458,6 +458,13 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM return 0; } + int size(CollectionFilter filter) { + if (filter is AlbumFilter) return albumSize(filter); + if (filter is LocationFilter) return countrySize(filter); + if (filter is TagFilter) return tagSize(filter); + return 0; + } + AvesEntry? recentEntry(CollectionFilter filter) { if (filter is AlbumFilter) return albumRecentEntry(filter); if (filter is LocationFilter) return countryRecentEntry(filter); diff --git a/lib/model/source/enums.dart b/lib/model/source/enums.dart index 6035caa19..ae59b22f3 100644 --- a/lib/model/source/enums.dart +++ b/lib/model/source/enums.dart @@ -1,6 +1,6 @@ enum SourceState { loading, cataloguing, locatingCountries, locatingPlaces, ready } -enum ChipSortFactor { date, name, count } +enum ChipSortFactor { date, name, count, size } enum AlbumChipGroupFactor { none, importance, volume } diff --git a/lib/model/source/location.dart b/lib/model/source/location.dart index 1b29dc43c..83d3439d1 100644 --- a/lib/model/source/location.dart +++ b/lib/model/source/location.dart @@ -9,6 +9,7 @@ import 'package:aves/model/source/analysis_controller.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/enums.dart'; import 'package:aves/services/common/services.dart'; +import 'package:aves/utils/collection_utils.dart'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:tuple/tuple.dart'; @@ -180,7 +181,7 @@ mixin LocationMixin on SourceBase { // filter summary // by country code - final Map _filterEntryCountMap = {}; + final Map _filterEntryCountMap = {}, _filterSizeMap = {}; final Map _filterRecentEntryMap = {}; void invalidateCountryFilterSummary({ @@ -188,10 +189,11 @@ mixin LocationMixin on SourceBase { Set? countryCodes, bool notify = true, }) { - if (_filterEntryCountMap.isEmpty && _filterRecentEntryMap.isEmpty) return; + if (_filterEntryCountMap.isEmpty && _filterSizeMap.isEmpty && _filterRecentEntryMap.isEmpty) return; if (entries == null && countryCodes == null) { _filterEntryCountMap.clear(); + _filterSizeMap.clear(); _filterRecentEntryMap.clear(); } else { countryCodes ??= {}; @@ -200,6 +202,7 @@ mixin LocationMixin on SourceBase { } countryCodes.forEach((countryCode) { _filterEntryCountMap.remove(countryCode); + _filterSizeMap.remove(countryCode); _filterRecentEntryMap.remove(countryCode); }); } @@ -214,6 +217,12 @@ mixin LocationMixin on SourceBase { return _filterEntryCountMap.putIfAbsent(countryCode, () => visibleEntries.where(filter.test).length); } + int countrySize(LocationFilter filter) { + final countryCode = filter.countryCode; + if (countryCode == null) return 0; + return _filterSizeMap.putIfAbsent(countryCode, () => visibleEntries.where(filter.test).map((v) => v.sizeBytes).sum); + } + AvesEntry? countryRecentEntry(LocationFilter filter) { final countryCode = filter.countryCode; if (countryCode == null) return null; diff --git a/lib/model/source/tag.dart b/lib/model/source/tag.dart index f7b597a18..56cb6c2d1 100644 --- a/lib/model/source/tag.dart +++ b/lib/model/source/tag.dart @@ -5,6 +5,7 @@ import 'package:aves/model/source/analysis_controller.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/enums.dart'; import 'package:aves/services/common/services.dart'; +import 'package:aves/utils/collection_utils.dart'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; @@ -75,7 +76,7 @@ mixin TagMixin on SourceBase { // filter summary // by tag - final Map _filterEntryCountMap = {}; + final Map _filterEntryCountMap = {}, _filterSizeMap = {}; final Map _filterRecentEntryMap = {}; void invalidateTagFilterSummary({ @@ -83,10 +84,11 @@ mixin TagMixin on SourceBase { Set? tags, bool notify = true, }) { - if (_filterEntryCountMap.isEmpty && _filterRecentEntryMap.isEmpty) return; + if (_filterEntryCountMap.isEmpty && _filterSizeMap.isEmpty && _filterRecentEntryMap.isEmpty) return; if (entries == null && tags == null) { _filterEntryCountMap.clear(); + _filterSizeMap.clear(); _filterRecentEntryMap.clear(); } else { tags ??= {}; @@ -95,6 +97,7 @@ mixin TagMixin on SourceBase { } tags.forEach((tag) { _filterEntryCountMap.remove(tag); + _filterSizeMap.remove(tag); _filterRecentEntryMap.remove(tag); }); } @@ -107,6 +110,10 @@ mixin TagMixin on SourceBase { return _filterEntryCountMap.putIfAbsent(filter.tag, () => visibleEntries.where(filter.test).length); } + int tagSize(TagFilter filter) { + return _filterSizeMap.putIfAbsent(filter.tag, () => visibleEntries.where(filter.test).map((v) => v.sizeBytes).sum); + } + AvesEntry? tagRecentEntry(TagFilter filter) { return _filterRecentEntryMap.putIfAbsent(filter.tag, () => sortedEntriesByDate.firstWhereOrNull(filter.test)); } diff --git a/lib/utils/collection_utils.dart b/lib/utils/collection_utils.dart index 74b87fac5..4983a8d62 100644 --- a/lib/utils/collection_utils.dart +++ b/lib/utils/collection_utils.dart @@ -13,3 +13,7 @@ extension ExtraMapNullableKeyValue on Map { Map whereNotNullValue() => {for (var kv in entries.where((kv) => kv.value != null)) kv.key: kv.value as V}; } + +extension ExtraNumIterable on Iterable { + int get sum => fold(0, (prev, v) => prev + (v ?? 0)); +} diff --git a/lib/widgets/collection/app_bar.dart b/lib/widgets/collection/app_bar.dart index 55d142445..e9ba07921 100644 --- a/lib/widgets/collection/app_bar.dart +++ b/lib/widgets/collection/app_bar.dart @@ -518,10 +518,10 @@ class _CollectionAppBarState extends State with SingleTickerPr return TileViewDialog( initialValue: initialValue, sortOptions: { - EntrySortFactor.date: l10n.collectionSortDate, - EntrySortFactor.size: l10n.collectionSortSize, - EntrySortFactor.name: l10n.collectionSortName, - EntrySortFactor.rating: l10n.collectionSortRating, + EntrySortFactor.date: l10n.sortByDate, + EntrySortFactor.size: l10n.sortBySize, + EntrySortFactor.name: l10n.sortByAlbumFileName, + EntrySortFactor.rating: l10n.sortByRating, }, groupOptions: { EntryGroupFactor.album: l10n.collectionGroupAlbum, diff --git a/lib/widgets/filter_grids/common/action_delegates/album_set.dart b/lib/widgets/filter_grids/common/action_delegates/album_set.dart index 90f8b0a5a..76feb189b 100644 --- a/lib/widgets/filter_grids/common/action_delegates/album_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/album_set.dart @@ -137,14 +137,15 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with return TileViewDialog( initialValue: initialValue, sortOptions: { - ChipSortFactor.date: context.l10n.chipSortDate, - ChipSortFactor.name: context.l10n.chipSortName, - ChipSortFactor.count: context.l10n.chipSortCount, + ChipSortFactor.date: l10n.sortByDate, + ChipSortFactor.name: l10n.sortByName, + ChipSortFactor.count: l10n.sortByItemCount, + ChipSortFactor.size: l10n.sortBySize, }, groupOptions: { - AlbumChipGroupFactor.importance: context.l10n.albumGroupTier, - AlbumChipGroupFactor.volume: context.l10n.albumGroupVolume, - AlbumChipGroupFactor.none: context.l10n.albumGroupNone, + AlbumChipGroupFactor.importance: l10n.albumGroupTier, + AlbumChipGroupFactor.volume: l10n.albumGroupVolume, + AlbumChipGroupFactor.none: l10n.albumGroupNone, }, layoutOptions: { TileLayout.grid: l10n.tileLayoutGrid, diff --git a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart index 060559a3c..8b6a34925 100644 --- a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart @@ -206,9 +206,10 @@ abstract class ChipSetActionDelegate with FeedbackMi return TileViewDialog( initialValue: initialValue, sortOptions: { - ChipSortFactor.date: context.l10n.chipSortDate, - ChipSortFactor.name: context.l10n.chipSortName, - ChipSortFactor.count: context.l10n.chipSortCount, + ChipSortFactor.date: l10n.sortByDate, + ChipSortFactor.name: l10n.sortByName, + ChipSortFactor.count: l10n.sortByItemCount, + ChipSortFactor.size: l10n.sortBySize, }, layoutOptions: { TileLayout.grid: l10n.tileLayoutGrid, diff --git a/lib/widgets/filter_grids/common/draggable_thumb_label.dart b/lib/widgets/filter_grids/common/draggable_thumb_label.dart index 5276ac819..6eb55a823 100644 --- a/lib/widgets/filter_grids/common/draggable_thumb_label.dart +++ b/lib/widgets/filter_grids/common/draggable_thumb_label.dart @@ -1,6 +1,7 @@ import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/enums.dart'; +import 'package:aves/utils/file_utils.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/grid/draggable_thumb_label.dart'; import 'package:flutter/material.dart'; @@ -22,10 +23,6 @@ class FilterDraggableThumbLabel extends StatelessWid offsetY: offsetY, lineBuilder: (context, filterGridItem) { switch (sortFactor) { - case ChipSortFactor.count: - return [ - context.l10n.itemCount(context.read().count(filterGridItem.filter)), - ]; case ChipSortFactor.date: return [ DraggableThumbLabel.formatMonthThumbLabel(context, filterGridItem.entry?.bestDate), @@ -34,6 +31,15 @@ class FilterDraggableThumbLabel extends StatelessWid return [ filterGridItem.filter.getLabel(context), ]; + case ChipSortFactor.count: + return [ + context.l10n.itemCount(context.read().count(filterGridItem.filter)), + ]; + case ChipSortFactor.size: + final locale = context.l10n.localeName; + return [ + formatFileSize(locale, context.read().size(filterGridItem.filter)), + ]; } }, ); diff --git a/lib/widgets/filter_grids/common/filter_nav_page.dart b/lib/widgets/filter_grids/common/filter_nav_page.dart index 7c68a3b89..a9cda6ea4 100644 --- a/lib/widgets/filter_grids/common/filter_nav_page.dart +++ b/lib/widgets/filter_grids/common/filter_nav_page.dart @@ -47,6 +47,11 @@ class FilterNavigationPage a, MapEntry b) { + final c = b.value.compareTo(a.value); + return c != 0 ? c : a.key.compareTo(b.key); + } + static int compareFiltersByName(FilterGridItem a, FilterGridItem b) { return a.filter.compareTo(b.filter); } @@ -75,6 +80,12 @@ class FilterNavigationPage kv.key).toSet(); allMapEntries = toGridItem(source, filters); break; + case ChipSortFactor.size: + final filtersWithSize = List.of(filters.map((filter) => MapEntry(filter, source.size(filter)))); + filtersWithSize.sort(compareFiltersBySize); + filters = filtersWithSize.map((kv) => kv.key).toSet(); + allMapEntries = toGridItem(source, filters); + break; } return allMapEntries; } diff --git a/lib/widgets/filter_grids/common/list_details.dart b/lib/widgets/filter_grids/common/list_details.dart index 3a7678d38..8bce14199 100644 --- a/lib/widgets/filter_grids/common/list_details.dart +++ b/lib/widgets/filter_grids/common/list_details.dart @@ -6,6 +6,7 @@ import 'package:aves/theme/format.dart'; import 'package:aves/theme/icons.dart'; import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/constants.dart'; +import 'package:aves/utils/file_utils.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/fx/borders.dart'; import 'package:aves/widgets/filter_grids/common/list_details_theme.dart'; @@ -140,6 +141,10 @@ class FilterListDetails extends StatelessWidget { child: Center(child: leading ?? const SizedBox()), ); + final l10n = context.l10n; + final locale = l10n.localeName; + final source = context.read(); + return IconTheme.merge( data: detailsTheme.captionIconTheme, child: Row( @@ -147,7 +152,7 @@ class FilterListDetails extends StatelessWidget { leading, const SizedBox(width: 8), Text( - context.l10n.itemCount(context.read().count(filter)), + '${l10n.itemCount(source.count(filter))} • ${formatFileSize(locale, source.size(filter))}', style: detailsTheme.captionStyle, strutStyle: Constants.overflowStrutStyle, softWrap: false, diff --git a/lib/widgets/stats/mime_donut.dart b/lib/widgets/stats/mime_donut.dart index 63fc18299..249d15f5b 100644 --- a/lib/widgets/stats/mime_donut.dart +++ b/lib/widgets/stats/mime_donut.dart @@ -48,7 +48,7 @@ class _MimeDonutState extends State with AutomaticKeepAliveClientMixi final locale = l10n.localeName; final numberFormat = NumberFormat.decimalPattern(locale); - final sum = byMimeTypes.values.fold(0, (prev, v) => prev + v); + final sum = byMimeTypes.values.sum; final colors = context.watch(); final seriesData = byMimeTypes.entries.map((kv) {