From 7722a72283be8d5113741d5197d0bace3ca80750 Mon Sep 17 00:00:00 2001
From: Maximilian Betz <Maximilian.Betz@awi.de>
Date: Thu, 31 Mar 2022 14:24:32 +0200
Subject: [PATCH] cleanup

---
 lib/addevent.dart      | 70 ++++++++++++++++++++++++++----------------
 lib/configuration.dart | 21 +++++++------
 lib/datamodel.dart     | 37 ++++++++++++++++++++++
 lib/main.dart          | 22 +++----------
 lib/viewevents.dart    |  2 +-
 5 files changed, 96 insertions(+), 56 deletions(-)

diff --git a/lib/addevent.dart b/lib/addevent.dart
index c798fb3..c1cde5a 100644
--- a/lib/addevent.dart
+++ b/lib/addevent.dart
@@ -1,3 +1,5 @@
+import 'dart:convert';
+
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
@@ -6,6 +8,7 @@ import 'datamodel.dart';
 import 'databaseconnector.dart';
 import 'dart:async';
 import 'package:geolocator/geolocator.dart';
+import 'package:shared_preferences/shared_preferences.dart';
 
 class AddEvent extends StatefulWidget {
   const AddEvent({Key? key}) : super(key: key);
@@ -16,6 +19,7 @@ class AddEvent extends StatefulWidget {
 
 class _AddEventPageState extends State<AddEvent>  {
   bool syncGNSSData = true;
+  bool _addButtonEnabled = true;
   late String long = "";
   late String lat = "";
   late String alt = "";
@@ -90,14 +94,18 @@ class _AddEventPageState extends State<AddEvent>  {
   }
 
   @override
-  void dispose() {
-
+  void dispose() async {
     try {
       streamHandler.cancel();
       debugPrint('Cancel location stream');
     }catch(e){
       debugPrint('Canceling location stream failed');
     }
+
+    /*Async update current event configuration to shared preferences*/
+    final EventStoreInstance event = EventStoreInstance();
+    event.storeToSharedPrefs();
+
     super.dispose();
   }
 
@@ -133,23 +141,21 @@ class _AddEventPageState extends State<AddEvent>  {
     }
     var number = num.tryParse(value);
     if(number != null){
-        return true;  // Any numerical value is valid for elevation
+      return true;  // Any numerical value is valid for elevation
     }
     return false;
   }
 
   bool _validateInput(){
-    final EventStoreInstance eventStore = EventStoreInstance();
+    final EventStoreInstance event = EventStoreInstance();
     if (RegExp(r'^[a-z A-Z . \- 0-9 , ( ) + - _ :]+$').hasMatch(
-        eventStore.currentEvent.label)) {
+        event.currentEvent.label)) {
       if (RegExp(r'^[a-z A-Z . \- 0-9 , ( ) + - _ :]+$').hasMatch(
-          eventStore.currentEvent.description) || eventStore.currentEvent.description == '') {
-        if(_validateLatitude(eventStore.currentEvent.latitude)){
-          if(_validateLongitude(eventStore.currentEvent.longitude)){
-            if(_validateElevation(eventStore.currentEvent.elevation)){
-              debugPrint('All inputs valid');
+          event.currentEvent.description) || event.currentEvent.description == '') {
+        if(_validateLatitude(event.currentEvent.latitude)){
+          if(_validateLongitude(event.currentEvent.longitude)){
+            if(_validateElevation(event.currentEvent.elevation)){
               return true;
-
             }
           }
         }
@@ -158,15 +164,32 @@ class _AddEventPageState extends State<AddEvent>  {
     return false;
   }
 
-  void _storeCurrentEvent() {
-    final EventStoreInstance eventStore = EventStoreInstance();
+  bool _addButtonStatus(){
+    if((_validateInput() == true) && (_addButtonEnabled == true)){
+
+      return true;
+    }
+    return false;
+  }
+
+  Future<void> _storeCurrentEvent() async {
+    final EventStoreInstance event = EventStoreInstance();
     final ConfigurationStoreInstance configuration = ConfigurationStoreInstance();
-    eventStore.currentEvent.typeId = configuration.getEventIdFromName(eventStore.currentEvent.type);
-    eventStore.currentEvent.status = "PENDING";
-    database.addEvent(eventStore.currentEvent);  //TODO: display feedback after this async function
+    event.currentEvent.typeId = configuration.getEventIdFromName(event.currentEvent.type);
+    event.currentEvent.status = "PENDING";
+    await database.addEvent(event.currentEvent);  //TODO: display feedback after this async function
+    HapticFeedback.vibrate(); //Feedback that adding event succeeded
+    _addButtonEnabled = true; //Activate button for add more events
+    setState(() {});
 
+    //Update timestamp in UI
+    var date = DateTime.now().toUtc();
+    var isoDate = date.toIso8601String();
+    event.currentEvent.startDate = isoDate;
+    event.currentEvent.endDate = isoDate;
   }
 
+
   @override
   Widget build(BuildContext context) {
     /* Get singletons to access relevant data here.*/
@@ -456,20 +479,13 @@ class _AddEventPageState extends State<AddEvent>  {
             const SizedBox(width: 50),
             Container(
                 margin: const EdgeInsets.symmetric(vertical: 10.0),
-                child: _validateInput() ?
+                child: _addButtonStatus() ?
                 FloatingActionButton(
                   onPressed: () {
                     if (_validateInput()) {
+                      _addButtonEnabled = false;  //Disable button until event is stored
                       _storeCurrentEvent();
-                      HapticFeedback.vibrate();
-
-                      //Update time for next event
-                      var date = DateTime.now().toUtc();
-                      var isoDate = date.toIso8601String();
-                      eventStore.currentEvent.startDate = isoDate;
-                      eventStore.currentEvent.endDate = isoDate;
 
-                      debugPrint(date.toIso8601String());
                     }
                     setState(() {});
                   },
@@ -484,7 +500,7 @@ class _AddEventPageState extends State<AddEvent>  {
                       //refresh the UI
                     });
                   },
-                  tooltip: 'Correct Inputs before adding the Event',
+                  tooltip: 'Complete / correct inputs before adding the Event',
                   //child: const Icon(Icons.check),
                 )
             ),
@@ -500,7 +516,7 @@ class _AddEventPageState extends State<AddEvent>  {
           crossAxisAlignment: CrossAxisAlignment.end,
           children: const <Widget>[
             Text(
-                '  Visit Configuration first.',
+                '  Visit Configuration first',
                 style: TextStyle(fontSize: 20)
             ),
           ],
diff --git a/lib/configuration.dart b/lib/configuration.dart
index 2c9bfa2..3cc0ac8 100644
--- a/lib/configuration.dart
+++ b/lib/configuration.dart
@@ -100,9 +100,8 @@ class _MyHomePageState extends State<Configuration> {
             throw Exception('Something went wrong try again');
           }
 
-          final prefs = await SharedPreferences.getInstance();
-          prefs.setString('configuration', jsonEncode(configuration.toMap()));
-          prefs.setString('currentEvent', jsonEncode(event.toMap()));
+          await event.storeToSharedPrefs();
+          await configuration.storeToSharedPrefs();
           debugPrint('Configuration stored!');
         });
       });
@@ -135,13 +134,15 @@ class _MyHomePageState extends State<Configuration> {
         appBar: AppBar(
           title: const Text('Configuration'),
         ),
-        body: Container(
+        body: SingleChildScrollView(
+        child: Container(
           margin: const EdgeInsets.symmetric(horizontal: 5.0),
           child:
           Center(
             child: Column(
               mainAxisAlignment: MainAxisAlignment.center,
               children: <Widget>[
+                const SizedBox(height: 50),
                 const Text(
                     'You must be online to do something here!',
                     style: TextStyle(fontSize: 14)
@@ -222,6 +223,7 @@ class _MyHomePageState extends State<Configuration> {
             ),
           ),
         ),
+        ),
         bottomNavigationBar: Container(
           margin: const EdgeInsets.symmetric(vertical: 10.0),
           child: Row(
@@ -236,18 +238,18 @@ class _MyHomePageState extends State<Configuration> {
                 onPressed: () {
                   dumpToFile();
 
-                  //events.reset();  //TODO: remove before release this is not a real use case!
-                  //var db = DatabaseInstance();
-                  //db.delete();
+                  //TODO: remove before release this is not a real use case!
+                  var db = DatabaseInstance();
+                  db.delete();
                   //configuration.reset();
                 },
               ),
               const SizedBox(width: 50),
               FloatingActionButton.extended(
                 heroTag: null,
-                tooltip: 'Select Collection and download corresponding devices',
+                tooltip: 'Download corresponding devices and store locally',
                 icon: const Icon(Icons.save),
-                label: const Text('Store'),
+                label: const Text('Update'),
                 onPressed: () {
                   updateConfiguration();
                   //TODO: display failed as user feedback somehow
@@ -261,5 +263,4 @@ class _MyHomePageState extends State<Configuration> {
   }
 }
 
-//TODO: add scrowlable view here for landscape compatibility.
 //TODO: write configuration on  app dispose!
\ No newline at end of file
diff --git a/lib/datamodel.dart b/lib/datamodel.dart
index 9eaeaed..b9488bd 100644
--- a/lib/datamodel.dart
+++ b/lib/datamodel.dart
@@ -2,6 +2,7 @@
 import 'dart:convert';
 
 import 'package:flutter/cupertino.dart';
+import 'package:shared_preferences/shared_preferences.dart';
 
 class Collection {
   int id;
@@ -335,6 +336,24 @@ class ConfigurationStoreInstance extends ConfigurationStoreBase {
   static final ConfigurationStoreInstance _instance = ConfigurationStoreInstance
       ._internal();
 
+  Future<void> storeToSharedPrefs() async {
+    final prefs = await SharedPreferences.getInstance();
+    prefs.setString('configuration', jsonEncode(toMap()));
+    debugPrint('Stored current configuration to shared prefs');
+  }
+
+  Future<void> loadFromSharedPrefs() async {
+    final prefs = await SharedPreferences.getInstance();
+    final String? configuration = prefs.getString('configuration');
+    if (configuration != null){
+      debugPrint('Configuration Current Event String: ' + configuration);
+      fromMap(jsonDecode(configuration));
+      debugPrint('Configuration Current Event loaded from shared preferences');
+    }else{
+      debugPrint('Failed to load Current Event configuration from shared preferences.');
+    }
+  }
+
   factory ConfigurationStoreInstance() {
     return _instance;
   }
@@ -382,6 +401,24 @@ abstract class EventStoreBase{
 class EventStoreInstance extends EventStoreBase {
   static final EventStoreInstance _instance = EventStoreInstance._internal();
 
+  Future<void> storeToSharedPrefs() async {
+    final prefs = await SharedPreferences.getInstance();
+    prefs.setString('currentEvent', jsonEncode(toMap()));
+    debugPrint('Stored current event to shared prefs');
+  }
+
+  Future<void> loadFromSharedPrefs() async {
+    final prefs = await SharedPreferences.getInstance();
+    final String? currentEvent = prefs.getString('currentEvent');
+    if (currentEvent != null){
+      debugPrint('Configuration Current Event String: ' + currentEvent);
+      fromMap(jsonDecode(currentEvent));
+      debugPrint('Configuration Current Event loaded from shared preferences');
+    }else{
+      debugPrint('Failed to load Current Event configuration from shared preferences.');
+    }
+  }
+
   factory EventStoreInstance() {
     return _instance;
   }
diff --git a/lib/main.dart b/lib/main.dart
index 25b97d4..f4f1bba 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -14,24 +14,10 @@ Future<void> loadConfiguration() async {
   final EventStoreInstance event = EventStoreInstance();
   WidgetsFlutterBinding.ensureInitialized();
 
-  final prefs = await SharedPreferences.getInstance();
-  final String? storedConfiguration = prefs.getString('configuration');
-  if (storedConfiguration != null){
-    debugPrint('Configuration String: ' + storedConfiguration);
-    configuration.fromMap(jsonDecode(storedConfiguration));
-    debugPrint('Configuration loaded from shared preferences');
-  }else{
-    debugPrint('Failed to load configuration from shared preferences.');
-  }
-
-  final String? currentEvent = prefs.getString('currentEvent');
-  if (currentEvent != null){
-    debugPrint('Configuration Current Event String: ' + currentEvent);
-    event.fromMap(jsonDecode(currentEvent));
-    debugPrint('Configuration Current Event loaded from shared preferences');
-  }else{
-    debugPrint('Failed to load Current Event configuration from shared preferences.');
-  }
+
+  await configuration.loadFromSharedPrefs();
+  await event.loadFromSharedPrefs();
+
 
   //const storage = FlutterSecureStorage();   //TODO: move login information to secure storage
   //Map<String, String> allValues = await storage.readAll();
diff --git a/lib/viewevents.dart b/lib/viewevents.dart
index 00a9fd5..59fb283 100644
--- a/lib/viewevents.dart
+++ b/lib/viewevents.dart
@@ -268,4 +268,4 @@ class _ViewEvents extends State<ViewEvents> {
     );
   }
 }
-//TODO: allow editing fields here. Check validation of input value!
+//TODO: allow editing fields here.
-- 
GitLab