From 3090439e1935466c4ab31c8b387df7908b121977 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Thu, 15 Sep 2022 22:05:19 +0200 Subject: [PATCH] #327 long press on section header selects all section --- lib/widgets/collection/collection_grid.dart | 7 ++++++- .../collection/grid/headers/album.dart | 3 +++ lib/widgets/collection/grid/headers/any.dart | 21 ++++++++++++++++--- lib/widgets/collection/grid/headers/date.dart | 6 ++++++ .../collection/grid/headers/rating.dart | 3 +++ .../collection/grid/section_layout.dart | 3 +++ lib/widgets/common/grid/header.dart | 15 ++++++++++++- .../filter_grids/common/filter_grid_page.dart | 1 + .../filter_grids/common/section_header.dart | 3 +++ .../filter_grids/common/section_layout.dart | 4 ++++ 10 files changed, 61 insertions(+), 5 deletions(-) diff --git a/lib/widgets/collection/collection_grid.dart b/lib/widgets/collection/collection_grid.dart index bc9eb6b34..39b161ac0 100644 --- a/lib/widgets/collection/collection_grid.dart +++ b/lib/widgets/collection/collection_grid.dart @@ -92,6 +92,7 @@ class _CollectionGridContent extends StatelessWidget { @override Widget build(BuildContext context) { + final selectable = context.select, bool>((v) => v.value.canSelectMedia); final settingsRouteKey = context.read().settingsRouteKey; final tileLayout = context.select((s) => s.getTileLayout(settingsRouteKey)); return Consumer( @@ -124,6 +125,7 @@ class _CollectionGridContent extends StatelessWidget { } return SectionedEntryListLayoutProvider( collection: collection, + selectable: selectable, scrollableWidth: scrollableWidth, tileLayout: tileLayout, columnCount: columnCount, @@ -160,6 +162,7 @@ class _CollectionGridContent extends StatelessWidget { isScrollingNotifier: _isScrollingNotifier, scrollController: PrimaryScrollController.of(context)!, tileLayout: tileLayout, + selectable: selectable, ), ); return sectionedListLayoutProvider; @@ -173,12 +176,14 @@ class _CollectionSectionedContent extends StatefulWidget { final ValueNotifier isScrollingNotifier; final ScrollController scrollController; final TileLayout tileLayout; + final bool selectable; const _CollectionSectionedContent({ required this.collection, required this.isScrollingNotifier, required this.scrollController, required this.tileLayout, + required this.selectable, }); @override @@ -220,7 +225,7 @@ class _CollectionSectionedContentState extends State<_CollectionSectionedContent final selector = GridSelectionGestureDetector( scrollableKey: _scrollableKey, - selectable: context.select, bool>((v) => v.value.canSelectMedia), + selectable: widget.selectable, items: collection.sortedEntries, scrollController: scrollController, appBarHeightNotifier: _appBarHeightNotifier, diff --git a/lib/widgets/collection/grid/headers/album.dart b/lib/widgets/collection/grid/headers/album.dart index 77bd42aef..85fb41b32 100644 --- a/lib/widgets/collection/grid/headers/album.dart +++ b/lib/widgets/collection/grid/headers/album.dart @@ -11,11 +11,13 @@ import 'package:flutter/material.dart'; class AlbumSectionHeader extends StatelessWidget { final String? directory, albumName; + final bool selectable; const AlbumSectionHeader({ super.key, required this.directory, required this.albumName, + required this.selectable, }); @override @@ -41,6 +43,7 @@ class AlbumSectionHeader extends StatelessWidget { color: Color(0xFF757575), ) : null, + selectable: selectable, ); } diff --git a/lib/widgets/collection/grid/headers/any.dart b/lib/widgets/collection/grid/headers/any.dart index 29cbbd0b5..35958d604 100644 --- a/lib/widgets/collection/grid/headers/any.dart +++ b/lib/widgets/collection/grid/headers/any.dart @@ -15,12 +15,14 @@ class CollectionSectionHeader extends StatelessWidget { final CollectionLens collection; final SectionKey sectionKey; final double height; + final bool selectable; const CollectionSectionHeader({ super.key, required this.collection, required this.sectionKey, required this.height, + required this.selectable, }); @override @@ -41,9 +43,17 @@ class CollectionSectionHeader extends StatelessWidget { case EntryGroupFactor.album: return _buildAlbumHeader(context); case EntryGroupFactor.month: - return MonthSectionHeader(key: ValueKey(sectionKey), date: (sectionKey as EntryDateSectionKey).date); + return MonthSectionHeader( + key: ValueKey(sectionKey), + date: (sectionKey as EntryDateSectionKey).date, + selectable: selectable, + ); case EntryGroupFactor.day: - return DaySectionHeader(key: ValueKey(sectionKey), date: (sectionKey as EntryDateSectionKey).date); + return DaySectionHeader( + key: ValueKey(sectionKey), + date: (sectionKey as EntryDateSectionKey).date, + selectable: selectable, + ); case EntryGroupFactor.none: break; } @@ -51,7 +61,11 @@ class CollectionSectionHeader extends StatelessWidget { case EntrySortFactor.name: return _buildAlbumHeader(context); case EntrySortFactor.rating: - return RatingSectionHeader(key: ValueKey(sectionKey), rating: (sectionKey as EntryRatingSectionKey).rating); + return RatingSectionHeader( + key: ValueKey(sectionKey), + rating: (sectionKey as EntryRatingSectionKey).rating, + selectable: selectable, + ); case EntrySortFactor.size: break; } @@ -65,6 +79,7 @@ class CollectionSectionHeader extends StatelessWidget { key: ValueKey(sectionKey), directory: directory, albumName: directory != null ? source.getAlbumDisplayName(context, directory) : null, + selectable: selectable, ); } diff --git a/lib/widgets/collection/grid/headers/date.dart b/lib/widgets/collection/grid/headers/date.dart index 033492287..a772a0712 100644 --- a/lib/widgets/collection/grid/headers/date.dart +++ b/lib/widgets/collection/grid/headers/date.dart @@ -7,10 +7,12 @@ import 'package:intl/intl.dart'; class DaySectionHeader extends StatelessWidget { final DateTime? date; + final bool selectable; const DaySectionHeader({ super.key, required this.date, + required this.selectable, }); // Examples (en_US): @@ -48,16 +50,19 @@ class DaySectionHeader extends StatelessWidget { return SectionHeader( sectionKey: EntryDateSectionKey(date), title: _formatDate(context, date), + selectable: selectable, ); } } class MonthSectionHeader extends StatelessWidget { final DateTime? date; + final bool selectable; const MonthSectionHeader({ super.key, required this.date, + required this.selectable, }); static String _formatDate(BuildContext context, DateTime? date) { @@ -74,6 +79,7 @@ class MonthSectionHeader extends StatelessWidget { return SectionHeader( sectionKey: EntryDateSectionKey(date), title: _formatDate(context, date), + selectable: selectable, ); } } diff --git a/lib/widgets/collection/grid/headers/rating.dart b/lib/widgets/collection/grid/headers/rating.dart index c6e0198f0..4cdfc3ed8 100644 --- a/lib/widgets/collection/grid/headers/rating.dart +++ b/lib/widgets/collection/grid/headers/rating.dart @@ -5,10 +5,12 @@ import 'package:flutter/material.dart'; class RatingSectionHeader extends StatelessWidget { final int rating; + final bool selectable; const RatingSectionHeader({ super.key, required this.rating, + required this.selectable, }); @override @@ -16,6 +18,7 @@ class RatingSectionHeader extends StatelessWidget { return SectionHeader( sectionKey: EntryRatingSectionKey(rating), title: RatingFilter.formatRating(context, rating), + selectable: selectable, ); } } diff --git a/lib/widgets/collection/grid/section_layout.dart b/lib/widgets/collection/grid/section_layout.dart index bfced886b..6ca41975c 100644 --- a/lib/widgets/collection/grid/section_layout.dart +++ b/lib/widgets/collection/grid/section_layout.dart @@ -7,10 +7,12 @@ import 'package:flutter/material.dart'; class SectionedEntryListLayoutProvider extends SectionedListLayoutProvider { final CollectionLens collection; + final bool selectable; const SectionedEntryListLayoutProvider({ super.key, required this.collection, + required this.selectable, required super.scrollableWidth, required super.tileLayout, required super.columnCount, @@ -42,6 +44,7 @@ class SectionedEntryListLayoutProvider extends SectionedListLayoutProvider extends StatelessWidget { constraints: BoxConstraints(minHeight: leadingSize.height), child: GestureDetector( onTap: selectable ? () => _toggleSectionSelection(context) : null, + onLongPress: selectable + ? () { + final selection = context.read>(); + if (selection.isSelecting) { + _toggleSectionSelection(context); + } else { + selection.select(); + selection.addToSelection(_getSectionEntries(context)); + } + } + : null, child: Text.rich( TextSpan( children: [ @@ -74,8 +85,10 @@ class SectionHeader extends StatelessWidget { ); } + List _getSectionEntries(BuildContext context) => context.read>().sections[sectionKey] ?? []; + void _toggleSectionSelection(BuildContext context) { - final sectionEntries = context.read>().sections[sectionKey] ?? []; + final sectionEntries = _getSectionEntries(context); final selection = context.read>(); final isSelected = selection.isSelected(sectionEntries); if (isSelected) { diff --git a/lib/widgets/filter_grids/common/filter_grid_page.dart b/lib/widgets/filter_grids/common/filter_grid_page.dart index b2e851dfc..b93899747 100644 --- a/lib/widgets/filter_grids/common/filter_grid_page.dart +++ b/lib/widgets/filter_grids/common/filter_grid_page.dart @@ -293,6 +293,7 @@ class _FilterGridContent extends StatelessWidget { child: SectionedFilterListLayoutProvider( sections: visibleSections, showHeaders: showHeaders, + selectable: selectable, tileLayout: tileLayout, scrollableWidth: scrollableWidth, columnCount: columnCount, diff --git a/lib/widgets/filter_grids/common/section_header.dart b/lib/widgets/filter_grids/common/section_header.dart index 7a9960510..977eb5bb5 100644 --- a/lib/widgets/filter_grids/common/section_header.dart +++ b/lib/widgets/filter_grids/common/section_header.dart @@ -4,10 +4,12 @@ import 'package:flutter/material.dart'; class FilterChipSectionHeader extends StatelessWidget { final ChipSectionKey sectionKey; + final bool selectable; const FilterChipSectionHeader({ super.key, required this.sectionKey, + required this.selectable, }); @override @@ -16,6 +18,7 @@ class FilterChipSectionHeader extends StatelessWidget { sectionKey: sectionKey, leading: sectionKey.leading, title: sectionKey.title, + selectable: selectable, ); } diff --git a/lib/widgets/filter_grids/common/section_layout.dart b/lib/widgets/filter_grids/common/section_layout.dart index 832078152..a00bd9c95 100644 --- a/lib/widgets/filter_grids/common/section_layout.dart +++ b/lib/widgets/filter_grids/common/section_layout.dart @@ -6,10 +6,13 @@ import 'package:aves/widgets/filter_grids/common/section_keys.dart'; import 'package:flutter/material.dart'; class SectionedFilterListLayoutProvider extends SectionedListLayoutProvider> { + final bool selectable; + const SectionedFilterListLayoutProvider({ super.key, required this.sections, required this.showHeaders, + required this.selectable, required super.scrollableWidth, required super.tileLayout, required super.columnCount, @@ -37,6 +40,7 @@ class SectionedFilterListLayoutProvider extends Sect Widget buildHeader(BuildContext context, SectionKey sectionKey, double headerExtent) { return FilterChipSectionHeader>( sectionKey: sectionKey as ChipSectionKey, + selectable: selectable, ); } }