#935 hidden items can be toggled

This commit is contained in:
Thibault Deckers 2024-03-23 22:26:52 +01:00
parent b5dbac1e2b
commit 55c96ad1c1
7 changed files with 118 additions and 58 deletions

View file

@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Added ### Added
- Collection: support for Fairphone burst pattern - Collection: support for Fairphone burst pattern
- Settings: hidden items can be toggled
### Changed ### Changed

View file

@ -1,10 +1,9 @@
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/settings/defaults.dart'; import 'package:aves/model/settings/defaults.dart';
import 'package:aves/model/settings/modules/search.dart';
import 'package:aves_model/aves_model.dart'; import 'package:aves_model/aves_model.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
mixin FilterGridsSettings on SettingsAccess, SearchSettings { mixin FilterGridsSettings on SettingsAccess {
AlbumChipGroupFactor get albumGroupFactor => getEnumOrDefault(SettingKeys.albumGroupFactorKey, SettingsDefaults.albumGroupFactor, AlbumChipGroupFactor.values); AlbumChipGroupFactor get albumGroupFactor => getEnumOrDefault(SettingKeys.albumGroupFactorKey, SettingsDefaults.albumGroupFactor, AlbumChipGroupFactor.values);
set albumGroupFactor(AlbumChipGroupFactor newValue) => set(SettingKeys.albumGroupFactorKey, newValue.toString()); set albumGroupFactor(AlbumChipGroupFactor newValue) => set(SettingKeys.albumGroupFactorKey, newValue.toString());
@ -53,21 +52,6 @@ mixin FilterGridsSettings on SettingsAccess, SearchSettings {
set pinnedFilters(Set<CollectionFilter> newValue) => set(SettingKeys.pinnedFiltersKey, newValue.map((filter) => filter.toJson()).toList()); set pinnedFilters(Set<CollectionFilter> newValue) => set(SettingKeys.pinnedFiltersKey, newValue.map((filter) => filter.toJson()).toList());
Set<CollectionFilter> get hiddenFilters => (getStringList(SettingKeys.hiddenFiltersKey) ?? []).map(CollectionFilter.fromJson).whereNotNull().toSet();
set hiddenFilters(Set<CollectionFilter> newValue) => set(SettingKeys.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;
}
bool get showAlbumPickQuery => getBool(SettingKeys.showAlbumPickQueryKey) ?? false; bool get showAlbumPickQuery => getBool(SettingKeys.showAlbumPickQueryKey) ?? false;
set showAlbumPickQuery(bool newValue) => set(SettingKeys.showAlbumPickQueryKey, newValue); set showAlbumPickQuery(bool newValue) => set(SettingKeys.showAlbumPickQueryKey, newValue);

View file

@ -0,0 +1,42 @@
import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/settings/modules/search.dart';
import 'package:aves_model/aves_model.dart';
import 'package:collection/collection.dart';
mixin PrivacySettings on SettingsAccess, SearchSettings {
Set<CollectionFilter> get hiddenFilters => (getStringList(SettingKeys.hiddenFiltersKey) ?? []).map(CollectionFilter.fromJson).whereNotNull().toSet();
set hiddenFilters(Set<CollectionFilter> newValue) => set(SettingKeys.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);
final _deactivatedHiddenFilters = deactivatedHiddenFilters;
_deactivatedHiddenFilters.removeAll(filters);
deactivatedHiddenFilters = _deactivatedHiddenFilters;
}
hiddenFilters = _hiddenFilters;
}
Set<CollectionFilter> get deactivatedHiddenFilters => (getStringList(SettingKeys.deactivatedHiddenFiltersKey) ?? []).map(CollectionFilter.fromJson).whereNotNull().toSet();
set deactivatedHiddenFilters(Set<CollectionFilter> newValue) => set(SettingKeys.deactivatedHiddenFiltersKey, newValue.map((filter) => filter.toJson()).toList());
void activateHiddenFilter(CollectionFilter filter, bool active) {
final _deactivatedHiddenFilters = deactivatedHiddenFilters;
if (active) {
_deactivatedHiddenFilters.remove(filter);
} else {
_deactivatedHiddenFilters.add(filter);
}
deactivatedHiddenFilters = _deactivatedHiddenFilters;
final visible = !active;
changeFilterVisibility({filter}, visible);
}
}

View file

@ -15,6 +15,7 @@ import 'package:aves/model/settings/modules/display.dart';
import 'package:aves/model/settings/modules/filter_grids.dart'; import 'package:aves/model/settings/modules/filter_grids.dart';
import 'package:aves/model/settings/modules/info.dart'; import 'package:aves/model/settings/modules/info.dart';
import 'package:aves/model/settings/modules/navigation.dart'; import 'package:aves/model/settings/modules/navigation.dart';
import 'package:aves/model/settings/modules/privacy.dart';
import 'package:aves/model/settings/modules/search.dart'; import 'package:aves/model/settings/modules/search.dart';
import 'package:aves/model/settings/modules/viewer.dart'; import 'package:aves/model/settings/modules/viewer.dart';
import 'package:aves/ref/bursts.dart'; import 'package:aves/ref/bursts.dart';
@ -37,7 +38,7 @@ import 'package:latlong2/latlong.dart';
final Settings settings = Settings._private(); final Settings settings = Settings._private();
class Settings with ChangeNotifier, SettingsAccess, AppSettings, DisplaySettings, NavigationSettings, SearchSettings, CollectionSettings, FilterGridsSettings, ViewerSettings, VideoSettings, SubtitlesSettings, InfoSettings { class Settings with ChangeNotifier, SettingsAccess, AppSettings, DisplaySettings, NavigationSettings, SearchSettings, CollectionSettings, FilterGridsSettings, PrivacySettings, ViewerSettings, VideoSettings, SubtitlesSettings, InfoSettings {
final List<StreamSubscription> _subscriptions = []; final List<StreamSubscription> _subscriptions = [];
final EventChannel _platformSettingsChangeChannel = const OptionalEventChannel('deckers.thibault/aves/settings_change'); final EventChannel _platformSettingsChangeChannel = const OptionalEventChannel('deckers.thibault/aves/settings_change');
final StreamController<SettingsChangedEvent> _updateStreamController = StreamController.broadcast(); final StreamController<SettingsChangedEvent> _updateStreamController = StreamController.broadcast();

View file

@ -69,6 +69,7 @@ class _DebugSettingsSectionState extends State<DebugSettingsSection> with Automa
'drawerPageBookmarks': toMultiline(settings.drawerPageBookmarks), 'drawerPageBookmarks': toMultiline(settings.drawerPageBookmarks),
'pinnedFilters': toMultiline(settings.pinnedFilters), 'pinnedFilters': toMultiline(settings.pinnedFilters),
'hiddenFilters': toMultiline(settings.hiddenFilters), 'hiddenFilters': toMultiline(settings.hiddenFilters),
'deactivatedHiddenFilters': toMultiline(settings.deactivatedHiddenFilters),
'searchHistory': toMultiline(settings.searchHistory), 'searchHistory': toMultiline(settings.searchHistory),
'recentDestinationAlbums': toMultiline(settings.recentDestinationAlbums), 'recentDestinationAlbums': toMultiline(settings.recentDestinationAlbums),
'recentTags': toMultiline(settings.recentTags), 'recentTags': toMultiline(settings.recentTags),

View file

@ -58,50 +58,77 @@ class _HiddenFilters extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool filterPredicate(CollectionFilter v) => v is! PathFilter;
return Selector<Settings, Set<CollectionFilter>>( return Selector<Settings, Set<CollectionFilter>>(
selector: (context, s) => settings.hiddenFilters.where((v) => v is! PathFilter).toSet(), selector: (context, s) => settings.hiddenFilters.where(filterPredicate).toSet(),
builder: (context, hiddenFilters, child) { builder: (context, activatedHiddenFilters, child) {
if (hiddenFilters.isEmpty) { return Selector<Settings, Set<CollectionFilter>>(
return Column( selector: (context, s) => settings.deactivatedHiddenFilters.where(filterPredicate).toSet(),
crossAxisAlignment: CrossAxisAlignment.start, builder: (context, deactivatedHiddenFilters, child) {
children: [ final allHiddenFilters = {
_Banner(bannerText: context.l10n.settingsHiddenFiltersBanner), ...activatedHiddenFilters,
const Divider(height: 0), ...deactivatedHiddenFilters,
Expanded( };
child: Padding( if (allHiddenFilters.isEmpty) {
padding: const EdgeInsets.all(8), return Column(
child: EmptyContent( crossAxisAlignment: CrossAxisAlignment.start,
icon: AIcons.hide, children: [
text: context.l10n.settingsHiddenFiltersEmpty, _Banner(bannerText: context.l10n.settingsHiddenFiltersBanner),
const Divider(height: 0),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8),
child: EmptyContent(
icon: AIcons.hide,
text: context.l10n.settingsHiddenFiltersEmpty,
),
),
), ),
), ],
), );
], }
);
}
final filterList = hiddenFilters.toList()..sort(); final filterList = allHiddenFilters.toList()..sort();
return ListView( return ListView(
children: [ children: [
_Banner(bannerText: context.l10n.settingsHiddenFiltersBanner), _Banner(bannerText: context.l10n.settingsHiddenFiltersBanner),
const Divider(height: 0), const Divider(height: 0),
Padding( const SizedBox(height: 8),
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8), ...filterList.map((filter) {
child: Wrap(
spacing: 8,
runSpacing: 8,
children: filterList.map((filter) {
void onRemove(CollectionFilter filter) => settings.changeFilterVisibility({filter}, true); void onRemove(CollectionFilter filter) => settings.changeFilterVisibility({filter}, true);
return AvesFilterChip( return Padding(
filter: filter, padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
onTap: onRemove, child: Row(
onRemove: onRemove, children: [
onLongPress: null, Expanded(
child: LayoutBuilder(builder: (context, constraints) {
debugPrint('TLAD constraints=$constraints');
return Row(
children: [
AvesFilterChip(
filter: filter,
maxWidth: constraints.maxWidth,
onTap: onRemove,
onRemove: onRemove,
onLongPress: null,
),
const Spacer(),
],
);
}),
),
const SizedBox(width: 8),
Switch(
value: activatedHiddenFilters.contains(filter),
onChanged: (v) => settings.activateHiddenFilter(filter, v),
),
],
),
); );
}).toList(), }),
), ],
), );
], },
); );
}, },
); );
@ -114,7 +141,10 @@ class _HiddenPaths extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Selector<Settings, Set<PathFilter>>( return Selector<Settings, Set<PathFilter>>(
selector: (context, s) => settings.hiddenFilters.whereType<PathFilter>().toSet(), selector: (context, s) => {
...settings.hiddenFilters,
...settings.deactivatedHiddenFilters,
}.whereType<PathFilter>().toSet(),
builder: (context, hiddenPaths, child) { builder: (context, hiddenPaths, child) {
final pathList = hiddenPaths.toList()..sort(); final pathList = hiddenPaths.toList()..sort();
return Column( return Column(

View file

@ -83,6 +83,7 @@ class SettingKeys {
static const tagSortReverseKey = 'tag_sort_reverse'; static const tagSortReverseKey = 'tag_sort_reverse';
static const pinnedFiltersKey = 'pinned_filters'; static const pinnedFiltersKey = 'pinned_filters';
static const hiddenFiltersKey = 'hidden_filters'; static const hiddenFiltersKey = 'hidden_filters';
static const deactivatedHiddenFiltersKey = 'deactivated_hidden_filters';
static const showAlbumPickQueryKey = 'show_album_pick_query'; static const showAlbumPickQueryKey = 'show_album_pick_query';
// viewer // viewer