#935 hidden items can be toggled
This commit is contained in:
parent
b5dbac1e2b
commit
55c96ad1c1
7 changed files with 118 additions and 58 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
42
lib/model/settings/modules/privacy.dart
Normal file
42
lib/model/settings/modules/privacy.dart
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue