server things

This commit is contained in:
nico
2024-05-15 19:59:10 +02:00
parent 3528e2ee6c
commit 1656ffb00c
7 changed files with 200 additions and 145 deletions

View File

@@ -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,22 +234,38 @@ class _AddCamMainState extends State<AddCamMain> {
}
Future<dynamic> _showServerErrorDialog() {
bool isLoading = false;
return showDialog(
context: context,
builder: (context) {
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 {
int errorCode = _httpRequest();
setState(() => isLoading = true);
int errorCode = await _httpRequest();
setState(() => isLoading = false);
if (errorCode != 201) {
Navigator.pop(context);
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);
@@ -258,75 +273,75 @@ class _AddCamMainState extends State<AddCamMain> {
child: Text(AppLocalizations.of(context)!.cancel))
],
);
},
);
});
}
Future<void> showSaveOptionsDialog() async {
return showDialog(
context: context,
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();
bool isLoading = false;
if (errorCode != 201) {
saveData();
_showServerErrorDialog();
} else {
saveData();
return showDialog(
context: context,
builder: (context) {
barrierDismissible:
false, // Verhindert das Schließen des Dialogs durch den Benutzer
builder: (BuildContext context) {
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
title: Text(
AppLocalizations.of(context)!.successful),
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: () {
Navigator.pop(context);
},
child: Text(
AppLocalizations.of(context)!.back)),
TextButton(
onPressed: () {
onPressed: () async {
setState(() => isLoading = true);
saveTemplate();
Navigator.pushNamedAndRemoveUntil(
context, '/home', (route) => false);
},
child: Text(AppLocalizations.of(context)!
.continueB))
],
);
});
}
},
child: Text(AppLocalizations.of(context)!.sendtoserver)),
child: Text(AppLocalizations.of(context)!.template)),
if (!isLoading)
TextButton(
onPressed: () async {
setState(() => isLoading = true);
int errorCode = await _httpRequest();
setState(() => isLoading = false);
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);
context, '/home', (route) => false);
},
child: Text(AppLocalizations.of(context)!.justsave)),
if (!isLoading)
TextButton(
onPressed: () {
Navigator.pop(context);
@@ -334,15 +349,40 @@ class _AddCamMainState extends State<AddCamMain> {
child: Text(AppLocalizations.of(context)!.cancel)),
],
);
},
);
});
}
int _httpRequest() {
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)!.back)), */
TextButton(
onPressed: () {
Navigator.pushNamedAndRemoveUntil(
context, '/home', (route) => false);
},
child: Text(AppLocalizations.of(context)!.continueB))
],
);
});
}
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;
}
@@ -368,7 +408,8 @@ class _AddCamMainState extends State<AddCamMain> {
if (mounted) {
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(AppLocalizations.of(context)!.savefilefailed))); }
content: Text(AppLocalizations.of(context)!.savefilefailed)));
}
return;
}
if (mounted) {
@@ -377,10 +418,7 @@ class _AddCamMainState extends State<AddCamMain> {
}
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);
@@ -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) {

View File

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

View File

@@ -97,5 +97,6 @@
"servererrortitle": "Serverfehler",
"sendagain": "Nochmal senden",
"successful": "Erfolgreich",
"back": "Zurück"
"back": "Zurück",
"loading": "Lädt"
}

View File

@@ -472,6 +472,11 @@
"back": "Back",
"@back": {
"description": "back alert dialog option"
},
"loading": "Loading",
"@loading": {
"description": "just Loading"
}
}

View File

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

View File

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

View File

@@ -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(
@@ -205,6 +209,7 @@ class _ViewCamsState extends State<ViewCams> {
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 |