diff --git a/build/app/outputs/apk/release/app-release.apk b/build/app/outputs/apk/release/app-release.apk index 0fb65edd01fbc3aed07b8e26d4a6a1de2e389b12..cd3478f0a69d80e7d73f5146cad889abc7b78356 100644 Binary files a/build/app/outputs/apk/release/app-release.apk and b/build/app/outputs/apk/release/app-release.apk differ diff --git a/lib/datamodel.dart b/lib/datamodel.dart index 178ba4d5af497571dff1c2342c6e2845ca359e98..4d16b19db7fa64ea2a9cd47c8458e49cc7fe457b 100644 --- a/lib/datamodel.dart +++ b/lib/datamodel.dart @@ -243,6 +243,16 @@ class ConfigurationStoreInstance extends ConfigurationStoreBase { abstract class EventStoreBase{ List<Event> events = []; Event currentEvent = Event(0, 'urn0', '', '', -1, '', 'PENDING', '', ''); + + int getPendingEventCount(){ + int count = 0; + for (var event in events) { + if (event.status == 'PENDING') { + count++; + } + } + return count; + } } class EventStoreInstance extends EventStoreBase { diff --git a/lib/main.dart b/lib/main.dart index c15c5533a220065ad5aa55d789ee84e94973265c..729c29c6666b33105266414332550953caaf29c7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'datamodel.dart'; @@ -13,13 +12,12 @@ void main() { final ConfigurationStoreInstance configuration = ConfigurationStoreInstance(); //Reset old data - events.reset(); + events.reset(); // TODO: load configuration and events from shared preferences. configuration.reset(); configuration.loginInformation.mail = 'admin'; // Sandbox.sensor.de admin account configuration.loginInformation.password ='adminadmin'; //TODO: replace for productive version. - // TODO: load configuration and events from shared preferences. runApp(MaterialApp( title: 'Mobile Event Log', diff --git a/lib/overview.dart b/lib/overview.dart index 39afd025dc5858528248f4de476f27ec3ed0b044..5f819aa4539ab17e46ec641b30ee7038f6bef612 100644 --- a/lib/overview.dart +++ b/lib/overview.dart @@ -23,7 +23,7 @@ class Overview extends StatelessWidget { const SizedBox(height: 10), Expanded( child: ElevatedButton( - child: const Text('View Added Events', style: TextStyle(fontSize: 22)), + child: const Text('View and Sync', style: TextStyle(fontSize: 22)), onPressed: () { Navigator.pushNamed(context, '/third'); }, diff --git a/lib/viewevents.dart b/lib/viewevents.dart index a6d61044ea754a68a701887edd80d8e9d969a471..55e57efda9021fef33dcaa4c49fcd05ca91b222b 100644 --- a/lib/viewevents.dart +++ b/lib/viewevents.dart @@ -5,59 +5,71 @@ import 'package:flutter/material.dart'; import 'datamodel.dart'; import 'package:http/http.dart' as http; -Future<bool> syncEvents() async { - final EventStoreInstance events = EventStoreInstance(); - final ConfigurationStoreInstance configuration = ConfigurationStoreInstance(); +class ViewEvents extends StatefulWidget { + const ViewEvents({Key? key}) : super(key: key); - String baseUrl = 'https://sandbox.sensor.awi.de/rest/sensors/events/putEvent/'; - String url = ''; + @override + _ViewEvents createState() => _ViewEvents(); +} +class _ViewEvents extends State<ViewEvents> { + int _synccounter = 0; //For displaying progress during event upload + Future<bool> syncEvents() async { + final EventStoreInstance events = EventStoreInstance(); + final ConfigurationStoreInstance configuration = ConfigurationStoreInstance(); - debugPrint('Number of Events: ' + events.events.length.toString()); - debugPrint('Pending Events:'); - var index = 0; - for (var event in events.events){ - if (event.status == 'PENDING') { - debugPrint('Idx: ' + index.toString() + ' ' + event.toSensorJson().toString()); - index++; + String baseUrl = 'https://sandbox.sensor.awi.de/rest/sensors/events/putEvent/'; + String url = ''; - url = baseUrl + event.id.toString() + '?createVersion=false'; - debugPrint('XXX ' + Uri.parse(url).toString()); - final response = await http.put(Uri.parse(url), + _synccounter = events.getPendingEventCount(); + debugPrint('Number of Events: ' + events.events.length.toString()); + debugPrint('Number of Pending Events: ' + _synccounter.toString()); + var index = 0; + for (var event in events.events){ + if (event.status == 'PENDING') { + debugPrint('Idx: ' + index.toString() + ' ' + event.toSensorJson().toString()); + index++; - headers: { - "Content-Type": "application/json", - "Cookie": "x-auth-token=72d9d4d20a33f87edca7e1ba01ce8db8" - }, - body: event.toSensorJson().toString(), - encoding: Encoding.getByName("utf-8"), - ); + url = baseUrl + event.id.toString() + '?createVersion=false'; + debugPrint('XXX ' + Uri.parse(url).toString()); + final response = await http.put(Uri.parse(url), + headers: { + "Content-Type": "application/json", + "Cookie": "x-auth-token=72d9d4d20a33f87edca7e1ba01ce8db8" + }, + body: event.toSensorJson().toString(), + encoding: Encoding.getByName("utf-8"), + ); - if (response.statusCode == 201) { - debugPrint('put success'); - event.status = 'EXPORTED'; //Update event status so that it is only exported once. + if (response.statusCode == 201) { + _synccounter--; + debugPrint('put success, remaining events: ' +_synccounter.toString()); + event.status = 'EXPORTED'; //Update event status so that it is only exported once. - debugPrint(response.body.toString()); - debugPrint(response.headers.toString()); - debugPrint(response.headers['set-cookie']); + //if(mounted){ + // setState(() { //refresh the UI + // });} - } else { - debugPrint('Header: ' + response.headers.toString()); - debugPrint('Body: ' + response.body.toString()); - debugPrint('StatusCode: ' + response.statusCode.toString()); - throw Exception('Failed to put.'); - } - } - } + setState(() { - return true; -} + }); + debugPrint(response.body.toString()); + debugPrint(response.headers.toString()); + debugPrint(response.headers['set-cookie']); -class ViewEvents extends StatelessWidget { - const ViewEvents({Key? key}) : super(key: key); + } else { + debugPrint('Header: ' + response.headers.toString()); + debugPrint('Body: ' + response.body.toString()); + debugPrint('StatusCode: ' + response.statusCode.toString()); + throw Exception('Failed to put.'); + } + } + } + return true; + } @override Widget build(BuildContext context) { @@ -218,39 +230,56 @@ class ViewEvents extends StatelessWidget { icon: null, label: const Text('Sync'), onPressed: () { + + syncEvents(); //showDialog( + // barrierDismissible: false, // context: context, // builder: (BuildContext context) => _buildPopupDialog(context), //); - - syncEvents(); }, ), ], ), ); } -} -Widget _buildPopupDialog(BuildContext context) { - return AlertDialog( - title: const Text('Popup example'), - content: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: const <Widget>[ - Text("Hello"), - ], - ), - actions: <Widget>[ - FlatButton( - onPressed: () { - Navigator.of(context).pop(); - }, - textColor: Theme.of(context).primaryColor, - child: const Text('Close'), + Widget _buildPopupDialog(BuildContext context) { + + return AlertDialog( + title: const Text('Uploading Events'), + + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: <Widget>[ + //Text("Progress"), + const CircularProgressIndicator(), + const SizedBox(height: 10), + Text('Remaining events to sync: ' + _synccounter.toString()), + ], ), - ], - ); + actions: <Widget>[ + TextButton( + onPressed: () { + //syncEvents(); + + setState(() { + + }); + //Navigator.of(context).pop(); + }, + //textColor: Theme.of(context).primaryColor, + child: const Text('Close'), + ), + ], + ); + } + + + } + + + //TODO: allow editing fields here. Check validation of input value! \ No newline at end of file