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();
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 = '';
List<Device> devices = [];
try{
token = await connector.getAuthToken(configuration.loginInformation.mail, configuration.loginInformation.password);
devices = await connector.fetchCollectionDevices(configuration.currentCollection.id);
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!');
_status = 'Login success & configuration stored';
setState(() {});
} on SocketException catch (e) {
debugPrint('Exception: $e');
_status = 'No connection';
setState(() {});
} catch (e) {
debugPrint('Exception: $e');
_status = '$e';
setState(() {});
}
Future<void> fetchInitData() async {
try {
//Start fetching all possible sensor data as soon as possible:
futureCollections = connector.fetchCollections();
futureEventTypes = connector.fetchEventTypes();
if (configuration.currentCollection.id != -1) {
futureDevices = connector.fetchCollectionDevices(configuration.currentCollection.id);
}
await futureCollections;
await futureEventTypes;
await futureDevices;
}catch(e){
debugPrint(e.toString());
}
@override
void initState() {
super.initState();
fetchInitData();
late Future<String> eventTypes;
@override
Widget build(BuildContext context) {
final ConfigurationStoreInstance configuration = ConfigurationStoreInstance();
final EventStoreInstance events = EventStoreInstance();
appBar: AppBar(
title: const Text('Configuration'),
),
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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)
),
const SizedBox(height: 50),
TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
initialValue: configuration.loginInformation.mail,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Sensor E-Mail',
hintText: 'User for writing events',
),
onChanged: (value) {
configuration.loginInformation.mail = value;
},
onFieldSubmitted: (value) {
//futureAuthToken = connector.getAuthToken(configuration.loginInformation.mail, configuration.loginInformation.password);
},
const SizedBox(height: 15.0),
TextFormField(
autofocus: false,
initialValue: configuration.loginInformation.password,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Sensor Password',
hintText: 'Password for writing events',
),
onChanged: (value){
configuration.loginInformation.password = value;
},
onFieldSubmitted: (value) {
//futureAuthToken = connector.getAuthToken(configuration.loginInformation.mail, configuration.loginInformation.password);
},
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
if(configuration.currentCollection.id == -1){
configuration.currentCollection = configuration.collections[0];
futureDevices = connector.fetchCollectionDevices(configuration.currentCollection.id);
}
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);
}
);
}
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),
],
),
),
),
bottomNavigationBar: Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
//const SizedBox(width: 10.0),
FloatingActionButton.extended(
heroTag: null,
tooltip: 'Export events to local .json file',
icon: const Icon(Icons.download),
label: const Text('Dump Events'),
//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,
label: const Text('Store'),
//TODO: display failed as user feedback somehow
},
),
const SizedBox(width: 5.0),
//TODO: write configuration on app dispose!
//TODO: grey out update button if nothing has changed. ?