From 38c2207b78288da7f5e5819a99d32000e6464226 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sat, 21 Mar 2020 10:55:08 +0900 Subject: [PATCH] stats: fixed pluralization, location percent indicator --- lib/widgets/stats.dart | 32 +++++++++++++++++++++++++------- pubspec.lock | 7 +++++++ pubspec.yaml | 3 ++- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/lib/widgets/stats.dart b/lib/widgets/stats.dart index c6767f84c..2617e015e 100644 --- a/lib/widgets/stats.dart +++ b/lib/widgets/stats.dart @@ -5,6 +5,9 @@ import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:outline_material_icons/outline_material_icons.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; class StatsPage extends StatelessWidget { final CollectionLens collection; @@ -17,7 +20,10 @@ class StatsPage extends StatelessWidget { Widget build(BuildContext context) { final catalogued = entries.where((entry) => entry.isCatalogued); final withGps = catalogued.where((entry) => entry.hasGps); + final withGpsPercent = withGps.length / entries.length; final Map byMimeTypes = groupBy(entries, (entry) => entry.mimeType).map((k, v) => MapEntry(k, v.length)); + final imagesByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('image/'))); + final videoByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('video/'))); return MediaQueryDataProvider( child: Scaffold( appBar: AppBar( @@ -29,17 +35,27 @@ class StatsPage extends StatelessWidget { Wrap( alignment: WrapAlignment.center, children: [ - _buildMimePie(context, 'images', Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('image/')))), - _buildMimePie(context, 'videos', Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('video/')))), + _buildMimePie(context, (sum) => Intl.plural(sum, one: 'image', other: 'images'), imagesByMimeTypes), + _buildMimePie(context, (sum) => Intl.plural(sum, one: 'video', other: 'videos'), videoByMimeTypes), ], ), Padding( padding: const EdgeInsets.all(16), child: Column( children: [ - LinearProgressIndicator(value: withGps.length / entries.length), + LinearPercentIndicator( + percent: withGpsPercent, + lineHeight: 16, + backgroundColor: Colors.white24, + progressColor: Theme.of(context).accentColor, + animation: true, + leading: Icon(OMIcons.place), + // right padding to match leading, so that inside label is aligned with outside label below + padding: const EdgeInsets.symmetric(horizontal: 16) + const EdgeInsets.only(right: 24), + center: Text(NumberFormat.percentPattern().format(withGpsPercent)), + ), const SizedBox(height: 8), - Text('${withGps.length} entries with location'), + Text('${withGps.length} ${Intl.plural(withGps.length, one: 'item', other: 'items')} with location'), ], ), ), @@ -50,15 +66,17 @@ class StatsPage extends StatelessWidget { ); } - Widget _buildMimePie(BuildContext context, String label, Map byMimeTypes) { + Widget _buildMimePie(BuildContext context, String Function(num) label, Map byMimeTypes) { if (byMimeTypes.isEmpty) return const SizedBox.shrink(); + final sum = byMimeTypes.values.fold(0, (prev, v) => prev + v); + final seriesData = byMimeTypes.entries.map((kv) => StringNumDatum(kv.key.replaceFirst(RegExp('.*/'), '').toUpperCase(), kv.value)).toList(); seriesData.sort((kv1, kv2) => kv2.value.compareTo(kv1.value)); final series = [ charts.Series( - id: label, + id: 'mime', colorFn: (d, i) => charts.ColorUtil.fromDartColor(stringToColor(d.key)), domainFn: (d, i) => d.key, measureFn: (d, i) => d.value, @@ -86,7 +104,7 @@ class StatsPage extends StatelessWidget { ), Center( child: Text( - '${byMimeTypes.values.fold(0, (prev, v) => prev + v)}\n$label', + '${sum}\n${label(sum)}', textAlign: TextAlign.center, ), ), diff --git a/pubspec.lock b/pubspec.lock index 01f00c6a1..3d162fcb6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -274,6 +274,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0+1" + percent_indicator: + dependency: "direct main" + description: + name: percent_indicator + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1+1" permission_handler: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 93da59fe7..a885d5142 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,7 +24,7 @@ dependencies: url: git://github.com/deckerst/flutter-draggable-scrollbar.git event_bus: flushbar: -# flushbar-1.9.1 cannot be built with Flutter 1.15.17 + # flushbar-1.9.1 cannot be built with Flutter 1.15.17 git: url: https://github.com/AndreHaueisen/flushbar.git ref: 13c55a8 @@ -42,6 +42,7 @@ dependencies: path: pdf: pedantic: + percent_indicator: permission_handler: photo_view: printing: