server things
This commit is contained in:
@@ -15,13 +15,15 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
class AddCamMain extends StatefulWidget {
|
||||
final bool isTemplate;
|
||||
final bool isFinished;
|
||||
final bool isSent;
|
||||
final Map<String, dynamic>? existingData;
|
||||
|
||||
const AddCamMain(
|
||||
{super.key,
|
||||
this.isTemplate = false,
|
||||
this.existingData,
|
||||
this.isFinished = false});
|
||||
this.isFinished = false,
|
||||
this.isSent = false});
|
||||
|
||||
@override
|
||||
State<AddCamMain> createState() => _AddCamMainState();
|
||||
@@ -121,9 +123,6 @@ class _AddCamMainState extends State<AddCamMain> {
|
||||
|
||||
// determine live position with checks for denied permission and turned off location service
|
||||
Future<Position> _deteterminePosition() async {
|
||||
|
||||
|
||||
|
||||
bool locationEnabled;
|
||||
LocationPermission permissionGiven;
|
||||
|
||||
@@ -182,10 +181,10 @@ class _AddCamMainState extends State<AddCamMain> {
|
||||
selectedPlatzung = widget.existingData!['Platzung'] ?? "";
|
||||
kSchloNrC.text = widget.existingData!['KSchloNr'] ?? "";
|
||||
datum = DateTime.parse(widget.existingData!['Datum']);
|
||||
kontDat = widget.existingData!['KontDat'] == null
|
||||
kontDat = widget.existingData!['KontDat'] == ""
|
||||
? null
|
||||
: DateTime.parse(widget.existingData!['KontDat']);
|
||||
abbauDat = widget.existingData!['AbbauDat'] == null
|
||||
abbauDat = widget.existingData!['AbbauDat'] == ""
|
||||
? null
|
||||
: DateTime.parse(widget.existingData!['AbbauDat']);
|
||||
auftragC.text = widget.existingData!['Auftrag'] ?? "";
|
||||
@@ -235,114 +234,155 @@ class _AddCamMainState extends State<AddCamMain> {
|
||||
}
|
||||
|
||||
Future<dynamic> _showServerErrorDialog() {
|
||||
bool isLoading = false;
|
||||
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(AppLocalizations.of(context)!.servererrortitle),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
int errorCode = _httpRequest();
|
||||
return StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return AlertDialog(
|
||||
title: Text(AppLocalizations.of(context)!.servererrortitle),
|
||||
content: isLoading
|
||||
? const SizedBox(
|
||||
height: 100,
|
||||
child: Center(child: CircularProgressIndicator()))
|
||||
: null,
|
||||
actions: [
|
||||
if (!isLoading)
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
setState(() => isLoading = true);
|
||||
int errorCode = await _httpRequest();
|
||||
setState(() => isLoading = false);
|
||||
|
||||
if (errorCode != 201) {
|
||||
Navigator.pop(context);
|
||||
_showServerErrorDialog();
|
||||
}
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.sendagain)),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.cancel))
|
||||
],
|
||||
if (errorCode != 201 && context.mounted) {
|
||||
_showServerErrorDialog();
|
||||
} else {
|
||||
if (context.mounted) Navigator.pop(context);
|
||||
saveData(true);
|
||||
_showSuccessDialog();
|
||||
}
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.sendagain)),
|
||||
if (!isLoading)
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.cancel))
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> showSaveOptionsDialog() async {
|
||||
bool isLoading = false;
|
||||
|
||||
return showDialog(
|
||||
context: context,
|
||||
barrierDismissible:
|
||||
false, // Verhindert das Schließen des Dialogs durch den Benutzer
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(AppLocalizations.of(context)!.savemethod),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
saveTemplate();
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context,
|
||||
'/home',
|
||||
(route) => false);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.template)),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
int errorCode = _httpRequest();
|
||||
return StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return AlertDialog(
|
||||
title: isLoading
|
||||
? Text(AppLocalizations.of(context)!.loading)
|
||||
: Text(AppLocalizations.of(context)!.savemethod),
|
||||
content: isLoading
|
||||
? const SizedBox(
|
||||
height: 100,
|
||||
child: Center(child: CircularProgressIndicator()))
|
||||
: null,
|
||||
actions: [
|
||||
if (!isLoading)
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
setState(() => isLoading = true);
|
||||
saveTemplate();
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context, '/home', (route) => false);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.template)),
|
||||
if (!isLoading)
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
setState(() => isLoading = true);
|
||||
int errorCode = await _httpRequest();
|
||||
setState(() => isLoading = false);
|
||||
|
||||
if (errorCode != 201) {
|
||||
saveData();
|
||||
_showServerErrorDialog();
|
||||
} else {
|
||||
saveData();
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.successful),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.back)),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context, '/home', (route) => false);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!
|
||||
.continueB))
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.sendtoserver)),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
saveData();
|
||||
saveFile();
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.saveasfile)),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
saveData();
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context,
|
||||
'/home',
|
||||
(route) => false);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.justsave)),
|
||||
TextButton(
|
||||
if (errorCode != 201 || !context.mounted) {
|
||||
saveData();
|
||||
_showServerErrorDialog();
|
||||
} else {
|
||||
saveData(true);
|
||||
_showSuccessDialog();
|
||||
}
|
||||
},
|
||||
child:
|
||||
Text(AppLocalizations.of(context)!.sendtoserver)),
|
||||
if (!isLoading)
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
setState(() => isLoading = true);
|
||||
saveData();
|
||||
saveFile();
|
||||
setState(() => isLoading = false);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.saveasfile)),
|
||||
if (!isLoading)
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
saveData();
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context, '/home', (route) => false);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.justsave)),
|
||||
if (!isLoading)
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.cancel)),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _showSuccessDialog() async {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(AppLocalizations.of(context)!.successful),
|
||||
actions: [
|
||||
/* TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.cancel)),
|
||||
child: Text(AppLocalizations.of(context)!.back)), */
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context, '/home', (route) => false);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.continueB))
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
int _httpRequest() {
|
||||
Future<int> _httpRequest() async {
|
||||
Map<String, dynamic> place = getPlace();
|
||||
|
||||
Methods method = Methods();
|
||||
HttpRequest method = HttpRequest();
|
||||
|
||||
method.httpRequest(jsonEncode(place));
|
||||
await method.httpRequest(jsonEncode(place));
|
||||
|
||||
return method.errorCode;
|
||||
}
|
||||
@@ -366,21 +406,19 @@ class _AddCamMainState extends State<AddCamMain> {
|
||||
await file.writeAsString(jsonPlace);
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
Navigator.pop(context);
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.savefilefailed))); }
|
||||
Navigator.pop(context);
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.savefilefailed)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Datei gespeichert in $selectedDirectory')));
|
||||
SnackBar(content: Text('Datei gespeichert in $selectedDirectory')));
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context,
|
||||
'/home',
|
||||
(route) => false);
|
||||
Navigator.pushNamedAndRemoveUntil(context, '/home', (route) => false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,12 +470,16 @@ class _AddCamMainState extends State<AddCamMain> {
|
||||
|
||||
// If the user has filled all needed values this function will be called to safe them in the database
|
||||
// * also creates a json string to send it to the server later
|
||||
void saveData() async {
|
||||
void saveData([bool sent = false]) async {
|
||||
var placeDB = DBHelper();
|
||||
|
||||
Map<String, dynamic> place = getPlace();
|
||||
|
||||
await placeDB.addPlace(place);
|
||||
// Get the ID of the newly added or updated place
|
||||
int newPlaceId = await placeDB.addPlace(place);
|
||||
|
||||
if (sent == true) {
|
||||
placeDB.updateSent(newPlaceId); // Update 'Sent' using the correct ID
|
||||
}
|
||||
|
||||
if (widget.isTemplate) {
|
||||
await placeDB.deleteTemplate(cid.text);
|
||||
@@ -721,7 +763,7 @@ class _AddCamMainState extends State<AddCamMain> {
|
||||
onDateChanged: (value) {
|
||||
abbauDat = value;
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
@@ -832,7 +874,9 @@ class _AddCamMainState extends State<AddCamMain> {
|
||||
List<String> emptyFields = validateData();
|
||||
// ! always filled out
|
||||
empty = false;
|
||||
if (empty == true) {
|
||||
if (widget.isSent) {
|
||||
Navigator.pushNamedAndRemoveUntil(context, '/home', (route) => false);
|
||||
} else if (empty == true) {
|
||||
showTemplateDialog(emptyFields);
|
||||
return;
|
||||
} else if (empty == false) {
|
||||
|
||||
@@ -18,7 +18,7 @@ class HomePage extends StatelessWidget {
|
||||
File file = File(result.files.single.path!);
|
||||
String content = await file.readAsString();
|
||||
|
||||
Methods().httpRequest(content);
|
||||
HttpRequest().httpRequest(content);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,5 +97,6 @@
|
||||
"servererrortitle": "Serverfehler",
|
||||
"sendagain": "Nochmal senden",
|
||||
"successful": "Erfolgreich",
|
||||
"back": "Zurück"
|
||||
"back": "Zurück",
|
||||
"loading": "Lädt"
|
||||
}
|
||||
@@ -472,6 +472,11 @@
|
||||
"back": "Back",
|
||||
"@back": {
|
||||
"description": "back alert dialog option"
|
||||
},
|
||||
|
||||
"loading": "Loading",
|
||||
"@loading": {
|
||||
"description": "just Loading"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,24 +5,23 @@ import 'package:dio/dio.dart';
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class Methods {
|
||||
class HttpRequest {
|
||||
int? _errorCode;
|
||||
|
||||
|
||||
int get errorCode => _errorCode ?? 0;
|
||||
|
||||
|
||||
Methods();
|
||||
|
||||
|
||||
|
||||
void httpRequest(String httpData) async {
|
||||
Future<void> httpRequest(String httpData) async {
|
||||
// print(jsonEncode(place));
|
||||
|
||||
final dio = Dio();
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
|
||||
dio.options.responseType = ResponseType.plain;
|
||||
dio.options
|
||||
..connectTimeout = const Duration(seconds: 5)
|
||||
..receiveTimeout = const Duration(seconds: 5)
|
||||
..responseType = ResponseType.plain;
|
||||
Response response = Response(requestOptions: RequestOptions(path: ''), statusCode: 400);
|
||||
|
||||
try {
|
||||
|
||||
@@ -35,50 +35,42 @@ class DBHelper {
|
||||
'CREATE TABLE templates (ID INTEGER PRIMARY KEY AUTOINCREMENT, CID TEXT, Standort TEXT, Rudel TEXT, Datum DATE, Adresse1 TEXT, Adresse2 TEXT, Adresse3 TEXT, BLand TEXT, Lkr TEXT, BeiOrt TEXT, OrtInfo TEXT, Status TEXT, FFTyp TEXT, FotoFilm TEXT, MEZ TEXT, Platzung TEXT, KSchloNr TEXT, KontDat DATE, Betreuung TEXT, AbbauDat DATE, Auftrag TEXT, KontAbsp TEXT, SonstBem TEXT, FKontakt1 TEXT, FKontakt2 TEXT, FKontakt3 TEXT, KTage1 INTEGER, KTage2 INTEGER, ProtoAm DATE, IntKomm TEXT, DECLNG DECIMALS(4,8), DECLAT DECIMALS(4,8))');
|
||||
}
|
||||
|
||||
// Function to add a finished entrie
|
||||
Future<void> addPlace(Map<String, dynamic> place) async {
|
||||
// Function to add a finished entry and return its ID
|
||||
Future<int> addPlace(Map<String, dynamic> place) async {
|
||||
var placeDBClient = await placeDB;
|
||||
|
||||
// gets an camid if it already exists
|
||||
final existingID = await placeDBClient.query(
|
||||
'place',
|
||||
where: 'ID = ?',
|
||||
whereArgs: [place['ID']],
|
||||
);
|
||||
|
||||
// checks if the camid var from before is empty to avoid double entries
|
||||
if (existingID.isNotEmpty) {
|
||||
updatePlace(place);
|
||||
return;
|
||||
return existingID.first['ID'] as int; // Return existing ID
|
||||
}
|
||||
|
||||
// inserts the entrie in the database
|
||||
await placeDBClient.insert(
|
||||
int id = await placeDBClient.insert(
|
||||
'place',
|
||||
place,
|
||||
|
||||
// replaces the entrie with the new onw if a unique value exists and conflicts
|
||||
// conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
//conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
);
|
||||
|
||||
return id; // Return the ID of the newly inserted entry
|
||||
}
|
||||
|
||||
Future<void> updatePlace(Map<String, dynamic> place) async {
|
||||
var placeDBClient = await placeDB;
|
||||
|
||||
await placeDBClient.update(
|
||||
'place',
|
||||
place,
|
||||
where: "ID = ?",
|
||||
whereArgs: [place['ID']]
|
||||
);
|
||||
await placeDBClient
|
||||
.update('place', place, where: "ID = ?", whereArgs: [place['ID']]);
|
||||
}
|
||||
|
||||
// function to update the sent value
|
||||
Future<void> updateSent() async {
|
||||
Future<void> updateSent(int id) async {
|
||||
var placeDBClient = await placeDB;
|
||||
|
||||
placeDBClient.update('place', true as Map<String, Object?>,
|
||||
where: 'ID = ?', whereArgs: ['ID']);
|
||||
await placeDBClient.update('place', {'Sent': 1},
|
||||
where: 'ID = ?', whereArgs: [id]);
|
||||
}
|
||||
|
||||
// same thing as before but with templatews
|
||||
|
||||
@@ -112,8 +112,12 @@ class _ViewCamsState extends State<ViewCams> {
|
||||
appBar: AppBar(
|
||||
bottom: TabBar(tabs: [
|
||||
Tab(text: AppLocalizations.of(context)!.completed),
|
||||
Tab(text: AppLocalizations.of(context)!.uncompleted,),
|
||||
Tab(text: AppLocalizations.of(context)!.map,),
|
||||
Tab(
|
||||
text: AppLocalizations.of(context)!.uncompleted,
|
||||
),
|
||||
Tab(
|
||||
text: AppLocalizations.of(context)!.map,
|
||||
),
|
||||
]),
|
||||
title: Text(AppLocalizations.of(context)!.viewplacesappbar)),
|
||||
body: TabBarView(
|
||||
@@ -201,13 +205,14 @@ class _ViewCamsState extends State<ViewCams> {
|
||||
onChanged: null,
|
||||
),
|
||||
onTap: () async {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => AddCamMain(
|
||||
isFinished: true,
|
||||
existingData: place,
|
||||
)));
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => AddCamMain(
|
||||
isSent: place['Sent'] == 1 ? true : false,
|
||||
isFinished: true,
|
||||
existingData: place,
|
||||
)));
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -277,17 +282,26 @@ class _ViewCamsState extends State<ViewCams> {
|
||||
return Marker(
|
||||
width: 80.0,
|
||||
height: 80.0,
|
||||
point: LatLng(double.parse(e['DECLAT'].toString()), double.parse(e['DECLNG'].toString())),
|
||||
point: LatLng(double.parse(e['DECLAT'].toString()),
|
||||
double.parse(e['DECLNG'].toString())),
|
||||
child: Column(
|
||||
children: [
|
||||
const Icon(Icons.location_on, color: Colors.red,),
|
||||
Text("ID: ${e['ID'].toString()}", style: const TextStyle(color: Colors.black),)
|
||||
const Icon(
|
||||
Icons.location_on,
|
||||
color: Colors.red,
|
||||
),
|
||||
Text(
|
||||
"ID: ${e['ID'].toString()}",
|
||||
style: const TextStyle(color: Colors.black),
|
||||
)
|
||||
],
|
||||
));
|
||||
}).toList();
|
||||
return FlutterMap(
|
||||
options: MapOptions(
|
||||
initialCenter: markers.isEmpty ? const LatLng(50, 10) : markers.first.point,
|
||||
initialCenter: markers.isEmpty
|
||||
? const LatLng(50, 10)
|
||||
: markers.first.point,
|
||||
interactionOptions: const InteractionOptions(
|
||||
flags: InteractiveFlag.pinchZoom |
|
||||
InteractiveFlag.drag |
|
||||
|
||||
Reference in New Issue
Block a user