Newer
Older
import 'package:flutter/material.dart';
import 'datamodel.dart';
import 'sensorconnector.dart';
import 'databaseconnector.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
class Configuration extends StatefulWidget {
@override
State<Configuration> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<Configuration> {
late Future<Collection> futureCollection;
late Future<List<Collection>> futureCollections;
late Future<List<EventType>> futureEventTypes;
late Future<List<Device>> futureDevices;
late Future<String> futureAuthToken;
var database = DatabaseInstance();
SensorConnector connector = SensorConnector();
final ConfigurationStoreInstance configuration = ConfigurationStoreInstance();
TextStyle _statusStyle = const TextStyle(color: Colors.black);
Future<void> dumpToFile() async{
var date = DateTime.now().toUtc();
var isoDate = date.toIso8601String();
String filename =
date.year.toString().padLeft(4, '0') +
date.month.toString().padLeft(2, '0') +
date.day.toString().padLeft(2, '0') +
date.hour.toString().padLeft(2, '0') +
date.minute.toString().padLeft(2, '0') +
date.second.toString().padLeft(2, '0') +
'_events.json';
String eventsJson = await database.eventDump();
final Directory? directory = await getExternalStorageDirectory();
if(directory != null) {
String filepath = join(directory.path, filename);
final File file = File(filepath);
await file.writeAsString(eventsJson);
debugPrint('Stored file at: ' + filepath);
Future<void> updateConfiguration() async {
final EventStoreInstance event = EventStoreInstance();
String token = '';
try{
token = await connector.getAuthToken(configuration.loginInformation.mail, configuration.loginInformation.password);
configuration.devices = await connector.fetchCollectionDevices(configuration.currentCollection.id); //await futureDevices; //already fetched just use the data.
configuration.eventTypes = await connector.fetchEventTypes();
event.currentEvent.id = 0;
event.currentEvent.urnId = configuration.devices[0].id; //TODO: fix if devices are an empty list.
event.currentEvent.urn = configuration.devices[0].urn;
event.currentEvent.description = '';
event.currentEvent.label = '';
event.currentEvent.type = configuration.eventTypes[0].name;
var date = DateTime.now().toUtc();
var isoDate = date.toIso8601String();
event.currentEvent.startDate = isoDate;
event.currentEvent.endDate = isoDate;
configuration.initialized = true;
HapticFeedback.vibrate();
//TODO: display success user feedback
//TODO: store complete "configuration"
await event.storeToSharedPrefs();
await configuration.storeToSharedPrefs();
debugPrint('Configuration stored!');
_statusStyle = const TextStyle(color: Colors.green);
} catch (e) {
debugPrint('Exception: $e');
_status = '$e';
_statusStyle = const TextStyle(color: Colors.red);
setState(() {});
}
Future<void> fetchInitData() async {
try {
futureCollections = connector.fetchCollections();
await futureCollections; //wait and catch error here!
}catch(e){
debugPrint(e.toString());
_statusStyle = const TextStyle(color: Colors.red);
}
@override
void initState() {
super.initState();
fetchInitData();
}
@override
Widget build(BuildContext context) {
final ConfigurationStoreInstance configuration = ConfigurationStoreInstance();
final EventStoreInstance events = EventStoreInstance();
appBar: AppBar(
title: const Text('Configuration'),
),
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 5.0),
child:
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
const SizedBox(height: 50),
const Text(
'You must be online to do something here!',
style: TextStyle(fontSize: 14)
),
const SizedBox(height: 50),
TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
initialValue: configuration.loginInformation.mail,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
onChanged: (value) {
configuration.loginInformation.mail = value;
},
const SizedBox(height: 15.0),
TextFormField(
autofocus: false,
initialValue: configuration.loginInformation.password,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
onChanged: (value){
configuration.loginInformation.password = value;
},
const SizedBox(height: 50),
FutureBuilder<List<Collection>>(
future: futureCollections,
builder: (context, snapshot){
if (snapshot.hasData)
{
configuration.collections = [];
snapshot.data?.forEach((element) {
configuration.collections.add(element);
});
/*Initialize active collection with first received collection if not initialized yet*/
if(configuration.currentCollection.id == -1){
configuration.currentCollection = configuration.collections[0];
}
return DropdownButtonFormField(
value: configuration.currentCollection.collectionName,
decoration: const InputDecoration(
labelText: 'Chose Collection',
border: OutlineInputBorder(),
),
items:
configuration.collections.map((Collection collection) {
return DropdownMenuItem(
value: collection.collectionName,
child: Text(collection.collectionName),
);
}).toList(),
onChanged: (value) {
configuration.currentCollection = configuration.getCollectionFromName(value.toString());
//Fetch new selected collection devices
futureDevices = connector.fetchCollectionDevices(configuration.currentCollection.id);
}
);
}
if (snapshot.hasError) {
debugPrint('Some error happened');
return const CircularProgressIndicator();
else{
return const CircularProgressIndicator();
}
),
const SizedBox(height: 50.0),
TextFormField(
readOnly: true,
autofocus: false,
enabled: false,
controller: TextEditingController(
text: _status,
),
),
const SizedBox(height: 15.0),
],
),
),
margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
FloatingActionButton.extended(
heroTag: null,
tooltip: 'Export events to local .json file',
icon: const Icon(Icons.download),
label: const Text('Dump Events'),
},
),
FloatingActionButton.extended(
heroTag: null,
//TODO: display failed as user feedback somehow
},
),
],
//TODO: write configuration on app dispose!
//TODO: align bottom buttons nicely!
//TODO: add label prefix with appended upcounting number.
//TODO: grey out update button if nothing has changed. ?