show/hide filter bar, show/hide headers

This commit is contained in:
Thibault Deckers 2020-03-30 18:05:03 +09:00
parent 4ab75fe218
commit e915f1922f
6 changed files with 54 additions and 24 deletions

View file

@ -2,9 +2,11 @@ import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'package:aves/model/collection_source.dart'; import 'package:aves/model/collection_source.dart';
import 'package:aves/model/filters/album.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_entry.dart';
import 'package:aves/model/settings.dart'; import 'package:aves/model/settings.dart';
import 'package:aves/utils/change_notifier.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -13,6 +15,7 @@ class CollectionLens with ChangeNotifier {
final Set<CollectionFilter> filters; final Set<CollectionFilter> filters;
GroupFactor groupFactor; GroupFactor groupFactor;
SortFactor sortFactor; SortFactor sortFactor;
final AChangeNotifier filterChangeNotifier = AChangeNotifier();
List<ImageEntry> _filteredEntries; List<ImageEntry> _filteredEntries;
List<StreamSubscription> _subscriptions = []; List<StreamSubscription> _subscriptions = [];
@ -63,11 +66,24 @@ class CollectionLens with ChangeNotifier {
int get entryCount => _filteredEntries.length; int get entryCount => _filteredEntries.length;
int get imageCount => _filteredEntries.where((entry) => !entry.isVideo).length; List<ImageEntry> _sortedEntries;
int get videoCount => _filteredEntries.where((entry) => entry.isVideo).length; List<ImageEntry> get sortedEntries {
if (_sortedEntries == null) {
_sortedEntries = List.unmodifiable(sections.entries.expand((e) => e.value));
}
return _sortedEntries;
}
List<ImageEntry> get sortedEntries => List.unmodifiable(sections.entries.expand((e) => e.value)); bool get showHeaders {
if (sortFactor == SortFactor.size) return false;
final albumSections = sortFactor == SortFactor.name || (sortFactor == SortFactor.date && groupFactor == GroupFactor.album);
final filterByAlbum = filters.any((f) => f is AlbumFilter);
if (albumSections && filterByAlbum) return false;
return true;
}
Object heroTag(ImageEntry entry) => '$hashCode${entry.uri}'; Object heroTag(ImageEntry entry) => '$hashCode${entry.uri}';
@ -90,6 +106,7 @@ class CollectionLens with ChangeNotifier {
_applyFilters(); _applyFilters();
_applySort(); _applySort();
_applyGroup(); _applyGroup();
filterChangeNotifier.notifyListeners();
} }
void sort(SortFactor sortFactor) { void sort(SortFactor sortFactor) {
@ -156,6 +173,7 @@ class CollectionLens with ChangeNotifier {
sections = Map.unmodifiable(SplayTreeMap.of(byAlbum, compare)); sections = Map.unmodifiable(SplayTreeMap.of(byAlbum, compare));
break; break;
} }
_sortedEntries = null;
notifyListeners(); notifyListeners();
} }

View file

