Fehlerkorrekturen

This commit is contained in:
Sven committed 2024-02-28 14:46:51 +01:00
1 parent faef9ac5d9
commit 125e6eb03e
16 files changed
+320 -33

No files matched your search

+1 -1
View File
@@ -88,7 +88,7 @@ class _AcceptedJobsPageState extends State<AcceptedJobsPage> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Text( Text(
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime)).toString(), DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime).toLocal()).toString(),
style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.transparent), style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.transparent),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
+1 -1
View File
@@ -121,7 +121,7 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> {
child: Column( child: Column(
children: [ children: [
Text( Text(
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime)).toString(), DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime).toLocal()).toString(),
textAlign: TextAlign.left, textAlign: TextAlign.left,
style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.white), style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.white),
), ),
+1 -1
View File
@@ -88,7 +88,7 @@ class _FinishedJobsPageState extends State<FinishedJobsPage> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Text( Text(
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime)).toString(), DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime).toLocal()).toString(),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
Text( Text(
+44 -6
View File
@@ -230,7 +230,7 @@ class _MainPageState extends State<MainPage> {
getDefaultButton( getDefaultButton(
_loggedOut ? 'Anmelden' : 'Abmelden', _loggedOut ? 'Anmelden' : 'Abmelden',
image: Image.asset(_loggedOut ? 'assets/anmelden.png' : 'assets/abmelden.png', width: 30, height: 30), image: Image.asset(_loggedOut ? 'assets/anmelden.png' : 'assets/abmelden.png', width: 30, height: 30),
() async => {_logout()}), () async => {_logout(context)}),
Expanded( Expanded(
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -305,20 +305,58 @@ class _MainPageState extends State<MainPage> {
} }
} }
_logout() { _logout(context) {
if (!_loggedOut) { if (!_loggedOut) {
showLogoutAlertDialog(context);
} else {
MqttCore.setup();
_loggedOut = false;
setState(() {});
}
}
showLogoutAlertDialog(BuildContext context) {
Widget yesButton = TextButton(
child: const Text("Ja"),
onPressed: () {
Navigator.of(context).pop();
_sendLogoutMessage(); _sendLogoutMessage();
Future.delayed(const Duration(seconds: 1), () async { Future.delayed(const Duration(seconds: 1), () async {
MqttCore.instance.diconnect(); MqttCore.instance.diconnect();
}); });
} else {
MqttCore.setup();
}
_loggedOut = !_loggedOut; _loggedOut = true;
setState(() {}); setState(() {});
},
);
Widget noButton = TextButton(
child: const Text("Nein"),
onPressed: () {
Navigator.of(context).pop();
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: const Text("Warnung"),
content: const Text("Wollen Sie sich wirklich abmelden?"),
actions: [
yesButton, noButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
} }
_sendLogoutMessage() { _sendLogoutMessage() {
+11 -9
View File
@@ -6,6 +6,7 @@ import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart'; import 'package:stadtbote/content_views/utils/header_info.dart';
import 'package:stadtbote/main.dart'; import 'package:stadtbote/main.dart';
import 'package:stadtbote/model/message.dart' as sbmessage; import 'package:stadtbote/model/message.dart' as sbmessage;
import 'package:stadtbote/model/message.dart';
import 'package:stadtbote/model/session_status.dart'; import 'package:stadtbote/model/session_status.dart';
import 'package:stadtbote/tools/mqtt_core.dart'; import 'package:stadtbote/tools/mqtt_core.dart';
@@ -93,16 +94,17 @@ class _MessagesPageState extends State<MessagesPage> {
void _handleSendPressed(types.PartialText text) async { void _handleSendPressed(types.PartialText text) async {
var now = DateTime.now(); var now = DateTime.now();
var message = sbmessage.Message(); var message = MessageMessage();
message.text = [text.text]; message.mssg = sbmessage.Message();
message.from = _sid; message.mssg.text = [text.text];
message.subj = ''; message.mssg.from = _sid;
message.time = now.toIso8601String(); message.mssg.subj = '';
message.read = true; message.mssg.time = now.toIso8601String();
message.id = await sbmessage.Message.getNextId(); message.mssg.read = true;
message.mssg.id = await sbmessage.Message.getNextId();
MyApp.isarInstance.writeTxnSync(() { MyApp.isarInstance.writeTxnSync(() {
MyApp.isarInstance.messages.putSync(message); MyApp.isarInstance.messages.putSync(message.mssg);
}); });
MqttCore.instance.publishPayloadMessage('mssg', message.toJson()); MqttCore.instance.publishPayloadMessage('mssg', message.toJson());
@@ -110,7 +112,7 @@ class _MessagesPageState extends State<MessagesPage> {
_messages.insert(0, types.TextMessage( _messages.insert(0, types.TextMessage(
author: _user, author: _user,
createdAt: now.millisecondsSinceEpoch, createdAt: now.millisecondsSinceEpoch,
id: message.id.toString(), id: message.mssg.id.toString(),
text: text.text, text: text.text,
)); ));
+99 -5
View File
@@ -1,4 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:ffi';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@@ -20,6 +21,7 @@ import 'package:stadtbote/popups/tasks_popups/take_photos_popup.dart';
import 'package:stadtbote/protocoll_messages/accept_job_message.dart'; import 'package:stadtbote/protocoll_messages/accept_job_message.dart';
import 'package:stadtbote/protocoll_messages/fin_task_message.dart'; import 'package:stadtbote/protocoll_messages/fin_task_message.dart';
import 'package:stadtbote/protocoll_messages/fin_tour_message.dart'; import 'package:stadtbote/protocoll_messages/fin_tour_message.dart';
import 'package:stadtbote/protocoll_messages/pic_message.dart';
import 'package:stadtbote/tools/constants.dart'; import 'package:stadtbote/tools/constants.dart';
import 'package:stadtbote/tools/message_service.dart'; import 'package:stadtbote/tools/message_service.dart';
import 'package:stadtbote/tools/mqtt_core.dart'; import 'package:stadtbote/tools/mqtt_core.dart';
@@ -64,6 +66,8 @@ class _TaskListPageState extends State<TaskListPage> {
late List<TaskInfo> _taskList; late List<TaskInfo> _taskList;
List<Uint8List> _photos = [];
@override @override
void initState() { void initState() {
Future.delayed(const Duration(seconds: 0), () async { Future.delayed(const Duration(seconds: 0), () async {
@@ -282,6 +286,7 @@ class _TaskListPageState extends State<TaskListPage> {
answer.codes!.add(barcode); answer.codes!.add(barcode);
} }
taskInfo.answer = jsonEncode(answer.toJson());
taskInfo.additionalText = "Barcodes gescannt"; taskInfo.additionalText = "Barcodes gescannt";
taskInfo.completed = true; taskInfo.completed = true;
@@ -292,13 +297,17 @@ class _TaskListPageState extends State<TaskListPage> {
} }
_processTakePhotos(TaskInfo taskInfo) { _processTakePhotos(TaskInfo taskInfo) {
showTakePhotosPopup(context, taskInfo, () { showTakePhotosPopup(context, taskInfo, (List<Uint8List>? photos) {
if (photos != null) {
_photos = photos;
taskInfo.additionalText = "Fotos aufgenommen"; taskInfo.additionalText = "Fotos aufgenommen";
taskInfo.completed = true; taskInfo.completed = true;
setState(() {}); setState(() {});
_finishTaskProcessing(taskInfo); _finishTaskProcessing(taskInfo);
}
}); });
} }
@@ -349,23 +358,29 @@ class _TaskListPageState extends State<TaskListPage> {
} }
void _processSignature(TaskInfo taskInfo) { void _processSignature(TaskInfo taskInfo) {
MyApp.suppressAcceptDialog = true;
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]); SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
Future.delayed(const Duration(seconds: 1), () async { Future.delayed(const Duration(seconds: 1), () async {
showSignaturePopup(context, taskInfo, () { showSignaturePopup(context, taskInfo, (String? signature) {
MyApp.suppressAcceptDialog = false;
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
if (signature != null) {
var answer = _createAnswerHeader(taskInfo); var answer = _createAnswerHeader(taskInfo);
answer.sign = 'A110'; answer.sign = signature;
taskInfo.answer = jsonEncode(answer.toJson()); taskInfo.answer = jsonEncode(answer.toJson());
taskInfo.completed = true; taskInfo.completed = true;
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
_sendFinTourMessage(); _sendFinTourMessage();
_finishTaskProcessing(taskInfo); _finishTaskProcessing(taskInfo);
MessageService().publish<PopContentViewMessage>(Constants.messageTopicPopContentView, arguments: PopContentViewMessage(count: 2)); MessageService().publish<PopContentViewMessage>(Constants.messageTopicPopContentView, arguments: PopContentViewMessage(count: 2));
}
}); });
}); });
} }
@@ -457,5 +472,84 @@ class _TaskListPageState extends State<TaskListPage> {
await MyApp.isarInstance.writeTxn(() async { await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.jobs.put(widget.job); await MyApp.isarInstance.jobs.put(widget.job);
}); });
_sendImages();
}
_sendImages() {
Future.delayed(const Duration(seconds: 1), () {
if (_photos.isNotEmpty) {
int photoIndex = 0;
for (var photoData in _photos) {
var message = PicMessage();
message.pic = PicData();
message.pic.trId = widget.tour.id;
message.pic.num = photoIndex;
message.pic.time = DateTime.now().millisecondsSinceEpoch;
message.pic.data = base64Encode(photoData);
var position = MyApp.currentPosition;
if (position != null) {
message.pos = PicMessagePos();
message.pos.lat = position.latitude;
message.pos.long = position.longitude;
}
MqttCore.instance.publishPayloadMessage("job", message.toJson());
} }
} }
});
}
/*private void SendImages()
{
var tourId = _jobTour.Id;
Task.Run(() =>
{
try
{
Thread.Sleep(1000);
var index = 0;
var realm = Realm.GetInstance();
var tourImages = realm.All<TourImage>().Where(tourImage => tourImage.TourId == tourId);
if (tourImages.Any())
{
foreach (var tourImage in tourImages)
{
var payloadObject = new JObject();
var picObject = new JObject();
payloadObject.Add(new JProperty("pic", picObject));
picObject.Add(new JProperty("tr_id", tourImage.TourId));
picObject.Add(new JProperty("num", index));
picObject.Add(new JProperty("time", DateTime.Now.ToString("o")));
picObject.Add(new JProperty("data", tourImage.ImageData));
var location = App.CurrentLocation;
if (location != null)
{
var posObject = new JObject();
picObject.Add(new JProperty("pos", posObject));
posObject.Add(new JProperty("lat", location.Latitude));
posObject.Add(new JProperty("long", location.Longitude));
}
App.Core.SendJsonMessageAsync("job", payloadObject);
index++;
}
Thread.Sleep(500);
}
}
catch (Exception ex)
{
}
});
}*/
}
+4
View File
@@ -60,6 +60,8 @@ class MyApp extends StatelessWidget {
static Position? currentPosition; static Position? currentPosition;
static bool suppressAcceptDialog = false;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
@@ -417,8 +419,10 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin {
} }
void _jobReceived(Job job) async { void _jobReceived(Job job) async {
if (!MyApp.suppressAcceptDialog) {
if (job.state == 0) { if (job.state == 0) {
await showAcceptJobsPopup(context, await MyApp.isarInstance.jobs.filter().stateEqualTo(0).findAll()); await showAcceptJobsPopup(context, await MyApp.isarInstance.jobs.filter().stateEqualTo(0).findAll());
} }
} }
} }
}
+11
View File
@@ -5,6 +5,17 @@ import 'package:stadtbote/tools/util.dart';
part 'message.g.dart'; part 'message.g.dart';
@JsonSerializable()
class MessageMessage {
late Message mssg;
MessageMessage();
factory MessageMessage.fromJson(Map<String, dynamic> json) => _$MessageMessageFromJson(json);
Map<String, dynamic> toJson() => _$MessageMessageToJson(this);
}
@collection @collection
@JsonSerializable() @JsonSerializable()
class Message { class Message {
+9
View File
@@ -1098,6 +1098,15 @@ extension MessageQueryProperty
// JsonSerializableGenerator // JsonSerializableGenerator
// ************************************************************************** // **************************************************************************
MessageMessage _$MessageMessageFromJson(Map<String, dynamic> json) =>
MessageMessage()
..mssg = Message.fromJson(json['mssg'] as Map<String, dynamic>);
Map<String, dynamic> _$MessageMessageToJson(MessageMessage instance) =>
<String, dynamic>{
'mssg': instance.mssg,
};
Message _$MessageFromJson(Map<String, dynamic> json) => Message() Message _$MessageFromJson(Map<String, dynamic> json) => Message()
..id = json['id'] as int ..id = json['id'] as int
..time = json['time'] as String ..time = json['time'] as String
+1 -1
View File
@@ -78,7 +78,7 @@ Future<void> showAcceptJobsPopup(BuildContext context, List<Job> jobs) async {
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: Text( child: Text(
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime)).toString(), DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime).toLocal()).toString(),
textAlign: TextAlign.left, textAlign: TextAlign.left,
style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.transparent), style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.transparent),
), ),
@@ -40,10 +40,15 @@ showReceiptGiverPopup(BuildContext context, TaskInfo taskInfo, Function(String)
controller: textEditingController, controller: textEditingController,
autofocus: true), autofocus: true),
const SizedBox(height: 20), const SizedBox(height: 20),
getDefaultButton('Übernehmen', () => { getDefaultButton('Übernehmen', () {
Navigator.of(context).pop(), if (textEditingController.text.isNotEmpty) {
Navigator.of(context).pop();
onFinished(textEditingController.text)}) onFinished(textEditingController.text);
} else {
showAlertDialog(context, "Fehler", "Sie müssen einen Text eingeben");
}
})
], ],
), ),
), ),
+33 -4
View File
@@ -1,13 +1,22 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:signature/signature.dart'; import 'package:signature/signature.dart';
import 'package:stadtbote/main.dart';
import 'package:stadtbote/model/task_info.dart'; import 'package:stadtbote/model/task_info.dart';
import 'package:stadtbote/tools/util.dart'; import 'package:stadtbote/tools/util.dart';
showSignaturePopup(BuildContext context, TaskInfo taskInfo, Function() onFinished) async { showSignaturePopup(BuildContext context, TaskInfo taskInfo, Function(String?) onFinished) async {
await showDialog( await showDialog(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return WillPopScope(
onWillPop: () async {
Navigator.of(context).pop();
onFinished(null);
return true;
},// False will prevent and true will allow to dismiss
child: AlertDialog(
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
shadowColor: Colors.transparent, shadowColor: Colors.transparent,
backgroundColor: Colors.white, backgroundColor: Colors.white,
@@ -18,6 +27,25 @@ showSignaturePopup(BuildContext context, TaskInfo taskInfo, Function() onFinishe
var popupHeight = MediaQuery.of(context).size.height * 0.85; var popupHeight = MediaQuery.of(context).size.height * 0.85;
var popupWidth = MediaQuery.of(context).size.width * 0.85; var popupWidth = MediaQuery.of(context).size.width * 0.85;
String convertPoints(List<Point> points) {
bool firstTap = true;
if (points.isNotEmpty) {
String result = "";
for (var point in points) {
if (point.type != PointType.tap) {
result += "${point.offset.dx.toInt()},${point.offset.dy.toInt()};";
} else {
result += "A";
}
}
return result.replaceAll("AA", "A");
}
return "";
}
return SizedBox( return SizedBox(
key: GlobalKey(), key: GlobalKey(),
height: popupHeight, height: popupHeight,
@@ -48,12 +76,13 @@ showSignaturePopup(BuildContext context, TaskInfo taskInfo, Function() onFinishe
getDefaultButton('Übernehmen', buttonHeight: 50, () => { getDefaultButton('Übernehmen', buttonHeight: 50, () => {
Navigator.of(context).pop(), Navigator.of(context).pop(),
onFinished()}) onFinished(convertPoints(controller.points))
})
], ],
), ),
), ),
)); ));
}, },
)); )));
}); });
} }
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:stadtbote/model/task_info.dart'; import 'package:stadtbote/model/task_info.dart';
import 'package:stadtbote/tools/util.dart'; import 'package:stadtbote/tools/util.dart';
Future<void> showTakePhotosPopup(BuildContext context, TaskInfo taskInfo, Function() onFinished) async { Future<void> showTakePhotosPopup(BuildContext context, TaskInfo taskInfo, Function(List<Uint8List>) onFinished) async {
List<Uint8List> imageDataList = []; List<Uint8List> imageDataList = [];
List<Widget> imageWidgetsList = []; List<Widget> imageWidgetsList = [];
@@ -90,7 +90,7 @@ Future<void> showTakePhotosPopup(BuildContext context, TaskInfo taskInfo, Functi
buttonHeight: 50, buttonHeight: 50,
() => { () => {
if (imageDataList.length == taskInfo.task.min! && imageDataList.length <= taskInfo.task.max!) if (imageDataList.length == taskInfo.task.min! && imageDataList.length <= taskInfo.task.max!)
{Navigator.of(context).pop(), onFinished()} {Navigator.of(context).pop(), onFinished(imageDataList)}
else else
{showAlertDialog(context, 'Fehler', 'Sie müssen mindestens ${taskInfo.task.min} Foto(s) aufnehmen')} {showAlertDialog(context, 'Fehler', 'Sie müssen mindestens ${taskInfo.task.min} Foto(s) aufnehmen')}
}) })
+50
View File
@@ -0,0 +1,50 @@
import 'package:json_annotation/json_annotation.dart';
part 'pic_message.g.dart';
@JsonSerializable()
class PicMessage {
late PicData pic;
late PicMessagePos pos;
PicMessage();
factory PicMessage.fromJson(Map<String, dynamic> json) => _$PicMessageFromJson(json);
Map<String, dynamic> toJson() => _$PicMessageToJson(this);
}
@JsonSerializable()
class PicData
{
@JsonKey(name: "tr_id")
late int trId;
late int num;
late int time;
late String data;
PicData();
factory PicData.fromJson(Map<String, dynamic> json) => _$PicDataFromJson(json);
Map<String, dynamic> toJson() => _$PicDataToJson(this);
}
@JsonSerializable()
class PicMessagePos {
late double lat;
late double long;
late int acc = 0;
PicMessagePos();
factory PicMessagePos.fromJson(Map<String, dynamic> json) => _$PicMessagePosFromJson(json);
Map<String, dynamic> toJson() => _$PicMessagePosToJson(this);
}
+43
View File
@@ -0,0 +1,43 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'pic_message.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
PicMessage _$PicMessageFromJson(Map<String, dynamic> json) => PicMessage()
..pic = PicData.fromJson(json['pic'] as Map<String, dynamic>)
..pos = PicMessagePos.fromJson(json['pos'] as Map<String, dynamic>);
Map<String, dynamic> _$PicMessageToJson(PicMessage instance) =>
<String, dynamic>{
'pic': instance.pic,
'pos': instance.pos,
};
PicData _$PicDataFromJson(Map<String, dynamic> json) => PicData()
..trId = json['tr_id'] as int
..num = json['num'] as int
..time = json['time'] as int
..data = json['data'] as String;
Map<String, dynamic> _$PicDataToJson(PicData instance) => <String, dynamic>{
'tr_id': instance.trId,
'num': instance.num,
'time': instance.time,
'data': instance.data,
};
PicMessagePos _$PicMessagePosFromJson(Map<String, dynamic> json) =>
PicMessagePos()
..lat = (json['lat'] as num).toDouble()
..long = (json['long'] as num).toDouble()
..acc = json['acc'] as int;
Map<String, dynamic> _$PicMessagePosToJson(PicMessagePos instance) =>
<String, dynamic>{
'lat': instance.lat,
'long': instance.long,
'acc': instance.acc,
};
+2
View File
@@ -198,7 +198,9 @@ class MqttCore {
break; break;
case 'job_del': case 'job_del':
if (!kDebugMode) {
_jobDeleteReceived(payloadData); _jobDeleteReceived(payloadData);
}
break; break;
case 'sync_request': case 'sync_request':