stats: open full top listings
This commit is contained in:
parent
d27e3ccfc0
commit
92ba7b9e9f
3 changed files with 83 additions and 7 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue