stats: fixed pluralization, location percent indicator
This commit is contained in:
parent
af7cc94270
commit
38c2207b78
3 changed files with 34 additions and 8 deletions
|
@ -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:charts_flutter/flutter.dart' as charts;
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.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 {
|
class StatsPage extends StatelessWidget {
|
||||||
final CollectionLens collection;
|
final CollectionLens collection;
|
||||||
|
@ -17,7 +20,10 @@ class StatsPage extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final catalogued = entries.where((entry) => entry.isCatalogued);
|
final catalogued = entries.where((entry) => entry.isCatalogued);
|
||||||
final withGps = catalogued.where((entry) => entry.hasGps);
|
final withGps = catalogued.where((entry) => entry.hasGps);
|
||||||
|
final withGpsPercent = withGps.length / entries.length;
|
||||||
final Map<String, int> byMimeTypes = groupBy(entries, (entry) => entry.mimeType).map((k, v) => MapEntry(k, v.length));
|
final Map<String, int> 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(
|
return MediaQueryDataProvider(
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
@ -29,17 +35,27 @@ class StatsPage extends StatelessWidget {
|
||||||
Wrap(
|
Wrap(
|
||||||
alignment: WrapAlignment.center,
|
alignment: WrapAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_buildMimePie(context, 'images', Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('image/')))),
|
_buildMimePie(context, (sum) => Intl.plural(sum, one: 'image', other: 'images'), imagesByMimeTypes),
|
||||||
_buildMimePie(context, 'videos', Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('video/')))),
|
_buildMimePie(context, (sum) => Intl.plural(sum, one: 'video', other: 'videos'), videoByMimeTypes),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
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),
|
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<String, num> byMimeTypes) {
|
Widget _buildMimePie(BuildContext context, String Function(num) label, Map<String, num> byMimeTypes) {
|
||||||
if (byMimeTypes.isEmpty) return const SizedBox.shrink();
|
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();
|
final seriesData = byMimeTypes.entries.map((kv) => StringNumDatum(kv.key.replaceFirst(RegExp('.*/'), '').toUpperCase(), kv.value)).toList();
|
||||||
seriesData.sort((kv1, kv2) => kv2.value.compareTo(kv1.value));
|
seriesData.sort((kv1, kv2) => kv2.value.compareTo(kv1.value));
|
||||||
|
|
||||||
final series = [
|
final series = [
|
||||||
charts.Series<StringNumDatum, String>(
|
charts.Series<StringNumDatum, String>(
|
||||||
id: label,
|
id: 'mime',
|
||||||
colorFn: (d, i) => charts.ColorUtil.fromDartColor(stringToColor(d.key)),
|
colorFn: (d, i) => charts.ColorUtil.fromDartColor(stringToColor(d.key)),
|
||||||
domainFn: (d, i) => d.key,
|
domainFn: (d, i) => d.key,
|
||||||
measureFn: (d, i) => d.value,
|
measureFn: (d, i) => d.value,
|
||||||
|
@ -86,7 +104,7 @@ class StatsPage extends StatelessWidget {
|
||||||
),
|
),
|
||||||
Center(
|
Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'${byMimeTypes.values.fold(0, (prev, v) => prev + v)}\n$label',
|
'${sum}\n${label(sum)}',
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -274,6 +274,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0+1"
|
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:
|
permission_handler:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -24,7 +24,7 @@ dependencies:
|
||||||
url: git://github.com/deckerst/flutter-draggable-scrollbar.git
|
url: git://github.com/deckerst/flutter-draggable-scrollbar.git
|
||||||
event_bus:
|
event_bus:
|
||||||
flushbar:
|
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:
|
git:
|
||||||
url: https://github.com/AndreHaueisen/flushbar.git
|
url: https://github.com/AndreHaueisen/flushbar.git
|
||||||
ref: 13c55a8
|
ref: 13c55a8
|
||||||
|
@ -42,6 +42,7 @@ dependencies:
|
||||||
path:
|
path:
|
||||||
pdf:
|
pdf:
|
||||||
pedantic:
|
pedantic:
|
||||||
|
percent_indicator:
|
||||||
permission_handler:
|
permission_handler:
|
||||||
photo_view:
|
photo_view:
|
||||||
printing:
|
printing:
|
||||||
|
|
Loading…
Reference in a new issue