remember whether to show the title filter when picking albums
This commit is contained in:
parent
a4869bf41a
commit
413d41c78d
7 changed files with 109 additions and 78 deletions
|
@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
- option to set the Tags page as home
|
- option to set the Tags page as home
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- remember whether to show the title filter when picking albums
|
||||||
|
|
||||||
## <a id="v1.8.6"></a>[v1.8.6] - 2023-04-30
|
## <a id="v1.8.6"></a>[v1.8.6] - 2023-04-30
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -8,7 +8,8 @@ class Query extends ChangeNotifier {
|
||||||
final ValueNotifier<String> _queryNotifier = ValueNotifier('');
|
final ValueNotifier<String> _queryNotifier = ValueNotifier('');
|
||||||
final StreamController<bool> _enabledStreamController = StreamController.broadcast();
|
final StreamController<bool> _enabledStreamController = StreamController.broadcast();
|
||||||
|
|
||||||
Query({required String? initialValue}) {
|
Query({required bool enabled, required String? initialValue}) {
|
||||||
|
_enabled = enabled;
|
||||||
if (initialValue != null && initialValue.isNotEmpty) {
|
if (initialValue != null && initialValue.isNotEmpty) {
|
||||||
_enabled = true;
|
_enabled = true;
|
||||||
queryNotifier.value = initialValue;
|
queryNotifier.value = initialValue;
|
||||||
|
|
|
@ -118,6 +118,7 @@ class Settings extends ChangeNotifier {
|
||||||
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 showAlbumPickQueryKey = 'show_album_pick_query';
|
||||||
|
|
||||||
// viewer
|
// viewer
|
||||||
static const viewerQuickActionsKey = 'viewer_quick_actions';
|
static const viewerQuickActionsKey = 'viewer_quick_actions';
|
||||||
|
@ -625,6 +626,10 @@ class Settings extends ChangeNotifier {
|
||||||
hiddenFilters = _hiddenFilters;
|
hiddenFilters = _hiddenFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get showAlbumPickQuery => getBool(showAlbumPickQueryKey) ?? false;
|
||||||
|
|
||||||
|
set showAlbumPickQuery(bool newValue) => _set(showAlbumPickQueryKey, newValue);
|
||||||
|
|
||||||
// viewer
|
// viewer
|
||||||
|
|
||||||
List<EntryAction> get viewerQuickActions => getEnumListOrDefault(viewerQuickActionsKey, SettingsDefaults.viewerQuickActions, EntryAction.values);
|
List<EntryAction> get viewerQuickActions => getEnumListOrDefault(viewerQuickActionsKey, SettingsDefaults.viewerQuickActions, EntryAction.values);
|
||||||
|
@ -1107,6 +1112,7 @@ class Settings extends ChangeNotifier {
|
||||||
case stateSortReverseKey:
|
case stateSortReverseKey:
|
||||||
case placeSortReverseKey:
|
case placeSortReverseKey:
|
||||||
case tagSortReverseKey:
|
case tagSortReverseKey:
|
||||||
|
case showAlbumPickQueryKey:
|
||||||
case showOverlayOnOpeningKey:
|
case showOverlayOnOpeningKey:
|
||||||
case showOverlayMinimapKey:
|
case showOverlayMinimapKey:
|
||||||
case showOverlayInfoKey:
|
case showOverlayInfoKey:
|
||||||
|
|
|
@ -3,19 +3,24 @@ import 'package:flutter/widgets.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class QueryProvider extends StatelessWidget {
|
class QueryProvider extends StatelessWidget {
|
||||||
|
final bool enabled;
|
||||||
final String? initialQuery;
|
final String? initialQuery;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
const QueryProvider({
|
const QueryProvider({
|
||||||
super.key,
|
super.key,
|
||||||
required this.initialQuery,
|
this.enabled = false,
|
||||||
|
this.initialQuery,
|
||||||
required this.child,
|
required this.child,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ChangeNotifierProvider<Query>(
|
return ChangeNotifierProvider<Query>(
|
||||||
create: (context) => Query(initialValue: initialQuery),
|
create: (context) => Query(
|
||||||
|
enabled: enabled,
|
||||||
|
initialValue: initialQuery,
|
||||||
|
),
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
||||||
import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';
|
import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';
|
||||||
import 'package:aves/widgets/common/identity/empty.dart';
|
import 'package:aves/widgets/common/identity/empty.dart';
|
||||||
|
import 'package:aves/widgets/common/providers/query_provider.dart';
|
||||||
import 'package:aves/widgets/common/providers/selection_provider.dart';
|
import 'package:aves/widgets/common/providers/selection_provider.dart';
|
||||||
import 'package:aves/widgets/dialogs/aves_confirmation_dialog.dart';
|
import 'package:aves/widgets/dialogs/aves_confirmation_dialog.dart';
|
||||||
import 'package:aves/widgets/dialogs/filter_editors/create_album_dialog.dart';
|
import 'package:aves/widgets/dialogs/filter_editors/create_album_dialog.dart';
|
||||||
|
@ -106,28 +107,31 @@ class _AlbumPickPageState extends State<_AlbumPickPage> {
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
final gridItems = AlbumListPage.getAlbumGridItems(context, source);
|
final gridItems = AlbumListPage.getAlbumGridItems(context, source);
|
||||||
return SelectionProvider<FilterGridItem<AlbumFilter>>(
|
return SelectionProvider<FilterGridItem<AlbumFilter>>(
|
||||||
child: FilterGridPage<AlbumFilter>(
|
child: QueryProvider(
|
||||||
settingsRouteKey: AlbumListPage.routeName,
|
enabled: settings.showAlbumPickQuery,
|
||||||
appBar: FilterGridAppBar(
|
child: FilterGridPage<AlbumFilter>(
|
||||||
source: source,
|
settingsRouteKey: AlbumListPage.routeName,
|
||||||
title: title,
|
appBar: FilterGridAppBar(
|
||||||
actionDelegate: AlbumChipSetActionDelegate(gridItems),
|
source: source,
|
||||||
actionsBuilder: _buildActions,
|
title: title,
|
||||||
isEmpty: false,
|
actionDelegate: _AlbumChipSetPickActionDelegate(gridItems),
|
||||||
|
actionsBuilder: _buildActions,
|
||||||
|
isEmpty: false,
|
||||||
|
appBarHeightNotifier: _appBarHeightNotifier,
|
||||||
|
),
|
||||||
appBarHeightNotifier: _appBarHeightNotifier,
|
appBarHeightNotifier: _appBarHeightNotifier,
|
||||||
|
sections: AlbumListPage.groupToSections(context, source, gridItems),
|
||||||
|
newFilters: source.getNewAlbumFilters(context),
|
||||||
|
sortFactor: settings.albumSortFactor,
|
||||||
|
showHeaders: settings.albumGroupFactor != AlbumChipGroupFactor.none,
|
||||||
|
selectable: false,
|
||||||
|
applyQuery: AlbumListPage.applyQuery,
|
||||||
|
emptyBuilder: () => EmptyContent(
|
||||||
|
icon: AIcons.album,
|
||||||
|
text: context.l10n.albumEmpty,
|
||||||
|
),
|
||||||
|
heroType: HeroType.never,
|
||||||
),
|
),
|
||||||
appBarHeightNotifier: _appBarHeightNotifier,
|
|
||||||
sections: AlbumListPage.groupToSections(context, source, gridItems),
|
|
||||||
newFilters: source.getNewAlbumFilters(context),
|
|
||||||
sortFactor: settings.albumSortFactor,
|
|
||||||
showHeaders: settings.albumGroupFactor != AlbumChipGroupFactor.none,
|
|
||||||
selectable: false,
|
|
||||||
applyQuery: AlbumListPage.applyQuery,
|
|
||||||
emptyBuilder: () => EmptyContent(
|
|
||||||
icon: AIcons.album,
|
|
||||||
text: context.l10n.albumEmpty,
|
|
||||||
),
|
|
||||||
heroType: HeroType.never,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -276,3 +280,15 @@ class _AlbumPickPageState extends State<_AlbumPickPage> {
|
||||||
Navigator.maybeOf(context)?.pop<AlbumFilter>(filter);
|
Navigator.maybeOf(context)?.pop<AlbumFilter>(filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _AlbumChipSetPickActionDelegate extends AlbumChipSetActionDelegate {
|
||||||
|
_AlbumChipSetPickActionDelegate(super.items);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onActionSelected(BuildContext context, Set<AlbumFilter> filters, ChipSetAction action) {
|
||||||
|
if (action == ChipSetAction.toggleTitleSearch) {
|
||||||
|
settings.showAlbumPickQuery = !settings.showAlbumPickQuery;
|
||||||
|
}
|
||||||
|
super.onActionSelected(context, filters, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import 'package:aves/widgets/common/grid/sliver.dart';
|
||||||
import 'package:aves/widgets/common/grid/theme.dart';
|
import 'package:aves/widgets/common/grid/theme.dart';
|
||||||
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
||||||
import 'package:aves/widgets/common/identity/scroll_thumb.dart';
|
import 'package:aves/widgets/common/identity/scroll_thumb.dart';
|
||||||
import 'package:aves/widgets/common/providers/query_provider.dart';
|
|
||||||
import 'package:aves/widgets/common/providers/tile_extent_controller_provider.dart';
|
import 'package:aves/widgets/common/providers/tile_extent_controller_provider.dart';
|
||||||
import 'package:aves/widgets/common/thumbnail/image.dart';
|
import 'package:aves/widgets/common/thumbnail/image.dart';
|
||||||
import 'package:aves/widgets/common/tile_extent_controller.dart';
|
import 'package:aves/widgets/common/tile_extent_controller.dart';
|
||||||
|
@ -82,38 +81,35 @@ class FilterGridPage<T extends CollectionFilter> extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final useTvLayout = settings.useTvLayout;
|
final useTvLayout = settings.useTvLayout;
|
||||||
final body = QueryProvider(
|
final body = GestureAreaProtectorStack(
|
||||||
initialQuery: null,
|
child: DirectionalSafeArea(
|
||||||
child: GestureAreaProtectorStack(
|
start: !useTvLayout,
|
||||||
child: DirectionalSafeArea(
|
top: false,
|
||||||
start: !useTvLayout,
|
bottom: false,
|
||||||
top: false,
|
child: Selector<MediaQueryData, double>(
|
||||||
bottom: false,
|
selector: (context, mq) => mq.padding.top,
|
||||||
child: Selector<MediaQueryData, double>(
|
builder: (context, mqPaddingTop, child) {
|
||||||
selector: (context, mq) => mq.padding.top,
|
return ValueListenableBuilder<double>(
|
||||||
builder: (context, mqPaddingTop, child) {
|
valueListenable: appBarHeightNotifier,
|
||||||
return ValueListenableBuilder<double>(
|
builder: (context, appBarHeight, child) {
|
||||||
valueListenable: appBarHeightNotifier,
|
return _FilterGrid<T>(
|
||||||
builder: (context, appBarHeight, child) {
|
// key is expected by test driver
|
||||||
return _FilterGrid<T>(
|
key: const Key('filter-grid'),
|
||||||
// key is expected by test driver
|
settingsRouteKey: settingsRouteKey,
|
||||||
key: const Key('filter-grid'),
|
appBar: appBar,
|
||||||
settingsRouteKey: settingsRouteKey,
|
appBarHeight: mqPaddingTop + appBarHeight,
|
||||||
appBar: appBar,
|
sections: sections,
|
||||||
appBarHeight: mqPaddingTop + appBarHeight,
|
newFilters: newFilters,
|
||||||
sections: sections,
|
sortFactor: sortFactor,
|
||||||
newFilters: newFilters,
|
showHeaders: showHeaders,
|
||||||
sortFactor: sortFactor,
|
selectable: selectable,
|
||||||
showHeaders: showHeaders,
|
applyQuery: applyQuery,
|
||||||
selectable: selectable,
|
emptyBuilder: emptyBuilder,
|
||||||
applyQuery: applyQuery,
|
heroType: heroType,
|
||||||
emptyBuilder: emptyBuilder,
|
);
|
||||||
heroType: heroType,
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:aves/model/filters/filters.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/utils/time_utils.dart';
|
import 'package:aves/utils/time_utils.dart';
|
||||||
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
||||||
|
import 'package:aves/widgets/common/providers/query_provider.dart';
|
||||||
import 'package:aves/widgets/common/providers/selection_provider.dart';
|
import 'package:aves/widgets/common/providers/selection_provider.dart';
|
||||||
import 'package:aves/widgets/filter_grids/common/action_delegates/chip_set.dart';
|
import 'package:aves/widgets/filter_grids/common/action_delegates/chip_set.dart';
|
||||||
import 'package:aves/widgets/filter_grids/common/app_bar.dart';
|
import 'package:aves/widgets/filter_grids/common/app_bar.dart';
|
||||||
|
@ -106,30 +107,32 @@ class _FilterNavigationPageState<T extends CollectionFilter, CSAD extends ChipSe
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SelectionProvider<FilterGridItem<T>>(
|
return SelectionProvider<FilterGridItem<T>>(
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) => FilterGridPage<T>(
|
builder: (context) => QueryProvider(
|
||||||
appBar: FilterGridAppBar<T, CSAD>(
|
child: FilterGridPage<T>(
|
||||||
source: widget.source,
|
appBar: FilterGridAppBar<T, CSAD>(
|
||||||
title: widget.title,
|
source: widget.source,
|
||||||
actionDelegate: widget.actionDelegate,
|
title: widget.title,
|
||||||
isEmpty: widget.filterSections.isEmpty,
|
actionDelegate: widget.actionDelegate,
|
||||||
|
isEmpty: widget.filterSections.isEmpty,
|
||||||
|
appBarHeightNotifier: _appBarHeightNotifier,
|
||||||
|
),
|
||||||
appBarHeightNotifier: _appBarHeightNotifier,
|
appBarHeightNotifier: _appBarHeightNotifier,
|
||||||
|
sections: widget.filterSections,
|
||||||
|
newFilters: widget.newFilters ?? {},
|
||||||
|
sortFactor: widget.sortFactor,
|
||||||
|
showHeaders: widget.showHeaders,
|
||||||
|
selectable: true,
|
||||||
|
applyQuery: widget.applyQuery,
|
||||||
|
emptyBuilder: () => ValueListenableBuilder<SourceState>(
|
||||||
|
valueListenable: widget.source.stateNotifier,
|
||||||
|
builder: (context, sourceState, child) {
|
||||||
|
return sourceState != SourceState.loading ? widget.emptyBuilder() : const SizedBox();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
// do not always enable hero, otherwise unwanted hero gets triggered
|
||||||
|
// when using `Show in [...]` action from a chip in the Collection filter bar
|
||||||
|
heroType: HeroType.onTap,
|
||||||
),
|
),
|
||||||
appBarHeightNotifier: _appBarHeightNotifier,
|
|
||||||
sections: widget.filterSections,
|
|
||||||
newFilters: widget.newFilters ?? {},
|
|
||||||
sortFactor: widget.sortFactor,
|
|
||||||
showHeaders: widget.showHeaders,
|
|
||||||
selectable: true,
|
|
||||||
applyQuery: widget.applyQuery,
|
|
||||||
emptyBuilder: () => ValueListenableBuilder<SourceState>(
|
|
||||||
valueListenable: widget.source.stateNotifier,
|
|
||||||
builder: (context, sourceState, child) {
|
|
||||||
return sourceState != SourceState.loading ? widget.emptyBuilder() : const SizedBox();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
// do not always enable hero, otherwise unwanted hero gets triggered
|
|
||||||
// when using `Show in [...]` action from a chip in the Collection filter bar
|
|
||||||
heroType: HeroType.onTap,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue