From 1a17f9546c25e7dae48761b395c5032adfd09be1 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Wed, 5 Jan 2022 10:44:43 +0900 Subject: [PATCH] stats: added ratings --- lib/widgets/stats/filter_table.dart | 22 ++++++++++++++-------- lib/widgets/stats/stats_page.dart | 26 +++++++++++++++++++------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/lib/widgets/stats/filter_table.dart b/lib/widgets/stats/filter_table.dart index 2d5754440..325b518c0 100644 --- a/lib/widgets/stats/filter_table.dart +++ b/lib/widgets/stats/filter_table.dart @@ -2,15 +2,16 @@ import 'package:aves/model/filters/filters.dart'; import 'package:aves/utils/color_utils.dart'; import 'package:aves/utils/constants.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; -import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:percent_indicator/linear_percent_indicator.dart'; -class FilterTable extends StatelessWidget { +class FilterTable extends StatelessWidget { final int totalEntryCount; - final Map entryCountMap; - final CollectionFilter Function(String key) filterBuilder; + final Map entryCountMap; + final CollectionFilter Function(T key) filterBuilder; + final bool sortByCount; + final int? maxRowCount; final FilterCallback onFilterSelection; const FilterTable({ @@ -18,6 +19,8 @@ class FilterTable extends StatelessWidget { required this.totalEntryCount, required this.entryCountMap, required this.filterBuilder, + required this.sortByCount, + required this.maxRowCount, required this.onFilterSelection, }) : super(key: key); @@ -27,11 +30,13 @@ class FilterTable extends StatelessWidget { @override Widget build(BuildContext context) { - final sortedEntries = entryCountMap.entries.toList() - ..sort((kv1, kv2) { + final sortedEntries = entryCountMap.entries.toList(); + if (sortByCount) { + sortedEntries.sort((kv1, kv2) { final c = kv2.value.compareTo(kv1.value); - return c != 0 ? c : compareAsciiUpperCase(kv1.key, kv2.key); + return c != 0 ? c : kv1.key.compareTo(kv2.key); }); + } final textScaleFactor = MediaQuery.textScaleFactorOf(context); final lineHeight = 16 * textScaleFactor; @@ -41,8 +46,9 @@ class FilterTable extends StatelessWidget { child: LayoutBuilder( builder: (context, constraints) { final showPercentIndicator = constraints.maxWidth - (chipWidth + countWidth) > percentIndicatorMinWidth; + final displayedEntries = maxRowCount != null ? sortedEntries.take(maxRowCount!) : sortedEntries; return Table( - children: sortedEntries.take(5).map((kv) { + children: displayedEntries.map((kv) { final filter = filterBuilder(kv.key); final label = filter.getLabel(context); final count = kv.value; diff --git a/lib/widgets/stats/stats_page.dart b/lib/widgets/stats/stats_page.dart index 884cc6280..6ece99212 100644 --- a/lib/widgets/stats/stats_page.dart +++ b/lib/widgets/stats/stats_page.dart @@ -4,6 +4,7 @@ import 'package:aves/model/entry.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/location.dart'; import 'package:aves/model/filters/mime.dart'; +import 'package:aves/model/filters/rating.dart'; import 'package:aves/model/filters/tag.dart'; import 'package:aves/model/settings/accessibility_animations.dart'; import 'package:aves/model/settings/settings.dart'; @@ -33,6 +34,7 @@ class StatsPage extends StatelessWidget { final CollectionLens? parentCollection; final Set entries; final Map entryCountPerCountry = {}, entryCountPerPlace = {}, entryCountPerTag = {}; + final Map entryCountPerRating = Map.fromEntries(List.generate(7, (i) => MapEntry(5 - i, 0))); static const mimeDonutMinWidth = 124.0; @@ -55,9 +57,13 @@ class StatsPage extends StatelessWidget { entryCountPerPlace[place] = (entryCountPerPlace[place] ?? 0) + 1; } } + entry.tags.forEach((tag) { entryCountPerTag[tag] = (entryCountPerTag[tag] ?? 0) + 1; }); + + final rating = entry.rating; + entryCountPerRating[rating] = (entryCountPerRating[rating] ?? 0) + 1; }); } @@ -115,13 +121,15 @@ class StatsPage extends StatelessWidget { ], ), ); + final showRatings = entryCountPerRating.entries.any((kv) => kv.key != 0 && kv.value > 0); child = ListView( children: [ mimeDonuts, locationIndicator, - ..._buildTopFilters(context, context.l10n.statsTopCountries, entryCountPerCountry, (s) => LocationFilter(LocationLevel.country, s)), - ..._buildTopFilters(context, context.l10n.statsTopPlaces, entryCountPerPlace, (s) => LocationFilter(LocationLevel.place, s)), - ..._buildTopFilters(context, context.l10n.statsTopTags, entryCountPerTag, (s) => TagFilter(s)), + ..._buildFilterSection(context, context.l10n.statsTopCountries, entryCountPerCountry, (v) => LocationFilter(LocationLevel.country, v)), + ..._buildFilterSection(context, context.l10n.statsTopPlaces, entryCountPerPlace, (v) => LocationFilter(LocationLevel.place, v)), + ..._buildFilterSection(context, context.l10n.statsTopTags, entryCountPerTag, (v) => TagFilter(v)), + if (showRatings) ..._buildFilterSection(context, context.l10n.searchSectionRating, entryCountPerRating, (v) => RatingFilter(v), sortByCount: false, maxRowCount: null), ], ); } @@ -243,12 +251,14 @@ class StatsPage extends StatelessWidget { }); } - List _buildTopFilters( + List _buildFilterSection( BuildContext context, String title, - Map entryCountMap, - CollectionFilter Function(String key) filterBuilder, - ) { + Map entryCountMap, + CollectionFilter Function(T key) filterBuilder, { + bool sortByCount = true, + int? maxRowCount = 5, + }) { if (entryCountMap.isEmpty) return []; return [ @@ -263,6 +273,8 @@ class StatsPage extends StatelessWidget { totalEntryCount: entries.length, entryCountMap: entryCountMap, filterBuilder: filterBuilder, + sortByCount: sortByCount, + maxRowCount: maxRowCount, onFilterSelection: (filter) => _onFilterSelection(context, filter), ), ];