stats: open full top listings

This commit is contained in:
Thibault Deckers 2022-09-27 14:02:01 +02:00
parent d27e3ccfc0
commit 92ba7b9e9f
3 changed files with 83 additions and 7 deletions

View file

@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file.
- mosaic layout - mosaic layout
- Albums: group by content type - Albums: group by content type
- Stats: top albums
- Stats: open full top listings
- Slideshow: option for no transition - Slideshow: option for no transition
- Widget: tap action setting - Widget: tap action setting

View file

@ -30,7 +30,7 @@ class ExpandableFilterRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (filters.isEmpty) return const SizedBox.shrink(); if (filters.isEmpty) return const SizedBox();
final hasTitle = title != null && title!.isNotEmpty; final hasTitle = title != null && title!.isNotEmpty;

View file

@ -16,6 +16,7 @@ import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/collection/collection_page.dart';
import 'package:aves/widgets/common/basic/insets.dart'; import 'package:aves/widgets/common/basic/insets.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/extensions/media_query.dart';
import 'package:aves/widgets/common/identity/empty.dart'; import 'package:aves/widgets/common/identity/empty.dart';
import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
import 'package:aves/widgets/stats/date/histogram.dart'; import 'package:aves/widgets/stats/date/histogram.dart';
@ -223,7 +224,12 @@ class _StatsPageState extends State<StatsPage> {
body: GestureAreaProtectorStack( body: GestureAreaProtectorStack(
child: SafeArea( child: SafeArea(
bottom: false, bottom: false,
child: child, child: TooltipTheme(
data: TooltipTheme.of(context).copyWith(
preferBelow: false,
),
child: child,
),
), ),
), ),
), ),
@ -238,20 +244,50 @@ class _StatsPageState extends State<StatsPage> {
Map<T, int> entryCountMap, Map<T, int> entryCountMap,
CollectionFilter Function(T key) filterBuilder, { CollectionFilter Function(T key) filterBuilder, {
bool sortByCount = true, bool sortByCount = true,
int? maxRowCount = 5, int? maxRowCount = 3,
}) { }) {
if (entryCountMap.isEmpty) return []; if (entryCountMap.isEmpty) return [];
final totalEntryCount = entries.length;
final hasMore = maxRowCount != null && entryCountMap.length > maxRowCount;
return [ return [
Padding( Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Text( child: Row(
title, children: [
style: Constants.knownTitleTextStyle, Text(
title,
style: Constants.knownTitleTextStyle,
),
const Spacer(),
IconButton(
icon: const Icon(AIcons.next),
onPressed: hasMore
? () => Navigator.push(
context,
MaterialPageRoute(
settings: const RouteSettings(name: StatsTopPage.routeName),
builder: (context) => StatsTopPage(
title: title,
tableBuilder: (context) => FilterTable(
totalEntryCount: totalEntryCount,
entryCountMap: entryCountMap,
filterBuilder: filterBuilder,
sortByCount: sortByCount,
maxRowCount: null,
onFilterSelection: (filter) => _onFilterSelection(context, filter),
),
),
),
)
: null,
tooltip: MaterialLocalizations.of(context).moreButtonTooltip,
),
],
), ),
), ),
FilterTable( FilterTable(
totalEntryCount: entries.length, totalEntryCount: totalEntryCount,
entryCountMap: entryCountMap, entryCountMap: entryCountMap,
filterBuilder: filterBuilder, filterBuilder: filterBuilder,
sortByCount: sortByCount, sortByCount: sortByCount,
@ -293,3 +329,41 @@ class _StatsPageState extends State<StatsPage> {
); );
} }
} }
class StatsTopPage extends StatelessWidget {
static const routeName = '/collection/stats/top';
final String title;
final WidgetBuilder tableBuilder;
const StatsTopPage({
super.key,
required this.title,
required this.tableBuilder,
});
@override
Widget build(BuildContext context) {
return MediaQueryDataProvider(
child: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: GestureAreaProtectorStack(
child: SafeArea(
bottom: false,
child: Builder(builder: (context) {
return SingleChildScrollView(
padding: const EdgeInsets.symmetric(vertical: 8) +
EdgeInsets.only(
bottom: context.select<MediaQueryData, double>((mq) => mq.effectiveBottomPadding),
),
child: tableBuilder(context),
);
}),
),
),
),
);
}
}