Commit 8af0e3f
Changed files (5)
lib
lib/components/export_item_order.dart
@@ -1,10 +1,16 @@
import 'dart:async';
+import 'package:badges/badges.dart' as badges;
+import 'package:blood_pressure_app/components/consistent_future_builder.dart';
+import 'package:blood_pressure_app/model/export_options.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:provider/provider.dart';
-class ExportItemsCustomizer extends StatelessWidget {
+import '../model/settings_store.dart';
+
+class ExportItemsCustomizer extends StatefulWidget {
final List<String> exportItems;
final List<String> exportAddableItems;
final FutureOr<void> Function(List<String> exportItems, List<String> exportAddableItems) onReorder;
@@ -12,37 +18,70 @@ class ExportItemsCustomizer extends StatelessWidget {
const ExportItemsCustomizer({super.key, required this.exportItems, required this.exportAddableItems,
required this.onReorder});
+ @override
+ State<ExportItemsCustomizer> createState() => _ExportItemsCustomizerState();
+}
+
+class _ExportItemsCustomizerState extends State<ExportItemsCustomizer> {
+ // hack so that FutureBuilder doesn't always rebuild
+ Future<ExportConfigurationModel>? _future;
+
@override
Widget build(BuildContext context) {
- return Container(
- margin: const EdgeInsets.all(25),
- padding: const EdgeInsets.all(20),
- height: 420,
- decoration: BoxDecoration(
- border: Border.all(color: Theme.of(context).textTheme.labelLarge?.color ?? Colors.teal),
- borderRadius: const BorderRadius.all(Radius.circular(10)),
- ),
- clipBehavior: Clip.hardEdge,
- child: ReorderableListView(
- physics: const NeverScrollableScrollPhysics(),
- shrinkWrap: true,
- onReorder: _onReorderList,
- children: <Widget>[
- for (int i = 0; i < exportItems.length; i += 1)
- ListTile(
- key: Key('l_${exportItems[i]}'),
- title: Text(exportItems[i]),
- trailing: const Icon(Icons.drag_handle),
+ _future ??= ExportConfigurationModel.get(Provider.of<Settings>(context, listen: false), AppLocalizations.of(context)!);
+ return ConsistentFutureBuilder(
+ future: _future!,
+ onData: (BuildContext context, ExportConfigurationModel result) {
+ final formats = result.availableFormats;
+ return badges.Badge(
+ badgeStyle: badges.BadgeStyle(
+ badgeColor: Theme.of(context).colorScheme.background,
+ padding: const EdgeInsets.all(10)
+ ),
+ position: badges.BadgePosition.bottomEnd(bottom: 3, end: 3),
+ badgeContent: Container(
+ decoration: BoxDecoration(
+ border: Border.all(color: Theme.of(context).colorScheme.onBackground),
+ shape: BoxShape.circle
+ ),
+ child: IconButton(
+ tooltip: 'add exportformat',
+ onPressed:() {},
+ icon: const Icon(Icons.add),
+ ),
+ ),
+ child: Container(
+ margin: const EdgeInsets.all(25),
+ padding: const EdgeInsets.all(20),
+ height: 420,
+ decoration: BoxDecoration(
+ border: Border.all(color: Theme.of(context).textTheme.labelLarge?.color ?? Colors.teal),
+ borderRadius: const BorderRadius.all(Radius.circular(10)),
),
- _buildListSectionDivider(context),
- for (int i = 0; i < exportAddableItems.length; i += 1)
- ListTile(
- key: Key('ul_${exportAddableItems[i]}'),
- title: Opacity(opacity: 0.7,child: Text(exportAddableItems[i]),),
- trailing: const Icon(Icons.drag_handle),
+ clipBehavior: Clip.hardEdge,
+ child: ReorderableListView(
+ physics: const NeverScrollableScrollPhysics(),
+ shrinkWrap: true,
+ onReorder: _onReorderList,
+ children: <Widget>[
+ for (int i = 0; i < widget.exportItems.length; i += 1)
+ ListTile(
+ key: Key('l_${widget.exportItems[i]}'),
+ title: Text(formats[widget.exportItems[i]]?.columnTitle ?? widget.exportItems[i]),
+ trailing: const Icon(Icons.drag_handle),
+ ),
+ _buildListSectionDivider(context),
+ for (int i = 0; i < widget.exportAddableItems.length; i += 1)
+ ListTile(
+ key: Key('ul_${widget.exportAddableItems[i]}'),
+ title: Opacity(opacity: 0.7,child: Text(widget.exportAddableItems[i]),),
+ trailing: const Icon(Icons.drag_handle),
+ ),
+ ],
),
- ],
- ),
+ ),
+ );
+ },
);
}
@@ -95,23 +134,23 @@ class ExportItemsCustomizer extends StatelessWidget {
}
final String item;
- if (0 <= oldIndex && oldIndex < exportItems.length) {
- item = exportItems.removeAt(oldIndex);
- } else if ((exportItems.length + 1) <= oldIndex && oldIndex < (exportItems.length + 1 + exportAddableItems.length)) {
- item = exportAddableItems.removeAt(oldIndex - (exportItems.length + 1));
+ if (0 <= oldIndex && oldIndex < widget.exportItems.length) {
+ item = widget.exportItems.removeAt(oldIndex);
+ } else if ((widget.exportItems.length + 1) <= oldIndex && oldIndex < (widget.exportItems.length + 1 + widget.exportAddableItems.length)) {
+ item = widget.exportAddableItems.removeAt(oldIndex - (widget.exportItems.length + 1));
} else {
assert(false, 'oldIndex outside expected boundaries');
return;
}
- if (newIndex < (exportItems.length + 1)) {
- exportItems.insert(newIndex, item);
+ if (newIndex < (widget.exportItems.length + 1)) {
+ widget.exportItems.insert(newIndex, item);
} else {
- newIndex -= (exportItems.length + 1);
- exportAddableItems.insert(newIndex, item);
+ newIndex -= (widget.exportItems.length + 1);
+ widget.exportAddableItems.insert(newIndex, item);
}
- onReorder(exportItems, exportAddableItems);
+ widget.onReorder(widget.exportItems, widget.exportAddableItems);
}
}
lib/model/export_options.dart
@@ -48,13 +48,14 @@ class ExportConfigurationModel {
return _instance!;
}
- List<ExportColumn> _getDefaultFormates() => [
+ List<ExportColumn> _getDefaultFormates() => [ // TODO: localizations
ExportColumn(internalColumnName: 'timestampUnixMs', columnTitle: 'Unix timestamp', formatPattern: r'$TIMESTAMP'),
ExportColumn(internalColumnName: 'formattedTimestamp', columnTitle: 'Time', formatPattern: '\$FORMAT{\$TIMESTAMP,${settings.dateFormatString}}'),
ExportColumn(internalColumnName: 'systolic', columnTitle: 'Systolic', formatPattern: r'$SYS'),
ExportColumn(internalColumnName: 'diastolic', columnTitle: 'Diastolic', formatPattern: r'$DIA'),
ExportColumn(internalColumnName: 'pulse', columnTitle: 'Pulse', formatPattern: r'$PUL'),
ExportColumn(internalColumnName: 'notes', columnTitle: 'Notes', formatPattern: r'$NOTE'),
+ ExportColumn(internalColumnName: 'pulsePressure', columnTitle: 'Pulse pressure', formatPattern: r'{{$SYS-$DIA}}')
];
void add(ExportColumn format) {
@@ -66,7 +67,8 @@ class ExportConfigurationModel {
},);
}
- UnmodifiableListView<ExportColumn> get availableFormats => UnmodifiableListView(_availableFormats);
+ UnmodifiableMapView<String, ExportColumn> get availableFormats =>
+ UnmodifiableMapView(Map.fromIterable(_availableFormats, key: (e) => e.internalColumnName));
}
class ExportColumn {
lib/screens/settings.dart
@@ -365,7 +365,6 @@ class _DetermineAgeValuesState extends State<DetermineAgeValues> {
context,
MaterialPageRoute(builder: (context) => const SettingsPage()),
);
-
},
child: Text(AppLocalizations.of(context)!.btnConfirm)
);
pubspec.lock
@@ -41,6 +41,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.11.0"
+ badges:
+ dependency: "direct main"
+ description:
+ name: badges
+ sha256: "6e7f3ec561ec08f47f912cfe349d4a1707afdc8dda271e17b046aa6d42c89e77"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.1"
barcode:
dependency: transitive
description:
pubspec.yaml
@@ -31,6 +31,7 @@ dependencies:
file_picker: ^5.2.11 # MIT
jsaver: ^1.2.0
function_tree: ^0.8.13
+ badges: ^3.1.1
dev_dependencies:
flutter_test: