#327 long press on section header selects all section
This commit is contained in:
parent
3ee20d46bf
commit
3090439e19
10 changed files with 61 additions and 5 deletions
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue