diff --git a/lib/model/image_entry.dart b/lib/model/image_entry.dart index 5c4f55d2d..e2cfe22e0 100644 --- a/lib/model/image_entry.dart +++ b/lib/model/image_entry.dart @@ -7,6 +7,7 @@ import 'package:aves/services/metadata_service.dart'; import 'package:aves/services/service_policy.dart'; import 'package:aves/utils/change_notifier.dart'; import 'package:aves/utils/time_utils.dart'; +import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:geocoder/geocoder.dart'; @@ -395,4 +396,19 @@ class ImageEntry { favourites.remove([this]); } } + + static int compareByName(ImageEntry a, ImageEntry b) { + final c = compareAsciiUpperCase(a.bestTitle, b.bestTitle); + return c != 0 ? c : compareAsciiUpperCase(a.extension, b.extension); + } + + static int compareBySize(ImageEntry a, ImageEntry b) { + final c = b.sizeBytes.compareTo(a.sizeBytes); + return c != 0 ? c : compareByName(a, b); + } + + static int compareByDate(ImageEntry a, ImageEntry b) { + final c = b.bestDate?.compareTo(a.bestDate) ?? -1; + return c != 0 ? c : compareByName(a, b); + } } diff --git a/lib/model/source/album.dart b/lib/model/source/album.dart index f534beb7e..3369ed290 100644 --- a/lib/model/source/album.dart +++ b/lib/model/source/album.dart @@ -9,13 +9,18 @@ mixin AlbumMixin on SourceBase { List sortedAlbums = List.unmodifiable([]); + int compareAlbumsByName(String a, String b) { + final ua = getUniqueAlbumName(a); + final ub = getUniqueAlbumName(b); + final c = compareAsciiUpperCase(ua, ub); + if (c != 0) return c; + final va = androidFileUtils.getStorageVolume(a)?.path ?? ''; + final vb = androidFileUtils.getStorageVolume(b)?.path ?? ''; + return compareAsciiUpperCase(va, vb); + } + void updateAlbums() { - final sorted = _folderPaths.toList() - ..sort((a, b) { - final ua = getUniqueAlbumName(a); - final ub = getUniqueAlbumName(b); - return compareAsciiUpperCase(ua, ub); - }); + final sorted = _folderPaths.toList()..sort(compareAlbumsByName); sortedAlbums = List.unmodifiable(sorted); invalidateFilterEntryCounts(); eventBus.fire(AlbumsChangedEvent()); diff --git a/lib/model/source/collection_lens.dart b/lib/model/source/collection_lens.dart index 85361c504..21b169c91 100644 --- a/lib/model/source/collection_lens.dart +++ b/lib/model/source/collection_lens.dart @@ -7,7 +7,6 @@ import 'package:aves/model/image_entry.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/tag.dart'; -import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/change_notifier.dart'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; @@ -137,16 +136,13 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel void _applySort() { switch (sortFactor) { case EntrySortFactor.date: - _filteredEntries.sort((a, b) { - final c = b.bestDate?.compareTo(a.bestDate) ?? -1; - return c != 0 ? c : compareAsciiUpperCase(a.bestTitle, b.bestTitle); - }); + _filteredEntries.sort(ImageEntry.compareByDate); break; case EntrySortFactor.size: - _filteredEntries.sort((a, b) => b.sizeBytes.compareTo(a.sizeBytes)); + _filteredEntries.sort(ImageEntry.compareBySize); break; case EntrySortFactor.name: - _filteredEntries.sort((a, b) => compareAsciiUpperCase(a.bestTitle, b.bestTitle)); + _filteredEntries.sort(ImageEntry.compareByName); break; } } @@ -178,16 +174,7 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel break; case EntrySortFactor.name: final byAlbum = groupBy(_filteredEntries, (entry) => entry.directory); - int compare(a, b) { - final ua = source.getUniqueAlbumName(a); - final ub = source.getUniqueAlbumName(b); - final c = compareAsciiUpperCase(ua, ub); - if (c != 0) return c; - final va = androidFileUtils.getStorageVolume(a)?.path ?? ''; - final vb = androidFileUtils.getStorageVolume(b)?.path ?? ''; - return compareAsciiUpperCase(va, vb); - } - sections = SplayTreeMap.of(byAlbum, compare); + sections = SplayTreeMap>.of(byAlbum, source.compareAlbumsByName); break; } sections = Map.unmodifiable(sections); diff --git a/lib/widgets/filter_grids/albums_page.dart b/lib/widgets/filter_grids/albums_page.dart index b736fcd5f..e623a4d6a 100644 --- a/lib/widgets/filter_grids/albums_page.dart +++ b/lib/widgets/filter_grids/albums_page.dart @@ -68,8 +68,8 @@ class AlbumListPage extends StatelessWidget { entriesByDate.firstWhere((entry) => entry.directory == album, orElse: () => null), )); final byPin = groupBy, bool>(allAlbumMapEntries, (e) => pinned.contains(e.key)); - final pinnedMapEntries = (byPin[true] ?? [])..sort(FilterNavigationPage.compareChipByDate); - final unpinnedMapEntries = (byPin[false] ?? [])..sort(FilterNavigationPage.compareChipByDate); + final pinnedMapEntries = (byPin[true] ?? [])..sort(FilterNavigationPage.compareChipsByDate); + final unpinnedMapEntries = (byPin[false] ?? [])..sort(FilterNavigationPage.compareChipsByDate); return Map.fromEntries([...pinnedMapEntries, ...unpinnedMapEntries]); case ChipSortFactor.name: default: diff --git a/lib/widgets/filter_grids/common/filter_grid_page.dart b/lib/widgets/filter_grids/common/filter_grid_page.dart index 64f2ee751..9acc8a89d 100644 --- a/lib/widgets/filter_grids/common/filter_grid_page.dart +++ b/lib/widgets/filter_grids/common/filter_grid_page.dart @@ -136,7 +136,7 @@ class FilterNavigationPage extends StatelessWidget { )); } - static int compareChipByDate(MapEntry a, MapEntry b) { + static int compareChipsByDate(MapEntry a, MapEntry b) { final c = b.value.bestDate?.compareTo(a.value.bestDate) ?? -1; return c != 0 ? c : compareAsciiUpperCase(a.key, b.key); } diff --git a/lib/widgets/filter_grids/countries_page.dart b/lib/widgets/filter_grids/countries_page.dart index 482a477ed..783e79429 100644 --- a/lib/widgets/filter_grids/countries_page.dart +++ b/lib/widgets/filter_grids/countries_page.dart @@ -71,8 +71,8 @@ class CountryListPage extends StatelessWidget { switch (settings.countrySortFactor) { case ChipSortFactor.date: - pinnedMapEntries.sort(FilterNavigationPage.compareChipByDate); - unpinnedMapEntries.sort(FilterNavigationPage.compareChipByDate); + pinnedMapEntries.sort(FilterNavigationPage.compareChipsByDate); + unpinnedMapEntries.sort(FilterNavigationPage.compareChipsByDate); break; case ChipSortFactor.name: // already sorted by name at the source level diff --git a/lib/widgets/filter_grids/tags_page.dart b/lib/widgets/filter_grids/tags_page.dart index 366e4d8ca..9f8cb47a8 100644 --- a/lib/widgets/filter_grids/tags_page.dart +++ b/lib/widgets/filter_grids/tags_page.dart @@ -67,8 +67,8 @@ class TagListPage extends StatelessWidget { switch (settings.tagSortFactor) { case ChipSortFactor.date: - pinnedMapEntries.sort(FilterNavigationPage.compareChipByDate); - unpinnedMapEntries.sort(FilterNavigationPage.compareChipByDate); + pinnedMapEntries.sort(FilterNavigationPage.compareChipsByDate); + unpinnedMapEntries.sort(FilterNavigationPage.compareChipsByDate); break; case ChipSortFactor.name: // already sorted by name at the source level diff --git a/lib/widgets/fullscreen/info/metadata_section.dart b/lib/widgets/fullscreen/info/metadata_section.dart index 11bfda26d..c4f369611 100644 --- a/lib/widgets/fullscreen/info/metadata_section.dart +++ b/lib/widgets/fullscreen/info/metadata_section.dart @@ -6,6 +6,7 @@ import 'package:aves/services/metadata_service.dart'; import 'package:aves/widgets/common/highlight_title.dart'; import 'package:aves/widgets/common/icons.dart'; import 'package:aves/widgets/fullscreen/info/info_page.dart'; +import 'package:collection/collection.dart'; import 'package:expansion_tile_card/expansion_tile_card.dart'; import 'package:flutter/material.dart'; @@ -126,7 +127,7 @@ class _MetadataSectionSliverState extends State with Auto }).where((kv) => kv != null))); return _MetadataDirectory(directoryName, tags); }).toList() - ..sort((a, b) => a.name.compareTo(b.name)); + ..sort((a, b) => compareAsciiUpperCase(a.name, b.name)); _loadedMetadataUri = widget.entry.uri; } else { _metadata = [];