@ -30,7 +30,7 @@ class ImageEntry {
AddressDetails addressDetails; AddressDetails addressDetails;
final AChangeNotifier imageChangeNotifier = AChangeNotifier(), metadataChangeNotifier = AChangeNotifier(), addressChangeNotifier = AChangeNotifier(); final AChangeNotifier imageChangeNotifier = AChangeNotifier(), metadataChangeNotifier = AChangeNotifier(), addressChangeNotifier = AChangeNotifier();
final isFavouriteNotifier = ValueNotifier(false); final ValueNotifier<bool> isFavouriteNotifier = ValueNotifier(false);
ImageEntry({ ImageEntry({
this.uri, this.uri,

View file

@ -69,12 +69,17 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
valueListenable: stateNotifier, valueListenable: stateNotifier,
builder: (context, state, child) { builder: (context, state, child) {
debugPrint('$runtimeType builder state=$state'); debugPrint('$runtimeType builder state=$state');
return SliverAppBar( return Consumer<CollectionLens>(
leading: _buildAppBarLeading(), builder: (context, collection, child) => AnimatedBuilder(
title: _buildAppBarTitle(), animation: collection.filterChangeNotifier,
actions: _buildActions(), builder: (context, child) => SliverAppBar(
bottom: FilterBar(), leading: _buildAppBarLeading(),
floating: true, title: _buildAppBarTitle(),
actions: _buildActions(),
bottom: collection.filters.isNotEmpty ? FilterBar() : null,
floating: true,
),
),
); );
}, },
); );

View file

@ -14,12 +14,14 @@ class SectionSliver extends StatelessWidget {
final CollectionLens collection; final CollectionLens collection;
final dynamic sectionKey; final dynamic sectionKey;
final int columnCount; final int columnCount;
final bool showHeader;
const SectionSliver({ const SectionSliver({
Key key, Key key,
@required this.collection, @required this.collection,
@required this.sectionKey, @required this.sectionKey,
@required this.columnCount, @required this.columnCount,
@required this.showHeader,
}) : super(key: key); }) : super(key: key);
@override @override
@ -49,15 +51,17 @@ class SectionSliver extends StatelessWidget {
), ),
); );
return SliverStickyHeader( return showHeader
header: SectionHeader( ? SliverStickyHeader(
collection: collection, header: SectionHeader(
sections: sections, collection: collection,
sectionKey: sectionKey, sections: sections,
), sectionKey: sectionKey,
sliver: sliver, ),
overlapsContent: false, sliver: sliver,
); overlapsContent: false,
)
: sliver;
} }
} }
@ -133,7 +137,7 @@ class SectionHeader extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget header = const SizedBox.shrink(); Widget header;
switch (collection.sortFactor) { switch (collection.sortFactor) {
case SortFactor.date: case SortFactor.date:
if (collection.sortFactor == SortFactor.date) { if (collection.sortFactor == SortFactor.date) {
@ -156,9 +160,11 @@ class SectionHeader extends StatelessWidget {
header = _buildAlbumSectionHeader(context); header = _buildAlbumSectionHeader(context);
break; break;
} }
return IgnorePointer( return header != null
child: header, ? IgnorePointer(
); child: header,
)
: const SizedBox.shrink();
} }
Widget _buildAlbumSectionHeader(BuildContext context) { Widget _buildAlbumSectionHeader(BuildContext context) {

View file

@ -59,7 +59,6 @@ class ImageSearchDelegate extends SearchDelegate<CollectionFilter> {
child: ValueListenableBuilder<String>( child: ValueListenableBuilder<String>(
valueListenable: expandedSectionNotifier, valueListenable: expandedSectionNotifier,
builder: (context, expandedSection, child) { builder: (context, expandedSection, child) {
debugPrint('builder expandedSection=$expandedSection');
return ListView( return ListView(
children: [ children: [
_buildFilterRow( _buildFilterRow(

View file

@ -25,6 +25,7 @@ class ThumbnailCollection extends StatelessWidget {
final collection = Provider.of<CollectionLens>(context); final collection = Provider.of<CollectionLens>(context);
final sections = collection.sections; final sections = collection.sections;
final sectionKeys = sections.keys.toList(); final sectionKeys = sections.keys.toList();
final showHeaders = collection.showHeaders;
double topPadding = 0; double topPadding = 0;
if (appBar != null) { if (appBar != null) {
@ -64,6 +65,7 @@ class ThumbnailCollection extends StatelessWidget {
collection: collection, collection: collection,
sectionKey: sectionKey, sectionKey: sectionKey,
columnCount: columnCount, columnCount: columnCount,
showHeader: showHeaders,
)), )),
SliverToBoxAdapter( SliverToBoxAdapter(
child: Selector<MediaQueryData, double>( child: Selector<MediaQueryData, double>(