Commit 4841240
Changed files (11)
app/lib/l10n/app_en.arb
@@ -506,5 +506,7 @@
"titleInCsv": "Title in CSV",
"@titleInCsv": {},
"preferredPressureUnit": "Preferred pressure unit",
- "@preferredPressureUnit": {}
+ "@preferredPressureUnit": {},
+ "deleteAllMedicineIntakes": "Delete all medicine intakes",
+ "@deleteAllMedicineIntakes": {}
}
app/lib/model/storage/export_columns_store.dart
@@ -42,6 +42,7 @@ class ExportColumnsManager extends ChangeNotifier {
/// Reset all fields to their default values.
void reset() {
_userColumns.clear();
+ notifyListeners();
}
/// Namespaces that may not lead a user columns internal identifier.
app/lib/model/storage/export_csv_settings_store.dart
@@ -68,6 +68,7 @@ class CsvExportSettings extends ChangeNotifier implements CustomFieldsSettings {
_textDelimiter = d._textDelimiter;
_exportHeadline = d._exportHeadline;
_exportFieldsConfiguration = d._exportFieldsConfiguration;
+ notifyListeners();
}
String _fieldDelimiter = ',';
app/lib/model/storage/export_pdf_settings_store.dart
@@ -74,6 +74,7 @@ class PdfExportSettings extends ChangeNotifier implements CustomFieldsSettings {
_headerFontSize = d._headerFontSize;
_cellFontSize = d._cellFontSize;
_exportFieldsConfiguration = d._exportFieldsConfiguration;
+ notifyListeners();
}
bool _exportTitle = true;
app/lib/model/storage/export_settings_store.dart
@@ -43,6 +43,7 @@ class ExportSettings extends ChangeNotifier {
_exportFormat = d._exportFormat;
_defaultExportDir = d._defaultExportDir;
_exportAfterEveryEntry = d._exportAfterEveryEntry;
+ notifyListeners();
}
ExportFormat _exportFormat = ExportFormat.csv;
app/lib/model/storage/intervall_store.dart
@@ -270,6 +270,7 @@ class IntervallStoreManager extends ChangeNotifier {
mainPage = IntervallStorage();
exportPage = IntervallStorage();
statsPage = IntervallStorage();
+ notifyListeners();
}
/// Intervall for the page with graph and list.
app/lib/model/storage/settings_store.dart
@@ -181,6 +181,7 @@ class Settings extends ChangeNotifier {
_medications.clear();
_highestMedIndex = d._highestMedIndex;
_preferredPressureUnit = d._preferredPressureUnit;
+ notifyListeners();
}
Locale? _language;
app/lib/screens/subsettings/delete_data_screen.dart
@@ -1,15 +1,12 @@
-import 'dart:io';
-import 'dart:math';
-
-import 'package:blood_pressure_app/components/consistent_future_builder.dart';
-import 'package:blood_pressure_app/components/custom_banner.dart';
-import 'package:blood_pressure_app/main.dart';
+import 'package:blood_pressure_app/model/blood_pressure/model.dart';
+import 'package:blood_pressure_app/model/storage/export_columns_store.dart';
+import 'package:blood_pressure_app/model/storage/storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
-import 'package:path/path.dart';
-import 'package:restart_app/restart_app.dart';
-import 'package:sqflite/sqflite.dart';
+import 'package:health_data_store/health_data_store.dart';
+import 'package:provider/provider.dart';
+/// Screen that allows
class DeleteDataScreen extends StatefulWidget {
const DeleteDataScreen({super.key});
@@ -18,11 +15,6 @@ class DeleteDataScreen extends StatefulWidget {
}
class _DeleteDataScreenState extends State<DeleteDataScreen> {
- /// Whether or not files were deleted while on this page.
- ///
- /// Should never be reset to false.
- bool _deletedData = false;
-
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
@@ -32,193 +24,98 @@ class _DeleteDataScreenState extends State<DeleteDataScreen> {
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
- if (_deletedData) {
- Restart.restartApp();
- } else {
- Navigator.pop(context, );
- }
+ Navigator.pop(context);
},
),
),
- body: Column(
+ body: ListView(
children: [
- if (_deletedData)
- CustomBanner(
- content: Text(localizations.warnNeedsRestartForUsingApp),
- action: TextButton(
- onPressed: Restart.restartApp,
- child: Text(localizations.restartNow),
- ),
- ),
- Expanded(
- child: Container(
- padding: const EdgeInsets.all(10),
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(localizations.data, style: Theme.of(context).textTheme.headlineMedium),
- Expanded(
- child: ListView(
- children: [
- ListTile(
- leading: const Icon(Icons.timeline),
- title: Text(localizations.deleteAllMeasurements),
- subtitle: ConsistentFutureBuilder(
- future: Future(() async {
- final String dbPath = join(await getDatabasesPath(), 'blood_pressure.db');
- final String dbJournalPath = join(await getDatabasesPath(), 'blood_pressure.db-journal');
- int sizeBytes;
- try {
- sizeBytes = File(dbPath).lengthSync();
- } on PathNotFoundException {
- sizeBytes = 0;
- }
- try {
- sizeBytes += File(dbJournalPath).lengthSync();
- } on PathNotFoundException {}
-
- return _bytesToString(sizeBytes);
- }),
- onData: (context, data) => Text(data),
- ),
- trailing: const Icon(Icons.delete_forever),
- onTap: () async {
- final messanger = ScaffoldMessenger.of(context);
- if (await showDeleteDialoge(context, localizations)) {
- final String dbPath = join(await getDatabasesPath(), 'blood_pressure.db');
- final String dbJournalPath = join(await getDatabasesPath(), 'blood_pressure.db-journal');
- await closeDatabases();
- tryDeleteFile(dbPath, messanger, localizations);
- tryDeleteFile(dbJournalPath, messanger, localizations);
- setState(() {
- _deletedData = true;
- });
- }
- },
- ),
- ListTile(
- leading: const Icon(Icons.settings),
- title: Text(localizations.deleteAllSettings),
- subtitle: ConsistentFutureBuilder(
- future: Future(() async {
- final String dbPath = join(await getDatabasesPath(), 'config.db');
- final String dbJournalPath = join(await getDatabasesPath(), 'config.db-journal');
- int sizeBytes;
- try {
- sizeBytes = File(dbPath).lengthSync();
- } on PathNotFoundException {
- sizeBytes = 0;
- }
- try {
- sizeBytes += File(dbJournalPath).lengthSync();
- } on PathNotFoundException {}
- return _bytesToString(sizeBytes);
- }),
- onData: (context, data) => Text(data),
- ),
- trailing: const Icon(Icons.delete_forever),
- onTap: () async {
- final messanger = ScaffoldMessenger.of(context);
- if (await showDeleteDialoge(context, localizations)) {
- final String dbPath = join(await getDatabasesPath(), 'config.db');
- final String dbJournalPath = join(await getDatabasesPath(), 'config.db-journal');
- await closeDatabases();
- tryDeleteFile(dbPath, messanger, localizations);
- tryDeleteFile(dbJournalPath, messanger, localizations);
- setState(() {
- _deletedData = true;
- });
- }
- },
- ),
- ],
- ),
+ ListTile(
+ leading: const Icon(Icons.timeline),
+ title: Text(localizations.deleteAllMeasurements),
+ trailing: const Icon(Icons.delete_forever),
+ onTap: () async {
+ final messanger = ScaffoldMessenger.of(context);
+ if (await _showDeleteDialoge(context, localizations)) {
+ final model = context.read<BloodPressureModel>();
+ final previousRecords = await model.all;
+ for (final record in previousRecords) {
+ await model.delete(record.creationTime);
+ }
+ messanger.showSnackBar(SnackBar(
+ content: Text(localizations.deletionConfirmed),
+ action: SnackBarAction(
+ label: localizations.btnUndo,
+ onPressed: () => model.addAll(previousRecords, context),
),
- /* Text('Files', style: Theme.of(context).textTheme.headlineMedium),
- Expanded(
- flex: 3,
- child: ConsistentFutureBuilder(
- future: Future(() async => Directory(await getDatabasesPath()).list(recursive: true).toList()),
- onData: (context, files) =>
- ListView.builder(
- itemCount: files.length,
- itemBuilder: (context, idx) => ListTile(
- title: Text(files[idx].path),
- trailing: const Icon(Icons.delete_forever),
- onTap: () async {
- final messanger = ScaffoldMessenger.of(context);
- if (await showDeleteDialoge(context, localizations)) {
- if (!context.mounted) return;
- await unregisterAllProviders(context);
- files[idx].deleteSync();
- messanger.showSnackBar(SnackBar(
- duration: const Duration(seconds: 5),
- content: Text('File deleted.'),
- ));
- setState(() {
- _deletedData = true;
- });
- }
- },
- )
- )
- ),
- ), */
- ],
- ),
- ),
+ ));
+ }
+ },
+ ),
+ ListTile(
+ leading: const Icon(Icons.settings),
+ title: Text(localizations.deleteAllSettings),
+ trailing: const Icon(Icons.delete_forever),
+ onTap: () async {
+ final messanger = ScaffoldMessenger.of(context);
+ if (await _showDeleteDialoge(context, localizations)) {
+ context.read<Settings>().reset();
+ context.read<ExportSettings>().reset();
+ context.read<CsvExportSettings>().reset();
+ context.read<PdfExportSettings>().reset();
+ context.read<IntervallStoreManager>().reset();
+ context.read<ExportColumnsManager>().reset();
+ messanger.showSnackBar(SnackBar(
+ content: Text(localizations.deletionConfirmed),
+ ));
+ }
+ },
+ ),
+ ListTile(
+ leading: const Icon(Icons.medication),
+ title: Text(localizations.deleteAllMedicineIntakes),
+ trailing: const Icon(Icons.delete_forever),
+ onTap: () async {
+ if (await _showDeleteDialoge(context, localizations)) {
+ final repo = context.read<MedicineIntakeRepository>();
+ final allIntakes = await repo.get(DateRange(start: DateTime.fromMillisecondsSinceEpoch(0), end: DateTime.now()));
+ for (final intake in allIntakes) {
+ await repo.remove(intake);
+ }
+ final messanger = ScaffoldMessenger.of(context);
+ messanger.showSnackBar(SnackBar(
+ content: Text(localizations.deletionConfirmed),
+ ));
+ }
+ },
),
],
),
);
}
- /// Converts file size in bytes to human readable string
- String _bytesToString(int sizeBytes) {
- if (sizeBytes <= 0) return '0 B';
- const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
- final i = (log(sizeBytes) / log(1024)).floor();
- return '${(sizeBytes / pow(1024, i)).toStringAsFixed(1)} ${suffixes[i]}';
- }
-
- Future<bool> showDeleteDialoge(BuildContext context, AppLocalizations localizations) async => await showDialog<bool>(context: context, builder: (context) =>
- AlertDialog(
- title: Text(localizations.confirmDelete),
- content: Text(localizations.warnDeletionUnrecoverable),
- actionsAlignment: MainAxisAlignment.spaceBetween,
- actions: [
- TextButton(
- onPressed: () => Navigator.pop(context, false),
- child: Text(AppLocalizations.of(context)!.btnCancel),),
- Theme(
- data: ThemeData.from(
- colorScheme: ColorScheme.fromSeed(seedColor: Colors.red, brightness: Theme.of(context).brightness),
- useMaterial3: true,
- ),
- child: ElevatedButton.icon(
- onPressed: () => Navigator.pop(context, true),
- icon: const Icon(Icons.delete_forever),
- label: Text(AppLocalizations.of(context)!.btnConfirm),
- ),
- ),
-
- ],
+ /// Show dialoge to confirm irrevocable deletion.
+ Future<bool> _showDeleteDialoge(BuildContext context, AppLocalizations localizations) async => await showDialog<bool>(context: context, builder: (context) =>
+ AlertDialog(
+ title: Text(localizations.confirmDelete),
+ content: Text(localizations.warnDeletionUnrecoverable),
+ actionsAlignment: MainAxisAlignment.spaceBetween,
+ actions: [
+ TextButton(
+ onPressed: () => Navigator.pop(context, false),
+ child: Text(AppLocalizations.of(context)!.btnCancel),),
+ Theme(
+ data: ThemeData.from(
+ colorScheme: ColorScheme.fromSeed(seedColor: Colors.red, brightness: Theme.of(context).brightness),
+ useMaterial3: true,
+ ),
+ child: ElevatedButton.icon(
+ onPressed: () => Navigator.pop(context, true),
+ icon: const Icon(Icons.delete_forever),
+ label: Text(AppLocalizations.of(context)!.btnConfirm),
+ ),
),
- ) ?? false;
-
- void tryDeleteFile(String path, ScaffoldMessengerState messanger, AppLocalizations localizations) {
- try {
- File(path).deleteSync();
- messanger.showSnackBar(SnackBar(
- duration: const Duration(seconds: 2),
- content: Text(localizations.fileDeleted),
- ),);
- } on PathNotFoundException {
- messanger.showSnackBar(SnackBar(
- duration: const Duration(seconds: 2),
- content: Text(localizations.fileAlreadyDeleted),
- ),);
- }
- }
-}
\ No newline at end of file
+ ],
+ ),
+ ) ?? false;
+}
app/lib/screens/settings_screen.dart
@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:blood_pressure_app/components/consistent_future_builder.dart';
+import 'package:blood_pressure_app/components/custom_banner.dart';
import 'package:blood_pressure_app/components/dialoges/enter_timeformat_dialoge.dart';
import 'package:blood_pressure_app/components/dialoges/input_dialoge.dart';
import 'package:blood_pressure_app/components/settings/settings_widgets.dart';
@@ -23,7 +24,6 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:path/path.dart';
import 'package:provider/provider.dart';
-import 'package:restart_app/restart_app.dart';
import 'package:sqflite/sqflite.dart';
import 'package:url_launcher/url_launcher.dart';
@@ -318,13 +318,10 @@ class SettingsPage extends StatelessWidget {
}
String dbPath = await getDatabasesPath();
- assert(dbPath != inMemoryDatabasePath);
dbPath = join(dbPath, 'config.db');
File(path).copySync(dbPath);
- if (!await Restart.restartApp()) {
- messenger.showSnackBar(SnackBar(content: Text(localizations.pleaseRestart)));
- return;
- }
+ messenger.showMaterialBanner(CustomBanner(content: Text(localizations.pleaseRestart)));
+ // TODO: read settings and replace them on running app.
},
),
ListTile(
@@ -375,7 +372,7 @@ class SettingsPage extends StatelessWidget {
// TODO: give feedback
},
- )
+ ),
],
),
TitledColumn(title: Text(localizations.aboutWarnValuesScreen), children: [
app/pubspec.lock
@@ -595,14 +595,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.1"
- restart_app:
- dependency: "direct main"
- description:
- name: restart_app
- sha256: b37daeb1c02fcab30e19d9e30b6fdd215bd53577efd927042eb77cf6f09daadb
- url: "https://pub.dev"
- source: hosted
- version: "1.2.1"
shared_preferences:
dependency: "direct main"
description:
app/pubspec.yaml
@@ -34,7 +34,6 @@ dependencies:
# can become one custom dependency
file_picker: ^8.0.3 # MIT
jsaver: ^1.2.0
- restart_app: ^1.2.1
fluttertoast: ^8.2.4
dev_dependencies: