diff --git a/lib/model/grouping/common.dart b/lib/model/grouping/common.dart index cc4af8bc5..423d86fbd 100644 --- a/lib/model/grouping/common.dart +++ b/lib/model/grouping/common.dart @@ -29,22 +29,17 @@ class FilterGrouping with ChangeNotifier { final T Function(Uri uri, SetOrFilter filter) _createGroupFilter; final Map> _groups = {}; + Map> get allGroups => Map.unmodifiable(_groups); + FilterGrouping._private(this._host, this._createGroupFilter) { if (kFlutterMemoryAllocationsEnabled) ChangeNotifier.maybeDispatchObjectCreation(this); } - static FilterGrouping? forUri(Uri uri) { - switch (uri.host) { - case hostAlbums: - return albumGrouping; - default: - return null; - } + void init(Map> groups) { + _groups.clear(); + _groups.addAll(groups); } - void clear() => _groups.clear(); - - // TODO TLAD [nested] invalidate summary for derived filters (parent groups, dynamic albums) void addToGroup(Set childrenUris, Uri? destinationGroup) { _removeFromGroups(childrenUris); if (destinationGroup != null) { @@ -60,10 +55,10 @@ class FilterGrouping with ChangeNotifier { void rename(Uri oldUri, Uri newUri) { final childrenUris = _groups[oldUri]; - if (childrenUris != null) { - // local copy to prevent concurrent modification - addToGroup(Set.of(childrenUris), newUri); - } + if (childrenUris == null) return; + + // local copy to prevent concurrent modification + addToGroup(Set.of(childrenUris), newUri); eventBus.fire(GroupUriChangedEvent(oldUri, newUri)); } @@ -243,10 +238,19 @@ class FilterGrouping with ChangeNotifier { return null; } + static FilterGrouping? forUri(Uri uri) { + switch (uri.host) { + case hostAlbums: + return albumGrouping; + default: + return null; + } + } + // serialization static String toJson(Map> groups) => jsonEncode(groups.map((parentUri, childrenUris) { - return MapEntry(parentUri.toString(), childrenUris.map((v) => v.toString())); + return MapEntry(parentUri.toString(), childrenUris.map((v) => v.toString()).toList()); })); static Map>? fromJson(String? jsonString) { diff --git a/lib/model/settings/modules/filter_grids.dart b/lib/model/settings/modules/filter_grids.dart index 4af197ded..75784ded8 100644 --- a/lib/model/settings/modules/filter_grids.dart +++ b/lib/model/settings/modules/filter_grids.dart @@ -7,9 +7,9 @@ import 'package:aves_model/aves_model.dart'; import 'package:synchronized/synchronized.dart'; mixin FilterGridsSettings on SettingsAccess { - AlbumChipSectionFactor get albumSectionFactor => getEnumOrDefault(SettingKeys.albumGroupFactorKey, SettingsDefaults.albumGroupFactor, AlbumChipSectionFactor.values); + AlbumChipSectionFactor get albumSectionFactor => getEnumOrDefault(SettingKeys.albumSectionFactorKey, SettingsDefaults.albumGroupFactor, AlbumChipSectionFactor.values); - set albumSectionFactor(AlbumChipSectionFactor newValue) => set(SettingKeys.albumGroupFactorKey, newValue.toString()); + set albumSectionFactor(AlbumChipSectionFactor newValue) => set(SettingKeys.albumSectionFactorKey, newValue.toString()); ChipSortFactor get albumSortFactor => getEnumOrDefault(SettingKeys.albumSortFactorKey, SettingsDefaults.chipListSortFactor, ChipSortFactor.values); @@ -59,7 +59,11 @@ mixin FilterGridsSettings on SettingsAccess { void setShowTitleQuery(String routeName, bool newValue) => set(SettingKeys.showTitleQueryPrefixKey + routeName, newValue); - // TODO TLAD [nested] save/load + Map> get albumGroups => FilterGrouping.fromJson(getString(SettingKeys.albumGroupsKey)) ?? {}; + + set albumGroups(Map> groups) => set(SettingKeys.albumGroupsKey, FilterGrouping.toJson(groups)); + + // listening final _lockForPins = Lock(); @@ -97,4 +101,6 @@ mixin FilterGridsSettings on SettingsAccess { } }); } + + void saveAlbumGroups() => albumGroups = albumGrouping.allGroups; } diff --git a/lib/model/settings/modules/navigation.dart b/lib/model/settings/modules/navigation.dart index aa61440f2..af7c9a4e7 100644 --- a/lib/model/settings/modules/navigation.dart +++ b/lib/model/settings/modules/navigation.dart @@ -77,6 +77,8 @@ mixin NavigationSettings on SettingsAccess { set drawerPageBookmarks(List newValue) => set(SettingKeys.drawerPageBookmarksKey, newValue); + // listening + final _lockForBookmarks = Lock(); Future updateBookmarkedDynamicAlbums(Map changes) async { diff --git a/lib/model/settings/settings.dart b/lib/model/settings/settings.dart index 80e36acf4..873900386 100644 --- a/lib/model/settings/settings.dart +++ b/lib/model/settings/settings.dart @@ -69,9 +69,20 @@ class Settings with ChangeNotifier, SettingsAccess, SearchSettings, AppSettings, Future init({required bool monitorPlatformSettings}) async { await store.init(); resetAppliedLocale(); + _unregister(); + _register(monitorPlatformSettings); + initAppSettings(); + } + + void _unregister() { + albumGrouping.removeListener(saveAlbumGroups); _subscriptions ..forEach((sub) => sub.cancel()) ..clear(); + } + + void _register(bool monitorPlatformSettings) { + albumGrouping.addListener(saveAlbumGroups); _subscriptions.add(dynamicAlbums.eventBus.on().listen((e) { final changes = e.changes; updateBookmarkedDynamicAlbums(changes); @@ -86,7 +97,6 @@ class Settings with ChangeNotifier, SettingsAccess, SearchSettings, AppSettings, if (monitorPlatformSettings) { _subscriptions.add(_platformSettingsChangeChannel.receiveBroadcastStream().listen((event) => _onPlatformSettingsChanged(event as Map?))); } - initAppSettings(); } Future reload() => store.reload(); @@ -387,12 +397,13 @@ class Settings with ChangeNotifier, SettingsAccess, SearchSettings, AppSettings, case SettingKeys.collectionSortFactorKey: case SettingKeys.thumbnailLocationIconKey: case SettingKeys.thumbnailTagIconKey: - case SettingKeys.albumGroupFactorKey: + case SettingKeys.albumSectionFactorKey: case SettingKeys.albumSortFactorKey: case SettingKeys.countrySortFactorKey: case SettingKeys.stateSortFactorKey: case SettingKeys.placeSortFactorKey: case SettingKeys.tagSortFactorKey: + case SettingKeys.albumGroupsKey: case SettingKeys.imageBackgroundKey: case SettingKeys.videoAutoPlayModeKey: case SettingKeys.videoBackgroundModeKey: diff --git a/lib/model/source/media_store_source.dart b/lib/model/source/media_store_source.dart index e0b2887f8..eb53c729e 100644 --- a/lib/model/source/media_store_source.dart +++ b/lib/model/source/media_store_source.dart @@ -6,6 +6,7 @@ import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/origins.dart'; import 'package:aves/model/favourites.dart'; import 'package:aves/model/filters/covered/stored_album.dart'; +import 'package:aves/model/grouping/common.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/analysis_controller.dart'; import 'package:aves/model/source/collection_source.dart'; @@ -59,6 +60,7 @@ class MediaStoreSource extends CollectionSource { await localMediaDb.init(); await vaults.init(); await favourites.init(); + albumGrouping.init(settings.albumGroups); await covers.init(); await dynamicAlbums.init(); diff --git a/lib/widgets/debug/settings.dart b/lib/widgets/debug/settings.dart index 4c7bf2a81..9a412b17a 100644 --- a/lib/widgets/debug/settings.dart +++ b/lib/widgets/debug/settings.dart @@ -77,6 +77,7 @@ class _DebugSettingsSectionState extends State with Automa 'systemLocales': '${WidgetsBinding.instance.platformDispatcher.locales}', 'topEntryIds': '${settings.topEntryIds}', 'longPressTimeout': '${settings.longPressTimeout}', + 'albumGroups': toMultiline(settings.albumGroups.entries), }, ), ), diff --git a/plugins/aves_model/lib/src/settings/keys.dart b/plugins/aves_model/lib/src/settings/keys.dart index f28cf8163..0528d14e3 100644 --- a/plugins/aves_model/lib/src/settings/keys.dart +++ b/plugins/aves_model/lib/src/settings/keys.dart @@ -76,7 +76,7 @@ class SettingKeys { static const showThumbnailVideoDurationKey = 'show_thumbnail_video_duration'; // filter grids - static const albumGroupFactorKey = 'album_group_factor'; + static const albumSectionFactorKey = 'album_section_factor'; static const albumSortFactorKey = 'album_sort_factor'; static const countrySortFactorKey = 'country_sort_factor'; static const stateSortFactorKey = 'state_sort_factor'; @@ -87,6 +87,7 @@ class SettingKeys { static const stateSortReverseKey = 'state_sort_reverse'; static const placeSortReverseKey = 'place_sort_reverse'; static const tagSortReverseKey = 'tag_sort_reverse'; + static const albumGroupsKey = 'album_groups'; static const pinnedFiltersKey = 'pinned_filters'; static const hiddenFiltersKey = 'hidden_filters'; static const deactivatedHiddenFiltersKey = 'deactivated_hidden_filters'; diff --git a/test/model/filters_test.dart b/test/model/filters_test.dart index 25743810b..a793f3005 100644 --- a/test/model/filters_test.dart +++ b/test/model/filters_test.dart @@ -35,7 +35,7 @@ void main() { }); tearDown(() async { - albumGrouping.clear(); + albumGrouping.init({}); await getIt.reset(); }); diff --git a/test/model/grouping/common_test.dart b/test/model/grouping/common_test.dart index e1565981d..1a3b24763 100644 --- a/test/model/grouping/common_test.dart +++ b/test/model/grouping/common_test.dart @@ -23,7 +23,7 @@ void main() { }); tearDown(() async { - albumGrouping.clear(); + albumGrouping.init({}); await dynamicAlbums.clear(); await getIt.reset(); });