import 'dart:io'; import 'package:flutter/material.dart'; import 'datamodel.dart'; import 'sensorconnector.dart'; import 'databaseconnector.dart'; class ViewEvents extends StatefulWidget { const ViewEvents({Key? key}) : super(key: key); @override _ViewEvents createState() => _ViewEvents(); } class _ViewEvents extends State<ViewEvents> { // Get singleton to access locally stored events: final EventStoreInstance _events = EventStoreInstance(); String _syncStatus = ''; var database = DatabaseInstance(); List<Event> localEvents = []; Future<void> fetchEventsFromDb() async{ localEvents = await database.getEvents(); int pendingEventCnt = await database.getPendingEventCnt(); _syncStatus = pendingEventCnt.toString() + ' event(s) pending'; setState(() {}); //Got events from database, so update UI } @override void initState() { _syncStatus = ''; super.initState(); fetchEventsFromDb(); } Future<void> syncEvents() async { final ConfigurationStoreInstance configuration = ConfigurationStoreInstance(); SensorConnector connection = SensorConnector(); List<Event> events = await database.getPendingEvents(); int syncCounter = events.length; debugPrint('Pending Events'); for (var event in events){ debugPrint(event.toString()); } if(syncCounter > 0) { try { String? token = await connection.getAuthToken( configuration.loginInformation.mail, configuration.loginInformation.password); var index = 0; for (var event in events) { debugPrint('Idx: ' + index.toString() + ' ' + event.toSensorJson().toString()); index++; if (await connection.putEvent(event, token) == true) { //Event has been posted to Sensor. syncCounter--; debugPrint( 'put success, remaining events: ' + syncCounter.toString()); event.status = 'EXPORTED'; //Update event to export only once database.updateEvent(event); //Update Event as exported in SQL Database fetchEventsFromDb(); //update view list //TODO: this is bad for the sync performance! setState(() {}); } else { throw Exception('Sync for ' + event.urn + 'failed'); } } _syncStatus = 'export success'; } catch (e) { debugPrint('Exception: $e'); _syncStatus = '$e'; setState(() {}); } }else{ debugPrint('No PENDING event(s)'); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("View & Sync"), ), body: Container( margin: const EdgeInsets.symmetric(horizontal: 5.0), child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: SingleChildScrollView( scrollDirection: Axis.vertical, child: DataTable( columns: const <DataColumn>[ DataColumn( label: Text( 'UrnId', style: TextStyle(fontStyle: FontStyle.italic), ), ), DataColumn( label: Text( 'URN', style: TextStyle(fontStyle: FontStyle.italic), ), ), DataColumn( label: Text( 'Label', style: TextStyle(fontStyle: FontStyle.italic), ), ), DataColumn( label: Text( 'Type', style: TextStyle(fontStyle: FontStyle.italic), ), ), DataColumn( label: Text( 'Description', style: TextStyle(fontStyle: FontStyle.italic), ), ), DataColumn( label: Text( 'StartDate', style: TextStyle(fontStyle: FontStyle.italic), ), ), DataColumn( label: Text( 'EndDate', style: TextStyle(fontStyle: FontStyle.italic), ), ), DataColumn( label: Text( 'Latitude', style: TextStyle(fontStyle: FontStyle.italic), ), ), DataColumn( label: Text( 'Longitude', style: TextStyle(fontStyle: FontStyle.italic), ), ), DataColumn( label: Text( 'Elevation', style: TextStyle(fontStyle: FontStyle.italic), ), ), DataColumn( label: Text( 'Status', style: TextStyle(fontStyle: FontStyle.italic), ), ), ], rows: <DataRow>[ for (var event in localEvents) DataRow( cells: <DataCell>[ DataCell(Text(event.urnId.toString())), DataCell(Text(event.urn)), DataCell( TextFormField( readOnly: true, initialValue: event.label, onFieldSubmitted: (val) { event.label = val; //Update Database }, ), ), DataCell(Text(event.type)), DataCell( TextFormField( readOnly: true, initialValue: event.description, onFieldSubmitted: (val) { event.description = val; //Update Database }, ), ), DataCell(Text(event.startDate)), DataCell(Text(event.endDate)), DataCell( TextFormField( readOnly: true, initialValue: event.latitude, onFieldSubmitted: (val) { event.latitude = val; //Update Database }, ), ), DataCell( TextFormField( readOnly: true, initialValue: event.longitude, onFieldSubmitted: (val) { event.longitude = val; //Update Database }, ), ), DataCell( TextFormField( readOnly: true, initialValue: event.elevation, onFieldSubmitted: (val) { event.elevation = val; //Update Database }, ), ), DataCell( TextFormField( readOnly: true, controller: TextEditingController( //Required to update field here text: event.status, ), onFieldSubmitted: (val) { event.status = val; //Update Database }, ), ), ], ), ], ), ), ), ), bottomNavigationBar: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ const SizedBox(width: 10), Text(_syncStatus), const SizedBox(width: 50), Container( margin: const EdgeInsets.symmetric(vertical: 10.0), child: FloatingActionButton.extended( heroTag: null, tooltip: 'Upload Events', icon: null, label: const Text('Sync'), onPressed: () { syncEvents(); }, ), ), const SizedBox(width: 5.0), ], ), ); } } //TODO: allow editing fields here.