Commit 78332b0
Changed files (8)
lib
test
lib/components/complex_settings.dart
@@ -1,17 +1,73 @@
import 'package:blood_pressure_app/model/settings.dart';
import 'package:flutter/material.dart';
import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
-import 'package:settings_ui/settings_ui.dart';
-class ColorSelectionTile {
- final ValueChanged<ColorSwatch?>? onMainColorChanged;
- final MaterialColor initialColor;
+class SettingsTile extends StatelessWidget {
final Widget title;
+ final void Function(BuildContext context) onPressed;
+ final Widget? leading;
+ final Widget? description;
+ final Widget? trailing;
+ final bool disabled;
+
+ const SettingsTile({super.key, required this.title, this.leading, this.trailing, required this.onPressed, this.description, this.disabled = false});
+
+ @override
+ Widget build(BuildContext context) {
+ if (disabled) return SizedBox.shrink();
+
+ var lead = SizedBox(
+ width: 40,
+ child: leading ?? const SizedBox.shrink(),
+ );
+ var trail = trailing ?? const SizedBox.shrink();
+
+ return InkWell(
+ onTap: () => onPressed(context),
+ child: SizedBox(
+ height: 45,
+ child: Row(
+ children: [
+ lead,
+ (() {
+ if (description != null) {
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ title,
+ DefaultTextStyle(
+ style: const TextStyle(color: Colors.grey),
+ child: description ?? const SizedBox.shrink()
+ )
+ ],
+ );
+ }
+ return title;
+ })(),
+ const Expanded(child: SizedBox.shrink()),
+ trail
+ ],
+ ),
+ ),
+ );
+ }
+}
+
- const ColorSelectionTile({required this.title, required this.onMainColorChanged, required this.initialColor});
+class ColorSelectionSettingsTile extends StatelessWidget {
+ final Widget title;
+ final ValueChanged<ColorSwatch?>? onMainColorChanged;
+ final MaterialColor initialColor;
+ final Widget? leading;
+ final Widget? trailing;
+ final Widget? description;
+ final bool disabled;
+ const ColorSelectionSettingsTile({super.key, required this.title, required this.onMainColorChanged, required this.initialColor, this.leading, this.trailing, this.description, this.disabled = false});
- SettingsTile build(BuildContext context) {
+ @override
+ Widget build(BuildContext context) {
return SettingsTile(
leading: Container(
width: 25.0,
@@ -22,6 +78,9 @@ class ColorSelectionTile {
),
),
title: title,
+ trailing: trailing,
+ description: description,
+ disabled: disabled,
onPressed: (context) {
showDialog(
context: context,
@@ -48,5 +107,66 @@ class ColorSelectionTile {
},
);
}
+}
-}
\ No newline at end of file
+class SwitchSettingsTile extends StatelessWidget {
+ final Widget title;
+ final void Function(bool newValue) onToggle;
+ final Widget? leading;
+ final Widget? description;
+ final bool? initialValue;
+ final bool disabled;
+
+ const SwitchSettingsTile({super.key, required this.title, required this.onToggle,
+ this.leading, this.description, this.initialValue, this.disabled = false});
+
+ @override
+ Widget build(BuildContext context) {
+ var s = Switch(
+ value: initialValue ?? false,
+ onChanged: onToggle,
+ );
+ return SettingsTile(
+ title: title,
+ onPressed: (BuildContext context) {
+ s.value != s.value;
+ },
+ leading: leading,
+ description: description,
+ disabled: disabled,
+ trailing: s,
+ );
+ }
+}
+
+class SettingsSection extends StatelessWidget {
+ final Widget title;
+ final List<Widget> children;
+
+ const SettingsSection({super.key, required this.title, required this.children});
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ children: [
+ Container(
+ padding: const EdgeInsets.only(top: 15),
+ child: Align(
+ alignment: const Alignment(-0.93, 0),
+ child: DefaultTextStyle(
+ style: (Theme.of(context).textTheme.bodyMedium ?? const TextStyle())
+ .copyWith(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold),
+ child: title
+ ),
+ ),
+ ),
+ Container(
+ padding: const EdgeInsets.only(left: 20, right: 20),
+ child: Column(
+ children: children,
+ ),
+ )
+ ],
+ );
+ }
+}
lib/model/blood_pressure.dart
@@ -29,6 +29,13 @@ class BloodPressureModel extends ChangeNotifier {
}
// factory method, to allow for async contructor
static Future<BloodPressureModel> create() async {
+ if (Platform.isWindows || Platform.isLinux) {
+ // Initialize FFI
+ sqfliteFfiInit();
+ // Change the default factory
+ databaseFactory = databaseFactoryFfi;
+ }
+
final component = BloodPressureModel._create();
await component._asyncInit();
return component;
lib/screens/home.dart
@@ -45,7 +45,10 @@ class AppHome extends StatelessWidget {
color: Theme.of(context).primaryColor
),
child: IconButton(
- icon: const Icon(Icons.add),
+ icon: const Icon(
+ Icons.add,
+ color: Colors.black,
+ ),
onPressed: () {
Navigator.push(
context,
@@ -61,7 +64,10 @@ class AppHome extends StatelessWidget {
color: Theme.of(context).unselectedWidgetColor
),
child: IconButton(
- icon: const Icon(Icons.settings),
+ icon: const Icon(
+ Icons.settings,
+ color: Colors.black
+ ),
onPressed: () {
Navigator.push(
context,
lib/screens/settings.dart
@@ -4,7 +4,6 @@ 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';
class SettingsScreen extends StatelessWidget {
const SettingsScreen({super.key});
@@ -18,45 +17,42 @@ class SettingsScreen extends StatelessWidget {
),
body: Consumer<Settings>(
builder: (context, settings, child) {
- 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()),
- );
- },
- ),
- SettingsTile.switchTile(
- initialValue: settings.followSystemDarkMode,
- onToggle: (value) {
- settings.followSystemDarkMode = value;
+ return Scaffold(
+ body: ListView(
+ children: [
+ SettingsSection(
+ title: const Text('layout'),
+ children: [
+ SwitchSettingsTile(
+ 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.auto_mode),
- title: const Text('follow system dark mode')
- ),
- SettingsTile.switchTile(
- initialValue: (() {
+ ),
+ SwitchSettingsTile(
+ initialValue: settings.followSystemDarkMode,
+ onToggle: (value) {
+ settings.followSystemDarkMode = value;
+ },
+ leading: const Icon(Icons.auto_mode),
+ title: const Text('follow system dark mode')
+ ),
+ SwitchSettingsTile(
+ initialValue: (() {
if (settings.followSystemDarkMode) {
return MediaQuery.of(context).platformBrightness == Brightness.dark;
}
@@ -65,67 +61,70 @@ class SettingsScreen extends StatelessWidget {
onToggle: (value) {
settings.darkMode = value;
},
- leading: const Icon(Icons.dark_mode),
- title: const Text('enable dark mode'),
- enabled: !settings.followSystemDarkMode,
+ leading: const Icon(Icons.dark_mode),
+ title: const Text('enable dark mode'),
+ disabled: settings.followSystemDarkMode,
+ ),
+ //settings.accentColor = settings.createMaterialColor((color ?? Colors.teal).value);
+ ColorSelectionSettingsTile(
+ onMainColorChanged: (color) => settings.accentColor = settings.createMaterialColor((color ?? Colors.teal).value),
+ initialColor: settings.accentColor,
+ title: const Text('theme color')
+ ),
+ ColorSelectionSettingsTile(
+ onMainColorChanged: (color) => settings.sysColor = settings.createMaterialColor((color ?? Colors.green).value),
+ initialColor: settings.sysColor,
+ title: const Text('systolic color')
+ ),
+ ColorSelectionSettingsTile(
+ onMainColorChanged: (color) => settings.diaColor = settings.createMaterialColor((color ?? Colors.teal).value),
+ initialColor: settings.diaColor,
+ title: const Text('diastolic color')
+ ),
+ ColorSelectionSettingsTile(
+ onMainColorChanged: (color) => settings.pulColor = settings.createMaterialColor((color ?? Colors.red).value),
+ initialColor: settings.pulColor,
+ title: const Text('pulse color')
+ ),
+ ]
+ ),
+ SettingsSection(
+ title: const Text('data'),
+ children: [
+ 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'}')));
+ }
+ }),
+ ),
+ ],
+ )
+ ],
+ ),
+ );
}
),
);
}
+}
+
-}
\ No newline at end of file
lib/main.dart
@@ -49,7 +49,6 @@ class AppRoot extends StatelessWidget {
brightness: Brightness.dark,
canvasColor: Colors.black,
primaryColor: settings.accentColor.shade400,
- iconTheme: const IconThemeData(color: Colors.black)
),
themeMode: mode,
home: const AppHome(),
test/model/bood_pressure_test.dart
@@ -72,7 +72,7 @@ void main() {
await clearDbDir();
var m = await BloodPressureModel.create();
- var r = BloodPressureRecord(DateTime.now(), -172, 10000, 0, "((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈๏ แผ่นดินฮั่นเABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвг, \n \t д∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა");
+ var r = BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(31415926), -172, 10000, 0, "((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈๏ แผ่นดินฮั่นเABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвг, \n \t д∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა");
m.addListener(() async {
var res = (await m.getLastX(1)).first;
expect(res, isNotNull);
pubspec.lock
@@ -1,6 +1,22 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
+ amdjs:
+ dependency: transitive
+ description:
+ name: amdjs
+ sha256: "97e6d96fd0e64d3eeb6fc85f386160322a23b1192662aac1fa4139569add2434"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.3"
+ args:
+ dependency: transitive
+ description:
+ name: args
+ sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.1"
async:
dependency: transitive
description:
@@ -9,6 +25,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.10.0"
+ async_extension:
+ dependency: transitive
+ description:
+ name: async_extension
+ sha256: "891a2ea770693a70cdf5155f5a0b5e81b0e3a2d3d631d112cffbca4807186468"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
boolean_selector:
dependency: transitive
description:
@@ -65,6 +89,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.2"
+ dom_tools:
+ dependency: transitive
+ description:
+ name: dom_tools
+ sha256: "55f1a0d30e2bb51fed0d0354514546d3f967bf0781a1f8562646b82a4da14c81"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.17"
+ enum_to_string:
+ dependency: transitive
+ description:
+ name: enum_to_string
+ sha256: bd9e83a33b754cb43a75b36a9af2a0b92a757bfd9847d2621ca0b1bed45f8e7a
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
equatable:
dependency: transitive
description:
@@ -85,10 +125,10 @@ packages:
dependency: transitive
description:
name: ffi
- sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
+ sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99
url: "https://pub.dev"
source: hosted
- version: "2.0.1"
+ version: "2.0.2"
file:
dependency: "direct dev"
description:
@@ -101,18 +141,18 @@ packages:
dependency: "direct main"
description:
name: file_picker
- sha256: e6c7ad8e572379df86ea64ef0a5395889fba3954411d47ca021b888d79f8e798
+ sha256: c7a8e25ca60e7f331b153b0cb3d405828f18d3e72a6fa1d9440c86556fffc877
url: "https://pub.dev"
source: hosted
- version: "5.2.11"
+ version: "5.3.0"
file_saver:
dependency: "direct main"
description:
name: file_saver
- sha256: "0de62b766ebbd491466b160909fce9f30d2c0b2ba9e062871dbda2e677e5b33b"
+ sha256: ec88678780c6d301579cebad4e236d1435eddd51804d31fc55a1db7856ef0595
url: "https://pub.dev"
source: hosted
- version: "0.2.1"
+ version: "0.2.2"
fl_chart:
dependency: "direct main"
description:
@@ -192,6 +232,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.5"
+ json_object_mapper:
+ dependency: transitive
+ description:
+ name: json_object_mapper
+ sha256: "8566947565045eb2a8dd679029c4fcbb84dfd0e10309a1693e67e83e174893a2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
lints:
dependency: transitive
description:
@@ -200,6 +248,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.1"
+ markdown:
+ dependency: transitive
+ description:
+ name: markdown
+ sha256: c2b81e184067b41d0264d514f7cdaa2c02d38511e39d6521a1ccc238f6d7b3f2
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.0.1"
matcher:
dependency: transitive
description:
@@ -252,10 +308,10 @@ packages:
dependency: transitive
description:
name: path_provider
- sha256: c7edf82217d4b2952b2129a61d3ad60f1075b9299e629e149a8d2e39c2e6aad4
+ sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2"
url: "https://pub.dev"
source: hosted
- version: "2.0.14"
+ version: "2.0.15"
path_provider_android:
dependency: transitive
description:
@@ -268,10 +324,10 @@ packages:
dependency: transitive
description:
name: path_provider_foundation
- sha256: ad4c4d011830462633f03eb34445a45345673dfd4faf1ab0b4735fbd93b19183
+ sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3"
url: "https://pub.dev"
source: hosted
- version: "2.2.2"
+ version: "2.2.3"
path_provider_linux:
dependency: transitive
description:
@@ -328,14 +384,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.0.5"
- settings_ui:
- dependency: "direct main"
+ resource_portable:
+ dependency: transitive
description:
- name: settings_ui
- sha256: d9838037cb554b24b4218b2d07666fbada3478882edefae375ee892b6c820ef3
+ name: resource_portable
+ sha256: "7b33fa68d1f088227f0d4ba6b1476ea9784fd320fc38385d938d641dc7b6ca0b"
url: "https://pub.dev"
source: hosted
- version: "2.0.2"
+ version: "3.0.1"
share_plus:
dependency: "direct main"
description:
@@ -401,10 +457,10 @@ packages:
dependency: "direct main"
description:
name: sqflite
- sha256: acf091c6e55c50d00b30b8532b2dd23e393cf775861665ebd0f15cdd6ebfb079
+ sha256: "3a82c9a216b46b88617e3714dd74227eaca20c501c4abcc213e56db26b9caa00"
url: "https://pub.dev"
source: hosted
- version: "2.2.8+1"
+ version: "2.2.8+2"
sqflite_common:
dependency: transitive
description:
@@ -453,6 +509,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
+ swiss_knife:
+ dependency: transitive
+ description:
+ name: swiss_knife
+ sha256: "3066fc2ed9a90139cf69f1733f6f9714f7a0a4e6a9d668451d5a1e371da8897b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.5"
synchronized:
dependency: transitive
description:
@@ -481,18 +545,18 @@ packages:
dependency: transitive
description:
name: typed_data
- sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
+ sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
- version: "1.3.1"
+ version: "1.3.2"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
- sha256: "75f2846facd11168d007529d6cd8fcb2b750186bea046af9711f10b907e1587e"
+ sha256: eb1e00ab44303d50dd487aab67ebc575456c146c6af44422f9c13889984c00f3
url: "https://pub.dev"
source: hosted
- version: "6.1.10"
+ version: "6.1.11"
url_launcher_android:
dependency: transitive
description:
pubspec.yaml
@@ -38,7 +38,6 @@ dependencies:
fl_chart: ^0.62.0 # MIT
file_saver: ^0.2.1 # BSD-3-Clause
share_plus: ^4.5.3 # BSD-3-Clause
- settings_ui: ^2.0.2 # Apache-2.0
flutter_material_color_picker: ^1.1.0+2 # MIT
file_picker: ^5.2.11 # MIT
csv: ^5.0.2 # MIT