#327 long press on section header selects all section

This commit is contained in:
Thibault Deckers 2022-09-15 22:05:19 +02:00
parent 3ee20d46bf
commit 3090439e19
10 changed files with 61 additions and 5 deletions

View file

@ -92,6 +92,7 @@ class _CollectionGridContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
final selectable = context.select<ValueNotifier<AppMode>, bool>((v) => v.value.canSelectMedia);
final settingsRouteKey = context.read<TileExtentController>().settingsRouteKey;
final tileLayout = context.select<Settings, TileLayout>((s) => s.getTileLayout(settingsRouteKey));
return Consumer<CollectionLens>(
@ -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<bool> 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<ValueNotifier<AppMode>, bool>((v) => v.value.canSelectMedia),
selectable: widget.selectable,
items: collection.sortedEntries,
scrollController: scrollController,
appBarHeightNotifier: _appBarHeightNotifier,

View file

@ -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,
);
}

View file

@ -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<AvesEntry>(key: ValueKey(sectionKey), date: (sectionKey as EntryDateSectionKey).date);
return MonthSectionHeader<AvesEntry>(
key: ValueKey(sectionKey),
date: (sectionKey as EntryDateSectionKey).date,
selectable: selectable,
);
case EntryGroupFactor.day:
return DaySectionHeader<AvesEntry>(key: ValueKey(sectionKey), date: (sectionKey as EntryDateSectionKey).date);
return DaySectionHeader<AvesEntry>(
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<AvesEntry>(key: ValueKey(sectionKey), rating: (sectionKey as EntryRatingSectionKey).rating);
return RatingSectionHeader<AvesEntry>(
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,
);
}

View file

@ -7,10 +7,12 @@ import 'package:intl/intl.dart';
class DaySectionHeader<T> 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<T> extends StatelessWidget {
return SectionHeader<T>(
sectionKey: EntryDateSectionKey(date),
title: _formatDate(context, date),
selectable: selectable,
);
}
}
class MonthSectionHeader<T> 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<T> extends StatelessWidget {
return SectionHeader<T>(
sectionKey: EntryDateSectionKey(date),
title: _formatDate(context, date),
selectable: selectable,
);
}
}

View file

@ -5,10 +5,12 @@ import 'package:flutter/material.dart';
class RatingSectionHeader<T> 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<T> extends StatelessWidget {
return SectionHeader<T>(
sectionKey: EntryRatingSectionKey(rating),
title: RatingFilter.formatRating(context, rating),
selectable: selectable,
);
}
}

View file

@ -7,10 +7,12 @@ import 'package:flutter/material.dart';
class SectionedEntryListLayoutProvider extends SectionedListLayoutProvider<AvesEntry> {
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<AvesE
collection: collection,
sectionKey: sectionKey,
height: headerExtent,
selectable: selectable,
);
}
}

View file

@ -36,6 +36,17 @@ class SectionHeader<T> extends StatelessWidget {
constraints: BoxConstraints(minHeight: leadingSize.height),
child: GestureDetector(
onTap: selectable ? () => _toggleSectionSelection(context) : null,
onLongPress: selectable
? () {
final selection = context.read<Selection<T>>();
if (selection.isSelecting) {
_toggleSectionSelection(context);
} else {
selection.select();
selection.addToSelection(_getSectionEntries(context));
}
}
: null,
child: Text.rich(
TextSpan(
children: [
@ -74,8 +85,10 @@ class SectionHeader<T> extends StatelessWidget {
);
}
List<T> _getSectionEntries(BuildContext context) => context.read<SectionedListLayout<T>>().sections[sectionKey] ?? [];
void _toggleSectionSelection(BuildContext context) {
final sectionEntries = context.read<SectionedListLayout<T>>().sections[sectionKey] ?? [];
final sectionEntries = _getSectionEntries(context);
final selection = context.read<Selection<T>>();
final isSelected = selection.isSelected(sectionEntries);
if (isSelected) {

View file

@ -293,6 +293,7 @@ class _FilterGridContent<T extends CollectionFilter> extends StatelessWidget {
child: SectionedFilterListLayoutProvider<T>(
sections: visibleSections,
showHeaders: showHeaders,
selectable: selectable,
tileLayout: tileLayout,
scrollableWidth: scrollableWidth,
columnCount: columnCount,

View file

@ -4,10 +4,12 @@ import 'package:flutter/material.dart';
class FilterChipSectionHeader<T> 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<T> extends StatelessWidget {
sectionKey: sectionKey,
leading: sectionKey.leading,
title: sectionKey.title,
selectable: selectable,
);
}

View file

@ -6,10 +6,13 @@ import 'package:aves/widgets/filter_grids/common/section_keys.dart';
import 'package:flutter/material.dart';
class SectionedFilterListLayoutProvider<T extends CollectionFilter> extends SectionedListLayoutProvider<FilterGridItem<T>> {
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<T extends CollectionFilter> extends Sect
Widget buildHeader(BuildContext context, SectionKey sectionKey, double headerExtent) {
return FilterChipSectionHeader<FilterGridItem<T>>(
sectionKey: sectionKey as ChipSectionKey,
selectable: selectable,
);
}
}