Commit 16091f7
Changed files (7)
lib
components
model
lib/components/measurement_list.dart
@@ -69,42 +69,47 @@ class MeasurementList extends StatelessWidget {
}
Widget buildListItem(BloodPressureRecord record) {
- final DateFormat formater = DateFormat('yy-MM-dd H:mm:s');
- return Container(
- margin: const EdgeInsets.only(bottom: 5),
- child: Row(
- children: [
- Expanded(
- flex: _sideFlex,
- child: const SizedBox(),
- ),
- Expanded(
- flex: _tableElementsSizes[0],
- child: Text(formater.format(record.creationTime))
- ),
- Expanded(
- flex: _tableElementsSizes[1],
- child: Text(record.systolic.toString())
- ),
- Expanded(
- flex: _tableElementsSizes[2],
- child: Text(record.diastolic.toString())
- ),
- Expanded(
- flex: _tableElementsSizes[3],
- child: Text(record.pulse.toString())
- ),
- Expanded(
- flex: _tableElementsSizes[4],
- child: Text(record.notes)
- ),
- Expanded(
- flex: _sideFlex,
- child: const SizedBox(),
+ return Consumer<Settings>(
+ builder: (context, settings, child) {
+ final formatter = DateFormat(settings.dateFormatString);
+ return Container(
+ margin: const EdgeInsets.only(bottom: 5),
+ child: Row(
+ children: [
+ Expanded(
+ flex: _sideFlex,
+ child: const SizedBox(),
+ ),
+ Expanded(
+ flex: _tableElementsSizes[0],
+ child: Text(formatter.format(record.creationTime))
+ ),
+ Expanded(
+ flex: _tableElementsSizes[1],
+ child: Text(record.systolic.toString())
+ ),
+ Expanded(
+ flex: _tableElementsSizes[2],
+ child: Text(record.diastolic.toString())
+ ),
+ Expanded(
+ flex: _tableElementsSizes[3],
+ child: Text(record.pulse.toString())
+ ),
+ Expanded(
+ flex: _tableElementsSizes[4],
+ child: Text(record.notes)
+ ),
+ Expanded(
+ flex: _sideFlex,
+ child: const SizedBox(),
+ ),
+ ]
),
- ]
- ),
+ );
+ }
);
+
}
@@ -161,8 +166,3 @@ class MeasurementList extends StatelessWidget {
});
}
}
-
-class _MeasuredValueListItem {
-
-
-}
lib/model/settings.dart
@@ -19,6 +19,7 @@ class Settings extends ChangeNotifier {
late MaterialColor _diaColor;
late MaterialColor _pulColor;
late bool _allowManualTimeInput;
+ late String _dateFormatString;
Settings._create();
Future<void> _asyncInit() async {
@@ -65,6 +66,7 @@ class Settings extends ChangeNotifier {
var pDiaColor = _getSetting('_diaColor');
var pPulColor = _getSetting('_pulColor');
var pAllowManualTimeInput = _getSetting('_allowManualTimeInput');
+ var pDateFormatString = _getSetting('_dateFormatString');
// var ...
_graphStepSize = (await pGraphStepSize as int?) ?? TimeStep.day;
@@ -77,6 +79,7 @@ class Settings extends ChangeNotifier {
_diaColor = createMaterialColor(await pDiaColor as int? ?? 0xFF4CAF50);
_pulColor = createMaterialColor(await pPulColor as int? ?? 0xFFF44336);
_allowManualTimeInput = ((await pAllowManualTimeInput as int?) ?? 1) == 1 ? true : false;
+ _dateFormatString = (await pDateFormatString as String?) ?? 'yy-MM-dd H:mm';
// ...
return;
}
@@ -184,6 +187,14 @@ class Settings extends ChangeNotifier {
_saveSetting('_allowManualTimeInput', newSetting ? 1 : 0);
notifyListeners();
}
+ String get dateFormatString {
+ return _dateFormatString;
+ }
+ set dateFormatString(String newFormatString) {
+ _dateFormatString = newFormatString;
+ _saveSetting('_dateFormatString', newFormatString);
+ notifyListeners();
+ }
}
lib/screens/add_measurement.dart
@@ -14,7 +14,6 @@ class AddMeasurementPage extends StatefulWidget {
}
class _AddMeasurementPageState extends State<AddMeasurementPage> {
- final _formatter = DateFormat('yy-MM-dd H:mm:s');
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
DateTime _time = DateTime.now();
int _systolic = -1;
@@ -39,9 +38,10 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
children: [
Consumer<Settings>(
builder: (context, settings, child) {
+ final formatter = DateFormat(settings.dateFormatString);
if(settings.allowManualTimeInput) {
return TextFormField(
- initialValue: _formatter.format(_time),
+ initialValue: formatter.format(_time),
decoration: const InputDecoration(
hintText: 'time'
),
@@ -50,9 +50,9 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
return 'Please enter a value';
} else {
try {
- _time = _formatter.parse(value);
+ _time = formatter.parse(value);
} on FormatException {
- return 'date format: ${_formatter.pattern}';
+ return 'date format: ${formatter.pattern}';
}
}
return null;
lib/screens/enter_timeformat.dart
@@ -0,0 +1,106 @@
+import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/settings.dart';
+import 'package:flutter/gestures.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:intl/intl.dart';
+import 'package:provider/provider.dart';
+import 'package:url_launcher/url_launcher.dart' show launch;
+
+
+class EnterTimeFormatScreen extends StatefulWidget {
+ const EnterTimeFormatScreen({super.key});
+
+ @override
+ State<EnterTimeFormatScreen> createState() => _EnterTimeFormatScreenState();
+}
+
+class _EnterTimeFormatScreenState extends State<EnterTimeFormatScreen> {
+ final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
+ final _firstNode = FocusNode();
+ late String _newVal;
+
+ @override
+ Widget build(BuildContext context) {
+ _firstNode.requestFocus();
+ return Scaffold(
+ body: Center(
+ child: Form(
+ key: _formKey,
+ child: Container(
+ padding: const EdgeInsets.all(90.0),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const Text('A formatter String consists of a mixture of predefined ICU/Skeleton Strings and any other text you want to include.'),
+ const SizedBox(height: 5,),
+ RichText(
+ text: TextSpan(
+ text: 'For a full list of valid formats please look here.',
+ style: const TextStyle(color: Colors.blue),
+ recognizer: TapGestureRecognizer()
+ ..onTap = () { launch('https://pub.dev/documentation/intl/latest/intl/DateFormat-class.html');
+ },
+ ),
+ ),
+ const SizedBox(height: 7,),
+ const Text('Please note that having longer/shorter format Strings wont magically change the width of the table columns, so it might come to awkward line breaks.'),
+ const SizedBox(height: 7,),
+ const Text('default: "yy-MM-dd H:mm"'),
+
+ const SizedBox(height: 10,),
+ Consumer<Settings>(
+ builder: (context, settings, child) {
+ _newVal = settings.dateFormatString;
+ return TextFormField(
+ initialValue: _newVal,
+ decoration: const InputDecoration(
+ hintText: 'format string'
+ ),
+ validator: (String? value) {
+ if (value == null || value.isEmpty) {
+ return 'Please enter a value';
+ } else {
+ _newVal = value;
+ }
+ return null;
+ },
+ );
+ }
+ ),
+ SizedBox(height: 25,),
+ Row(
+ children: [
+ ElevatedButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ style: ElevatedButton.styleFrom(
+ backgroundColor: Theme.of(context).unselectedWidgetColor
+ ),
+ child: const Text('CANCEL')),
+ const Spacer(),
+ ElevatedButton(
+ onPressed: () {
+ if (_formKey.currentState!.validate()) {
+ Provider.of<Settings>(context, listen: false).dateFormatString = _newVal;
+ Navigator.of(context).pop();
+ }
+ },
+ style: ElevatedButton.styleFrom(
+ backgroundColor: Theme.of(context).primaryColor
+ ),
+ child: const Text('SAVE'))
+ ],
+ )
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+
+}
\ No newline at end of file
lib/screens/settings.dart
@@ -1,6 +1,7 @@
import 'package:blood_pressure_app/components/complex_settings.dart';
import 'package:blood_pressure_app/model/blood_pressure.dart';
import 'package:blood_pressure_app/model/settings.dart';
+import 'package:blood_pressure_app/screens/enter_timeformat.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:settings_ui/settings_ui.dart';
@@ -17,93 +18,110 @@ class SettingsScreen extends StatelessWidget {
),
body: Consumer<Settings>(
builder: (context, settings, child) {
- return SettingsList(sections: [
- SettingsSection(
- title: const Text('layout'),
- tiles: <SettingsTile>[
- SettingsTile.switchTile(
- initialValue: settings.allowManualTimeInput,
- onToggle: (value) {
- settings.allowManualTimeInput = value;
- },
- leading: const Icon(Icons.details),
- title: const Text('allow manual time input')
- ),
- SettingsTile.switchTile(
- initialValue: settings.followSystemDarkMode,
- onToggle: (value) {
- settings.followSystemDarkMode = value;
- },
- leading: const Icon(Icons.auto_mode),
- title: const Text('follow system dark mode')
- ),
- SettingsTile.switchTile(
- initialValue: (() {
- if (settings.followSystemDarkMode) {
- return MediaQuery.of(context).platformBrightness == Brightness.dark;
- }
- return settings.darkMode;
- })(),
- onToggle: (value) {
- settings.darkMode = value;
+ return SettingsList(
+ darkTheme: SettingsThemeData(
+ settingsListBackground: Theme.of(context).canvasColor,
+ dividerColor: Theme.of(context).dividerColor,
+ ),
+ sections: [
+ SettingsSection(
+ title: const Text('layout'),
+ tiles: <SettingsTile>[
+ SettingsTile.switchTile(
+ initialValue: settings.allowManualTimeInput,
+ onToggle: (value) {
+ settings.allowManualTimeInput = value;
+ },
+ leading: const Icon(Icons.details),
+ title: const Text('allow manual time input')
+ ),
+ SettingsTile(
+ title: const Text('time format'),
+ leading: const Icon(Icons.schedule),
+ trailing: Icon(Icons.arrow_forward_ios, color: Theme.of(context).highlightColor,),
+ description: Text(settings.dateFormatString),
+ onPressed: (context) {
+ Navigator.push(
+ context,
+ MaterialPageRoute(builder: (context) => EnterTimeFormatScreen()),
+ );
},
- leading: const Icon(Icons.dark_mode),
- title: const Text('enable dark mode'),
- enabled: !settings.followSystemDarkMode,
+ ),
+ SettingsTile.switchTile(
+ initialValue: settings.followSystemDarkMode,
+ onToggle: (value) {
+ settings.followSystemDarkMode = value;
+ },
+ leading: const Icon(Icons.auto_mode),
+ title: const Text('follow system dark mode')
+ ),
+ SettingsTile.switchTile(
+ initialValue: (() {
+ if (settings.followSystemDarkMode) {
+ return MediaQuery.of(context).platformBrightness == Brightness.dark;
+ }
+ return settings.darkMode;
+ })(),
+ onToggle: (value) {
+ settings.darkMode = value;
+ },
+ leading: const Icon(Icons.dark_mode),
+ title: const Text('enable dark mode'),
+ enabled: !settings.followSystemDarkMode,
+ ),
+ //settings.accentColor = settings.createMaterialColor((color ?? Colors.teal).value);
+ ColorSelectionTile(
+ onMainColorChanged: (color) => settings.accentColor = settings.createMaterialColor((color ?? Colors.teal).value),
+ initialColor: settings.accentColor,
+ title: const Text('theme color')
+ ).build(context),
+ ColorSelectionTile(
+ onMainColorChanged: (color) => settings.sysColor = settings.createMaterialColor((color ?? Colors.green).value),
+ initialColor: settings.sysColor,
+ title: const Text('systolic color')
+ ).build(context),
+ ColorSelectionTile(
+ onMainColorChanged: (color) => settings.diaColor = settings.createMaterialColor((color ?? Colors.teal).value),
+ initialColor: settings.diaColor,
+ title: const Text('diastolic color')
+ ).build(context),
+ ColorSelectionTile(
+ onMainColorChanged: (color) => settings.pulColor = settings.createMaterialColor((color ?? Colors.red).value),
+ initialColor: settings.pulColor,
+ title: const Text('pulse color')
+ ).build(context),
+ ]
+ ),
+ SettingsSection(
+ title: const Text('data'),
+ tiles: <SettingsTile>[
+ SettingsTile(
+ title: const Text('export'),
+ leading: const Icon(Icons.save),
+ onPressed: (context) => Provider.of<BloodPressureModel>(context, listen: false).save((success, msg) {
+ if (success && msg != null) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(content: Text(msg)));
+ } else if (!success && msg != null) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(content: Text('Error: $msg')));
+ }
+ }),
),
- //settings.accentColor = settings.createMaterialColor((color ?? Colors.teal).value);
- ColorSelectionTile(
- onMainColorChanged: (color) => settings.accentColor = settings.createMaterialColor((color ?? Colors.teal).value),
- initialColor: settings.accentColor,
- title: const Text('theme color')
- ).build(context),
- ColorSelectionTile(
- onMainColorChanged: (color) => settings.sysColor = settings.createMaterialColor((color ?? Colors.green).value),
- initialColor: settings.sysColor,
- title: const Text('systolic color')
- ).build(context),
- ColorSelectionTile(
- onMainColorChanged: (color) => settings.diaColor = settings.createMaterialColor((color ?? Colors.teal).value),
- initialColor: settings.diaColor,
- title: const Text('diastolic color')
- ).build(context),
- ColorSelectionTile(
- onMainColorChanged: (color) => settings.pulColor = settings.createMaterialColor((color ?? Colors.red).value),
- initialColor: settings.pulColor,
- title: const Text('pulse color')
- ).build(context),
- ]
- ),
- SettingsSection(
- title: const Text('data'),
- tiles: <SettingsTile>[
- SettingsTile(
- title: const Text('export'),
- leading: const Icon(Icons.save),
- onPressed: (context) => Provider.of<BloodPressureModel>(context, listen: false).save((success, msg) {
- if (success && msg != null) {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(content: Text(msg)));
- } else if (!success && msg != null) {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(content: Text('Error: $msg')));
- }
- }),
- ),
- SettingsTile(
- title: const Text('import'),
- leading: const Icon(Icons.file_upload),
- onPressed: (context) => Provider.of<BloodPressureModel>(context, listen: false).import((res, String? err) {
- if (res) {
+ SettingsTile(
+ title: const Text('import'),
+ leading: const Icon(Icons.file_upload),
+ onPressed: (context) => Provider.of<BloodPressureModel>(context, listen: false).import((res, String? err) {
+ if (res) {
- } else {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(content: Text('Error: ${err ?? 'unknown error'}')));
- }
- }),
- ),
- ],
- )
+ } else {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(content: Text('Error: ${err ?? 'unknown error'}')));
+ }
+ }),
+ ),
+ ],
+ )
]);
}
),
pubspec.lock
@@ -486,7 +486,7 @@ packages:
source: hosted
version: "1.3.1"
url_launcher:
- dependency: transitive
+ dependency: "direct main"
description:
name: url_launcher
sha256: "75f2846facd11168d007529d6cd8fcb2b750186bea046af9711f10b907e1587e"
pubspec.yaml
@@ -42,6 +42,7 @@ dependencies:
flutter_material_color_picker: ^1.1.0+2 # MIT
file_picker: ^5.2.11 # MIT
csv: ^5.0.2 # MIT
+ url_launcher: ^6.1.10 # BSD-3-Clause
dev_dependencies:
flutter_test: