fixed source update on hidden filter import
This commit is contained in:
parent
d110695d53
commit
6b4d9c0bc3
11 changed files with 86 additions and 72 deletions
|
@ -20,9 +20,9 @@ final Settings settings = Settings._private();
|
|||
|
||||
class Settings extends ChangeNotifier {
|
||||
final EventChannel _platformSettingsChangeChannel = const EventChannel('deckers.thibault/aves/settings_change');
|
||||
final StreamController<String> _updateStreamController = StreamController<String>.broadcast();
|
||||
final StreamController<SettingsChangedEvent> _updateStreamController = StreamController<SettingsChangedEvent>.broadcast();
|
||||
|
||||
Stream<String> get updateStream => _updateStreamController.stream;
|
||||
Stream<SettingsChangedEvent> get updateStream => _updateStreamController.stream;
|
||||
|
||||
Settings._private();
|
||||
|
||||
|
@ -356,6 +356,17 @@ class Settings extends ChangeNotifier {
|
|||
|
||||
set hiddenFilters(Set<CollectionFilter> newValue) => setAndNotify(hiddenFiltersKey, newValue.map((filter) => filter.toJson()).toList());
|
||||
|
||||
void changeFilterVisibility(Set<CollectionFilter> filters, bool visible) {
|
||||
final _hiddenFilters = hiddenFilters;
|
||||
if (visible) {
|
||||
_hiddenFilters.removeAll(filters);
|
||||
} else {
|
||||
_hiddenFilters.addAll(filters);
|
||||
searchHistory = searchHistory..removeWhere(filters.contains);
|
||||
}
|
||||
hiddenFilters = _hiddenFilters;
|
||||
}
|
||||
|
||||
// viewer
|
||||
|
||||
List<EntryAction> get viewerQuickActions => getEnumListOrDefault(viewerQuickActionsKey, SettingsDefaults.viewerQuickActions, EntryAction.values);
|
||||
|
@ -540,7 +551,7 @@ class Settings extends ChangeNotifier {
|
|||
settingsStore.setBool(key, newValue);
|
||||
}
|
||||
if (oldValue != newValue) {
|
||||
_updateStreamController.add(key);
|
||||
_updateStreamController.add(SettingsChangedEvent(key, oldValue, newValue));
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
@ -583,37 +594,39 @@ class Settings extends ChangeNotifier {
|
|||
await reset(includeInternalKeys: false);
|
||||
|
||||
// apply user modifications
|
||||
jsonMap.forEach((key, value) {
|
||||
if (value == null) {
|
||||
jsonMap.forEach((key, newValue) {
|
||||
final oldValue = settingsStore.get(key);
|
||||
|
||||
if (newValue == null) {
|
||||
settingsStore.remove(key);
|
||||
} else if (key.startsWith(tileExtentPrefixKey)) {
|
||||
if (value is double) {
|
||||
settingsStore.setDouble(key, value);
|
||||
if (newValue is double) {
|
||||
settingsStore.setDouble(key, newValue);
|
||||
} else {
|
||||
debugPrint('failed to import key=$key, value=$value is not a double');
|
||||
debugPrint('failed to import key=$key, value=$newValue is not a double');
|
||||
}
|
||||
} else if (key.startsWith(tileLayoutPrefixKey)) {
|
||||
if (value is String) {
|
||||
settingsStore.setString(key, value);
|
||||
if (newValue is String) {
|
||||
settingsStore.setString(key, newValue);
|
||||
} else {
|
||||
debugPrint('failed to import key=$key, value=$value is not a string');
|
||||
debugPrint('failed to import key=$key, value=$newValue is not a string');
|
||||
}
|
||||
} else {
|
||||
switch (key) {
|
||||
case subtitleTextColorKey:
|
||||
case subtitleBackgroundColorKey:
|
||||
if (value is int) {
|
||||
settingsStore.setInt(key, value);
|
||||
if (newValue is int) {
|
||||
settingsStore.setInt(key, newValue);
|
||||
} else {
|
||||
debugPrint('failed to import key=$key, value=$value is not an int');
|
||||
debugPrint('failed to import key=$key, value=$newValue is not an int');
|
||||
}
|
||||
break;
|
||||
case subtitleFontSizeKey:
|
||||
case infoMapZoomKey:
|
||||
if (value is double) {
|
||||
settingsStore.setDouble(key, value);
|
||||
if (newValue is double) {
|
||||
settingsStore.setDouble(key, newValue);
|
||||
} else {
|
||||
debugPrint('failed to import key=$key, value=$value is not a double');
|
||||
debugPrint('failed to import key=$key, value=$newValue is not a double');
|
||||
}
|
||||
break;
|
||||
case isInstalledAppAccessAllowedKey:
|
||||
|
@ -638,10 +651,10 @@ class Settings extends ChangeNotifier {
|
|||
case subtitleShowOutlineKey:
|
||||
case saveSearchHistoryKey:
|
||||
case filePickerShowHiddenFilesKey:
|
||||
if (value is bool) {
|
||||
settingsStore.setBool(key, value);
|
||||
if (newValue is bool) {
|
||||
settingsStore.setBool(key, newValue);
|
||||
} else {
|
||||
debugPrint('failed to import key=$key, value=$value is not a bool');
|
||||
debugPrint('failed to import key=$key, value=$newValue is not a bool');
|
||||
}
|
||||
break;
|
||||
case localeKey:
|
||||
|
@ -661,10 +674,10 @@ class Settings extends ChangeNotifier {
|
|||
case unitSystemKey:
|
||||
case accessibilityAnimationsKey:
|
||||
case timeToTakeActionKey:
|
||||
if (value is String) {
|
||||
settingsStore.setString(key, value);
|
||||
if (newValue is String) {
|
||||
settingsStore.setString(key, newValue);
|
||||
} else {
|
||||
debugPrint('failed to import key=$key, value=$value is not a string');
|
||||
debugPrint('failed to import key=$key, value=$newValue is not a string');
|
||||
}
|
||||
break;
|
||||
case confirmationDialogsKey:
|
||||
|
@ -677,17 +690,29 @@ class Settings extends ChangeNotifier {
|
|||
case collectionSelectionQuickActionsKey:
|
||||
case viewerQuickActionsKey:
|
||||
case videoQuickActionsKey:
|
||||
if (value is List) {
|
||||
settingsStore.setStringList(key, value.cast<String>());
|
||||
if (newValue is List) {
|
||||
settingsStore.setStringList(key, newValue.cast<String>());
|
||||
} else {
|
||||
debugPrint('failed to import key=$key, value=$value is not a list');
|
||||
debugPrint('failed to import key=$key, value=$newValue is not a list');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
_updateStreamController.add(key);
|
||||
if (oldValue != newValue) {
|
||||
_updateStreamController.add(SettingsChangedEvent(key, oldValue, newValue));
|
||||
}
|
||||
});
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@immutable
|
||||
class SettingsChangedEvent {
|
||||
final String key;
|
||||
final dynamic oldValue;
|
||||
final dynamic newValue;
|
||||
|
||||
// old and new values as stored, e.g. `List<String>` for collections
|
||||
const SettingsChangedEvent(this.key, this.oldValue, this.newValue);
|
||||
}
|
||||
|
|
|
@ -79,10 +79,10 @@ class CollectionLens with ChangeNotifier {
|
|||
favourites.addListener(_onFavouritesChanged);
|
||||
}
|
||||
_subscriptions.add(settings.updateStream
|
||||
.where([
|
||||
Settings.collectionSortFactorKey,
|
||||
Settings.collectionGroupFactorKey,
|
||||
].contains)
|
||||
.where((event) => [
|
||||
Settings.collectionSortFactorKey,
|
||||
Settings.collectionGroupFactorKey,
|
||||
].contains(event.key))
|
||||
.listen((_) => _onSettingsChanged()));
|
||||
_refresh();
|
||||
}
|
||||
|
|
|
@ -45,7 +45,14 @@ mixin SourceBase {
|
|||
|
||||
abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagMixin, TrashMixin {
|
||||
CollectionSource() {
|
||||
settings.updateStream.where((key) => key == Settings.localeKey).listen((_) => invalidateAlbumDisplayNames());
|
||||
settings.updateStream.where((event) => event.key == Settings.localeKey).listen((_) => invalidateAlbumDisplayNames());
|
||||
settings.updateStream.where((event) => event.key == Settings.hiddenFiltersKey).listen((event) {
|
||||
final oldValue = event.oldValue;
|
||||
if (oldValue is List<String>?) {
|
||||
final oldHiddenFilters = (oldValue ?? []).map(CollectionFilter.fromJson).whereNotNull().toSet();
|
||||
_onFilterVisibilityChanged(oldHiddenFilters, settings.hiddenFilters);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final EventBus _eventBus = EventBus();
|
||||
|
@ -441,20 +448,13 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
|
|||
return recentEntry(filter);
|
||||
}
|
||||
|
||||
void changeFilterVisibility(Set<CollectionFilter> filters, bool visible) {
|
||||
final hiddenFilters = settings.hiddenFilters;
|
||||
if (visible) {
|
||||
hiddenFilters.removeAll(filters);
|
||||
} else {
|
||||
hiddenFilters.addAll(filters);
|
||||
settings.searchHistory = settings.searchHistory..removeWhere(filters.contains);
|
||||
}
|
||||
settings.hiddenFilters = hiddenFilters;
|
||||
void _onFilterVisibilityChanged(Set<CollectionFilter> oldHiddenFilters, Set<CollectionFilter> currentHiddenFilters) {
|
||||
updateDerivedFilters();
|
||||
eventBus.fire(FilterVisibilityChangedEvent(filters, visible));
|
||||
eventBus.fire(const FilterVisibilityChangedEvent());
|
||||
|
||||
if (visible) {
|
||||
final candidateEntries = visibleEntries.where((entry) => filters.any((f) => f.test(entry))).toSet();
|
||||
final newlyVisibleFilters = oldHiddenFilters.whereNot(currentHiddenFilters.contains).toSet();
|
||||
if (newlyVisibleFilters.isNotEmpty) {
|
||||
final candidateEntries = visibleEntries.where((entry) => newlyVisibleFilters.any((f) => f.test(entry))).toSet();
|
||||
analyze(null, entries: candidateEntries);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:aves/model/actions/move_type.dart';
|
||||
import 'package:aves/model/entry.dart';
|
||||
import 'package:aves/model/filters/filters.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
@immutable
|
||||
|
@ -34,10 +33,7 @@ class EntryRefreshedEvent {
|
|||
|
||||
@immutable
|
||||
class FilterVisibilityChangedEvent {
|
||||
final Set<CollectionFilter> filters;
|
||||
final bool visible;
|
||||
|
||||
const FilterVisibilityChangedEvent(this.filters, this.visible);
|
||||
const FilterVisibilityChangedEvent();
|
||||
}
|
||||
|
||||
@immutable
|
||||
|
|
|
@ -229,9 +229,9 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
|||
}
|
||||
}
|
||||
|
||||
settings.updateStream.where((key) => key == Settings.isInstalledAppAccessAllowedKey).listen((_) => applyIsInstalledAppAccessAllowed());
|
||||
settings.updateStream.where((key) => key == Settings.keepScreenOnKey).listen((_) => applyKeepScreenOn());
|
||||
settings.updateStream.where((key) => key == Settings.platformAccelerometerRotationKey).listen((_) => applyIsRotationLocked());
|
||||
settings.updateStream.where((event) => event.key == Settings.isInstalledAppAccessAllowedKey).listen((_) => applyIsInstalledAppAccessAllowed());
|
||||
settings.updateStream.where((event) => event.key == Settings.keepScreenOnKey).listen((_) => applyKeepScreenOn());
|
||||
settings.updateStream.where((event) => event.key == Settings.platformAccelerometerRotationKey).listen((_) => applyIsRotationLocked());
|
||||
|
||||
applyKeepScreenOn();
|
||||
applyIsRotationLocked();
|
||||
|
@ -239,7 +239,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
|||
|
||||
Future<void> _setupErrorReporting() async {
|
||||
await reportService.init();
|
||||
settings.updateStream.where((key) => key == Settings.isErrorReportingAllowedKey).listen(
|
||||
settings.updateStream.where((event) => event.key == Settings.isErrorReportingAllowedKey).listen(
|
||||
(_) => reportService.setCollectionEnabled(settings.isErrorReportingAllowed),
|
||||
);
|
||||
await reportService.setCollectionEnabled(settings.isErrorReportingAllowed);
|
||||
|
|
|
@ -40,7 +40,7 @@ class _CollectionPageState extends State<CollectionPage> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_subscriptions.add(settings.updateStream.where((key) => key == Settings.enableBinKey).listen((_) {
|
||||
_subscriptions.add(settings.updateStream.where((event) => event.key == Settings.enableBinKey).listen((_) {
|
||||
if (!settings.enableBin) {
|
||||
collection.removeFilter(TrashFilter.instance);
|
||||
}
|
||||
|
|
|
@ -132,7 +132,6 @@ class _AppDebugPageState extends State<AppDebugPage> {
|
|||
),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
final source = context.read<CollectionSource>();
|
||||
await source.init();
|
||||
await source.refresh();
|
||||
},
|
||||
|
@ -163,18 +162,16 @@ class _AppDebugPageState extends State<AppDebugPage> {
|
|||
Future<void> _onActionSelected(AppDebugAction action) async {
|
||||
switch (action) {
|
||||
case AppDebugAction.prepScreenshotThumbnails:
|
||||
final source = context.read<CollectionSource>();
|
||||
source.changeFilterVisibility(settings.hiddenFilters, true);
|
||||
source.changeFilterVisibility({
|
||||
settings.changeFilterVisibility(settings.hiddenFilters, true);
|
||||
settings.changeFilterVisibility({
|
||||
TagFilter('aves-thumbnail', not: true),
|
||||
}, false);
|
||||
await favourites.clear();
|
||||
await favourites.add(source.visibleEntries);
|
||||
break;
|
||||
case AppDebugAction.prepScreenshotStats:
|
||||
final source = context.read<CollectionSource>();
|
||||
source.changeFilterVisibility(settings.hiddenFilters, true);
|
||||
source.changeFilterVisibility({
|
||||
settings.changeFilterVisibility(settings.hiddenFilters, true);
|
||||
settings.changeFilterVisibility({
|
||||
PathFilter('/storage/emulated/0/Pictures/Dev'),
|
||||
}, false);
|
||||
break;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:aves/model/actions/chip_actions.dart';
|
||||
import 'package:aves/model/filters/filters.dart';
|
||||
import 'package:aves/model/highlight.dart';
|
||||
import 'package:aves/model/source/collection_source.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/dialogs/aves_dialog.dart';
|
||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||
|
@ -51,8 +51,7 @@ class ChipActionDelegate {
|
|||
);
|
||||
if (confirmed == null || !confirmed) return;
|
||||
|
||||
final source = context.read<CollectionSource>();
|
||||
source.changeFilterVisibility({filter}, false);
|
||||
settings.changeFilterVisibility({filter}, false);
|
||||
}
|
||||
|
||||
void _goTo(
|
||||
|
|
|
@ -271,8 +271,7 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
|||
);
|
||||
if (confirmed == null || !confirmed) return;
|
||||
|
||||
final source = context.read<CollectionSource>();
|
||||
source.changeFilterVisibility(filters, false);
|
||||
settings.changeFilterVisibility(filters, false);
|
||||
|
||||
_browse(context);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:aves/model/filters/filters.dart';
|
||||
import 'package:aves/model/filters/path.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/model/source/collection_source.dart';
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:aves/theme/icons.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
|
@ -116,7 +115,7 @@ class _HiddenFilters extends StatelessWidget {
|
|||
.map((filter) => AvesFilterChip(
|
||||
filter: filter,
|
||||
removable: true,
|
||||
onTap: (filter) => context.read<CollectionSource>().changeFilterVisibility({filter}, true),
|
||||
onTap: (filter) => settings.changeFilterVisibility({filter}, true),
|
||||
onLongPress: null,
|
||||
))
|
||||
.toList(),
|
||||
|
@ -152,7 +151,7 @@ class _HiddenPaths extends StatelessWidget {
|
|||
trailing: IconButton(
|
||||
icon: const Icon(AIcons.clear),
|
||||
onPressed: () {
|
||||
context.read<CollectionSource>().changeFilterVisibility({pathFilter}, true);
|
||||
settings.changeFilterVisibility({pathFilter}, true);
|
||||
},
|
||||
tooltip: context.l10n.actionRemove,
|
||||
),
|
||||
|
@ -176,7 +175,7 @@ class _HiddenPaths extends StatelessWidget {
|
|||
// wait for the dialog to hide as applying the change may block the UI
|
||||
await Future.delayed(Durations.pageTransitionAnimation * timeDilation);
|
||||
if (path != null && path.isNotEmpty) {
|
||||
context.read<CollectionSource>().changeFilterVisibility({PathFilter(path)}, false);
|
||||
settings.changeFilterVisibility({PathFilter(path)}, false);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'package:aves/model/filters/mime.dart';
|
|||
import 'package:aves/model/settings/enums/enums.dart';
|
||||
import 'package:aves/model/settings/enums/video_loop_mode.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/model/source/collection_source.dart';
|
||||
import 'package:aves/theme/colors.dart';
|
||||
import 'package:aves/theme/icons.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
|
@ -36,7 +35,7 @@ class VideoSection extends StatelessWidget {
|
|||
if (!standalonePage)
|
||||
SwitchListTile(
|
||||
value: currentShowVideos,
|
||||
onChanged: (v) => context.read<CollectionSource>().changeFilterVisibility({MimeFilter.video}, v),
|
||||
onChanged: (v) => settings.changeFilterVisibility({MimeFilter.video}, v),
|
||||
title: Text(context.l10n.settingsVideoShowVideos),
|
||||
),
|
||||
const VideoActionsTile(),
|
||||
|
|
Loading…
Reference in a new issue