Commit 977adf4
Changed files (5)
lib
model
blood_pressure
screens
subsettings
export_import
lib/model/blood_pressure/model.dart
@@ -77,8 +77,8 @@ class BloodPressureModel extends ChangeNotifier {
/// Adds a new measurement at the correct chronological position in the List.
///
- /// This is not suitable for user inputs, as in this case export is needed as well. Consider using
- /// [BloodPressureModel.addAndExport] instead.
+ /// This is not suitable for user inputs, as in this case export is needed as
+ /// well. Consider using [BloodPressureModel.addAndExport] instead.
Future<void> add(BloodPressureRecord measurement) async {
if (!_database.isOpen) return;
final existing = await _database.query('bloodPressureModel',
@@ -108,6 +108,26 @@ class BloodPressureModel extends ChangeNotifier {
notifyListeners();
}
+ /// Convenience wrapper for [add] that follows best practices.
+ ///
+ /// This ensures no timeout occurs by waiting for operations to finish and
+ /// exports in case the [context] is provided and the option in export
+ /// settings is active.
+ Future<void> addAll(
+ List<BloodPressureRecord> measurements,
+ BuildContext? context,
+ ) async {
+ for (final measurement in measurements) {
+ await add(measurement);
+ }
+
+ if (context == null || !context.mounted) return;
+ final exportSettings = Provider.of<ExportSettings>(context, listen: false);
+ if (exportSettings.exportAfterEveryEntry) {
+ performExport(context);
+ }
+ }
+
/// Adds a measurement to the model and tries to export all measurements, if [ExportSettings.exportAfterEveryEntry] is
/// true.
Future<void> addAndExport(BuildContext context, BloodPressureRecord record) async {
lib/screens/subsettings/foreign_db_import_screen.dart
@@ -16,11 +16,20 @@ import 'package:sqflite/sqflite.dart';
/// Parses data table to [BloodPressureRecord] list.
class ForeignDBImportScreen extends StatefulWidget {
/// Create a screen to import data from a database with unknown structure.
- const ForeignDBImportScreen({super.key, required this.db});
+ ///
+ /// Parses selected data to a [BloodPressureRecord] list.
+ const ForeignDBImportScreen({super.key,
+ required this.db,
+ required this.bottomAppBars,
+ });
/// Database from which to import data.
final Database db;
+ /// Whether to move the app bar for saving and loading to the bottom of the
+ /// screen.
+ final bool bottomAppBars;
+
@override
State<ForeignDBImportScreen> createState() => _ForeignDBImportScreenState();
}
@@ -60,7 +69,8 @@ class _ForeignDBImportScreenState extends State<ForeignDBImportScreen> {
}
if (elements.length < 4) return 'Select at least one data column';
- return 'The schnibledumps doesn\'t schwibble!'; // TODO
+ // return 'The schnibledumps doesn\'t schwibble!'; // TODO check if more tests are required
+ return null;
},
onSaved: (List<String> madeSelections) async {
final tableName = madeSelections.removeAt(0);
@@ -126,7 +136,7 @@ class _ForeignDBImportScreenState extends State<ForeignDBImportScreen> {
return 'Select column type (${selections.last})';
}
},
- bottomAppBars: true, // TODO
+ bottomAppBars: widget.bottomAppBars, // TODO
);
// TODO: localize everything
// TODO: detect when no more selections are possible
@@ -177,3 +187,18 @@ class _ColumnImportData {
/// Names of all tables.
Iterable<String> get tableNames => columns.keys;
}
+
+/// Shows a dialoge to import arbitrary data from a external database.
+Future<List<BloodPressureRecord>?> showForeignDBImportDialoge(
+ BuildContext context,
+ bool bottomAppBars,
+ Database db) =>
+ showDialog<List<BloodPressureRecord>>(
+ context: context, builder: (context) =>
+ Dialog.fullscreen(
+ child: ForeignDBImportScreen(
+ bottomAppBars: bottomAppBars,
+ db: db,
+ ),
+ ),
+ );
lib/screens/settings_screen.dart
@@ -4,6 +4,7 @@ import 'package:blood_pressure_app/components/consistent_future_builder.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';
+import 'package:blood_pressure_app/model/blood_pressure/model.dart';
import 'package:blood_pressure_app/model/blood_pressure/warn_values.dart';
import 'package:blood_pressure_app/model/iso_lang_names.dart';
import 'package:blood_pressure_app/model/storage/storage.dart';
@@ -341,11 +342,13 @@ class SettingsPage extends StatelessWidget {
},
),
ListTile(
- title: Text('TODO'), // TODO
- leading: Icon(Icons.add_circle, color: Colors.red,),
+ title: Text('Import foreign database (Preview)'), // TODO
+ subtitle: Text('Unstable feature: Use at your own risk. Please'
+ ' open issues and give feedback in form of issues on this '
+ 'projects GitHub page (accessible through the source code button).'),
+ leading: Icon(Icons.add_circle, color: Colors.orange,),
onTap: () async {
final messenger = ScaffoldMessenger.of(context);
- final navigator = Navigator.of(context);
final result = await FilePicker.platform.pickFiles();
if (result == null) {
@@ -360,9 +363,20 @@ class SettingsPage extends StatelessWidget {
final db = await openDatabase(path);
- navigator.push(MaterialPageRoute(builder: (context) =>
- ForeignDBImportScreen(db: db,),),
- );
+ if (!context.mounted) return;
+ final data = await showForeignDBImportDialoge(context,
+ settings.bottomAppBars, db,);
+
+ if (!context.mounted) return;
+ if (data == null) {
+ messenger.showSnackBar(SnackBar(content: Text(localizations.errNotImportable)));
+ return;
+ }
+ // TODO: Show import preview
+ final model = Provider.of<BloodPressureModel>(context, listen: false);
+ await model.addAll(data, context);
+ // TODO: give feedback
+
},
)
],
test/ram_only_implementations.dart
@@ -47,4 +47,11 @@ class RamBloodPressureModel extends ChangeNotifier implements BloodPressureModel
Future<void> addAndExport(BuildContext context, BloodPressureRecord record) async {
add(record);
}
+
+ @override
+ Future<void> addAll(List<BloodPressureRecord> measurements, BuildContext? context) async {
+ for (final m in measurements) {
+ add(m);
+ }
+ }
}