Newer
Older
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'dart:async';
import 'package:geolocator/geolocator.dart';
const AddEvent({Key? key}) : super(key: key);
@override
State<AddEvent> createState() => _AddEventPageState();
}
class _AddEventPageState extends State<AddEvent> {
late String long = "";
late String lat = "";
late String alt = "";
late StreamSubscription<Position> streamHandler;
Future startGNSS() async {
debugPrint("Check Location Permission");
bool serviceStatus = false;
bool hasPermission = false;
serviceStatus = await Geolocator.isLocationServiceEnabled();
if(serviceStatus){
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
}else if(permission == LocationPermission.deniedForever){
debugPrint('Location permissions are permanently denied');
if(hasPermission){
debugPrint('Location permissions granted');
if(mounted){
setState(() {
//refresh the UI
});}
debugPrint('Starting location stream');
streamHandler = Geolocator.getPositionStream(
locationSettings: const LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 0,
)).listen((Position position) {
debugPrint('Get Location: Lat:' + position.latitude.toString() +
' Long:' + position.longitude.toString() +
' Alt:' + position.altitude.toString());
long = position.longitude.toString();
lat = position.latitude.toString();
alt = position.altitude.toString();
accuracy = position.accuracy;
if (syncGNSSData == true) {
if(mounted){
setState(() {
//refresh UI on update
});}
}
});
debugPrint("GPS Service is not enabled, turn on GPS location");
setState(() {
//refresh the UI
});}
@override
void dispose() {
try {
streamHandler.cancel();
debugPrint('Cancel location stream');
}catch(e){
debugPrint('Canceling location stream failed');
}
super.dispose();
}
final EventStoreInstance eventsStore = EventStoreInstance();
eventsStore.currentEvent.status = "PENDING";
eventsStore.events.add(
eventsStore.currentEvent.id,
eventsStore.currentEvent.urn,
eventsStore.currentEvent.label,
eventsStore.currentEvent.type,
eventsStore.currentEvent.description,
eventsStore.currentEvent.status,
eventsStore.currentEvent.startDate,
eventsStore.currentEvent.endDate,
eventsStore.currentEvent.latitude,
eventsStore.currentEvent.longitude,
eventsStore.currentEvent.elevation
//TODO: add field validators for freetext fields. Check allowed characters in sensor.awi.de
@override
Widget build(BuildContext context) {
/* Get singletons to access relevant data here.*/
final EventStoreInstance eventsStore = EventStoreInstance();
final ConfigurationStoreInstance configuration = ConfigurationStoreInstance();
// Update current event coordinates from GNSS stream
eventsStore.currentEvent.latitude = lat;
eventsStore.currentEvent.longitude = long;
eventsStore.currentEvent.elevation = alt;
var date = DateTime.now().toUtc();
eventsStore.currentEvent.startDate = '$date';
eventsStore.currentEvent.endDate = '$date';
if(accuracy == 0.0){
gnssStatusText = "No-Fix";
else{
gnssStatusText = "Precision: "+ accuracy.toStringAsFixed(2) +"m";
}
gnssStatusText = "GNSS Disabled"; // Just display existing event coordinates
if (configuration.initialized == true) {
return Scaffold(
appBar: AppBar(title: const Text("Add Event")),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
TextFormField(
initialValue: eventsStore.currentEvent.label,
autovalidateMode: AutovalidateMode.always,
decoration: const InputDecoration(
labelText: 'Label',
errorText: 'Only: a-z , A-Z , _ , 0-9 , ,(Comma) , ( , ) , + , - , . , :'
),
onChanged: (value) {
eventsStore.currentEvent.label = value;
},
validator: (value) {
if (!RegExp(r'^[a-z A-Z . \- 0-9 , ( ) + - _ :]+$').hasMatch(
value!)) {
return "Only: a-z , A-Z , _ , 0-9 , ,(Comma) , ( , ) , + , - , . , :";
} else {
//eventsStore.currentEvent.label = value;
return ""; // Entered Text is valid
}
},
),
DropdownButtonFormField(
value: eventsStore.currentEvent.type,
isExpanded: true,
decoration: const InputDecoration(
labelText: 'Event Type',
),
items:
configuration.eventTypes.map((EventType event) {
return DropdownMenuItem(
value: event.name,
child: Text(event.name),
);
}).toList(),
onChanged: (value) {
eventsStore.currentEvent.type = value.toString();
}
),
DropdownButtonFormField(
value: eventsStore.currentEvent.urn,
isExpanded: true,
decoration: const InputDecoration(
labelText: 'URN',
),
items:
configuration.devices.map((Device device) {
return DropdownMenuItem(
value: device.urn,
child: Text(device.urn),
);
}).toList(),
onChanged: (value) {
eventsStore.currentEvent.urn = value.toString();
eventsStore.currentEvent.id =
configuration.getDeviceIdFromUrn(value.toString());
}
),
TextFormField(
initialValue: eventsStore.currentEvent.description,
decoration: const InputDecoration(
labelText: 'Description'
),
onChanged: (value) {
eventsStore.currentEvent.description = value;
},
Row(
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
children: <Widget>[
Flexible(child:
TextFormField(
controller: TextEditingController(
text: eventsStore.currentEvent.startDate),
readOnly: true,
decoration: const InputDecoration(
labelText: 'Timestamp',
//helperText: '', //Adds some space below field
border: OutlineInputBorder(),
),
onTap: () {
DatePicker.showDateTimePicker(context,
showTitleActions: true,
onConfirm: (date) {
//Only one field for start and end date.
eventsStore.currentEvent.startDate = '$date';
eventsStore.currentEvent.endDate = '$date';
debugPrint('Date set to : $date');
setState(() {});
},
currentTime: DateTime.now().toUtc(),
locale: LocaleType.en);
},
),
),
ElevatedButton(
onPressed: () {
var date = DateTime.now().toUtc();
eventsStore.currentEvent.startDate = '$date';
eventsStore.currentEvent.endDate = '$date';
debugPrint('Date set to : ' +
eventsStore.currentEvent.endDate.toString());
setState(() {});
},
child: Text('Now'),
]
),
TextFormField(
readOnly: false,
enabled: !syncGNSSData,
controller: TextEditingController(
text: eventsStore.currentEvent.latitude.toString()),
decoration: const InputDecoration(
labelText: 'Latitude',
border: OutlineInputBorder(),
onChanged: (value) {
eventsStore.currentEvent.latitude = value;
}
),
TextFormField(
readOnly: false,
enabled: !syncGNSSData,
controller: TextEditingController(
text: eventsStore.currentEvent.longitude.toString()),
decoration: const InputDecoration(
labelText: 'Longitude',
border: OutlineInputBorder(),
onChanged: (value) {
eventsStore.currentEvent.longitude = value;
}
),
TextFormField(
readOnly: false,
enabled: !syncGNSSData,
controller: TextEditingController(
text: eventsStore.currentEvent.elevation.toString()),
decoration: const InputDecoration(
labelText: 'Elevation',
border: OutlineInputBorder(),
onChanged: (value) {
eventsStore.currentEvent.elevation = value;
}
),
]),
bottomNavigationBar: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(gnssStatusText),
const SizedBox(width: 10),
Switch(
value: syncGNSSData,
onChanged: (value) {
syncGNSSData = value;
debugPrint('Switched to:' + syncGNSSData.toString());
setState(() {
//refresh the UI
});
},
const SizedBox(width: 50),
FloatingActionButton(
heroTag: null,
onPressed: () {
_storeCurrentEvent();
HapticFeedback.vibrate();
},
tooltip: 'Add Event',
child: const Icon(Icons.check),
const SizedBox(width: 20),
],
),
);
}else {
return Scaffold(
appBar: AppBar(title: const Text("Add Event")),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: const <Widget>[
Text(
' Visit Configuration first.',
style: TextStyle(fontSize: 20)
),
],
),
);
}