Skip to content
Snippets Groups Projects
configuration.dart 9.25 KiB
Newer Older
Maximilian Betz's avatar
Maximilian Betz committed
import 'dart:convert';
import 'package:flutter/material.dart';
Maximilian Betz's avatar
Maximilian Betz committed
import 'package:flutter/services.dart';
import 'sensorconnector.dart';
import 'databaseconnector.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Configuration extends StatefulWidget {
Maximilian Betz's avatar
Maximilian Betz committed
  const Configuration({Key? key}) : super(key: key);

  @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;

  SensorConnector connector = SensorConnector();
  final ConfigurationStoreInstance configuration = ConfigurationStoreInstance();
  Future<void> updateConfiguration() async {
    final EventStoreInstance event = EventStoreInstance();

    futureAuthToken.then((value){ //NOTE: Counterintuitive async callback function
      debugPrint("Login credentials correct! Auth Token: " + value);

      futureDevices.then((value) {
        debugPrint("Device List complete");
        configuration.devices = value;

        futureEventTypes.then((value) async {
          debugPrint("Event Types List complete");
          configuration.eventTypes = value;

          debugPrint("EventType Json: " + jsonEncode(
              configuration.eventTypes[0]));
          debugPrint("Device Json: " + jsonEncode(
              configuration.devices[0]));
          debugPrint("Current Collection Json: " + jsonEncode(
              configuration.currentCollection));
          debugPrint("Sensor Login Json: " + jsonEncode(
              configuration.loginInformation));

          try {
            //Update id and urn for the add event widget with some initial data
            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"
          } catch (e) {
            throw Exception('Something went wrong try again');
          }

          final prefs = await SharedPreferences.getInstance();
          prefs.setString('configuration', jsonEncode(configuration.toMap()));
          prefs.setString('currentEvent', jsonEncode(event.toMap()));
          debugPrint('Configuration stored!');
        });
      });
    });
    //TODO: display failed as user feedback somehow
  }


    @override
  void initState() {
    super.initState();

    //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);
    }
    futureAuthToken = connector.getAuthToken(configuration.loginInformation.mail, configuration.loginInformation.password);
  late Future<String> eventTypes;

  @override
  Widget build(BuildContext context) {

    final ConfigurationStoreInstance configuration = ConfigurationStoreInstance();
    final EventStoreInstance events = EventStoreInstance();
Maximilian Betz's avatar
Maximilian Betz committed
        appBar: AppBar(
          title: const Text('Configuration'),
        ),
        body: Container(
          margin: const EdgeInsets.symmetric(horizontal: 5.0),
          child:
          Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                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(
                    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);
                  },
                ),
                TextFormField(
                  autofocus: false,
                  initialValue: configuration.loginInformation.password,
                  decoration: const InputDecoration(
                    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
Maximilian Betz's avatar
Maximilian Betz committed
                    collection if not initialized yet*/
Maximilian Betz's avatar
Maximilian Betz committed
                        if(configuration.currentCollection.id == -1){
                          configuration.currentCollection = configuration.collections[0];
                          futureDevices = connector.fetchCollectionDevices(configuration.currentCollection.id);
Maximilian Betz's avatar
Maximilian Betz committed

                        return DropdownButtonFormField(
                            value: configuration.currentCollection.collectionName,
                            decoration: const InputDecoration(
                              labelText: 'Chose Collection',
                            ),
                            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();
                      }
                    }
                ),
              ],
Maximilian Betz's avatar
Maximilian Betz committed
        ),
        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: 'Reset all data',
                icon: const Icon(Icons.cancel),
                label: const Text('Reset all'),
                onPressed: () {
                  //events.reset();  //TODO: remove before release!
                  var db = DatabaseInstance();
                  db.delete();

Maximilian Betz's avatar
Maximilian Betz committed
                  configuration.reset();  //TODO: remove before release this is not a real use case!
                },
              ),
              const SizedBox(width: 50),
              FloatingActionButton.extended(
                heroTag: null,
                tooltip: 'Select Collection and download corresponding devices',
                icon: const Icon(Icons.save),
                label: const Text('Store'),
                onPressed: () {
                  updateConfiguration();
Maximilian Betz's avatar
Maximilian Betz committed
                  //TODO: display failed as user feedback somehow
                },
              ),
              const SizedBox(width: 10.0),
            ],
Maximilian Betz's avatar
Maximilian Betz committed

//TODO: add scrowlable view here for landscape compatibility.
//TODO: write configuration on  app dispose!