Fehlerkorrekturen und Erweiterungen
This commit is contained in:
1 parent
a16a8fcf28
commit
1207d9c517
12 files changed
+137
-39
No files matched your search
@@ -257,6 +257,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
|||||||
_processTaskArrivedOrFinished(TaskInfo taskInfo) {
|
_processTaskArrivedOrFinished(TaskInfo taskInfo) {
|
||||||
Util.logInfo('Task ${taskInfo.task.sId} called');
|
Util.logInfo('Task ${taskInfo.task.sId} called');
|
||||||
|
|
||||||
|
if (!mounted) return;
|
||||||
showTaskArrivedPopup(context, taskInfo, () async {
|
showTaskArrivedPopup(context, taskInfo, () async {
|
||||||
DateFormat dateFormat = DateFormat("dd.MM.yyyy HH:mm");
|
DateFormat dateFormat = DateFormat("dd.MM.yyyy HH:mm");
|
||||||
|
|
||||||
@@ -268,7 +269,9 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
|||||||
|
|
||||||
_sendArrivedMessage(taskInfo);
|
_sendArrivedMessage(taskInfo);
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
_finishTaskProcessing(taskInfo);
|
_finishTaskProcessing(taskInfo);
|
||||||
});
|
});
|
||||||
@@ -277,6 +280,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
|||||||
_processCommissionNumber(TaskInfo taskInfo) {
|
_processCommissionNumber(TaskInfo taskInfo) {
|
||||||
Util.logInfo('Task ${taskInfo.task.sId} called');
|
Util.logInfo('Task ${taskInfo.task.sId} called');
|
||||||
|
|
||||||
|
if (!mounted) return;
|
||||||
showComissionNumberPopup(context, taskInfo, (comissionNumber) async {
|
showComissionNumberPopup(context, taskInfo, (comissionNumber) async {
|
||||||
var answer = await _createAnswerHeader(taskInfo);
|
var answer = await _createAnswerHeader(taskInfo);
|
||||||
answer.val = comissionNumber;
|
answer.val = comissionNumber;
|
||||||
@@ -287,7 +291,9 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
|||||||
|
|
||||||
_commisionNumber = comissionNumber;
|
_commisionNumber = comissionNumber;
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
_finishTaskProcessing(taskInfo);
|
_finishTaskProcessing(taskInfo);
|
||||||
});
|
});
|
||||||
@@ -316,6 +322,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
|||||||
_processTakePhotos(TaskInfo taskInfo) {
|
_processTakePhotos(TaskInfo taskInfo) {
|
||||||
Util.logInfo('Task ${taskInfo.task.sId} called');
|
Util.logInfo('Task ${taskInfo.task.sId} called');
|
||||||
|
|
||||||
|
if (!mounted) return;
|
||||||
showTakePhotosPopup(context, taskInfo, (List<Uint8List>? photos) async {
|
showTakePhotosPopup(context, taskInfo, (List<Uint8List>? photos) async {
|
||||||
if (photos != null) {
|
if (photos != null) {
|
||||||
await MyApp.isarInstance.writeTxn(() async {
|
await MyApp.isarInstance.writeTxn(() async {
|
||||||
@@ -335,7 +342,9 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
|||||||
taskInfo.additionalText = "Fotos aufgenommen";
|
taskInfo.additionalText = "Fotos aufgenommen";
|
||||||
taskInfo.completed = true;
|
taskInfo.completed = true;
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
_finishTaskProcessing(taskInfo);
|
_finishTaskProcessing(taskInfo);
|
||||||
}
|
}
|
||||||
@@ -362,6 +371,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
|||||||
void _processReceiptGiver(TaskInfo taskInfo) {
|
void _processReceiptGiver(TaskInfo taskInfo) {
|
||||||
Util.logInfo('Task ${taskInfo.task.sId} called');
|
Util.logInfo('Task ${taskInfo.task.sId} called');
|
||||||
|
|
||||||
|
if (!mounted) return;
|
||||||
showReceiptGiverPopup(context, taskInfo, (receiptGiver, selectedTourEntry) async {
|
showReceiptGiverPopup(context, taskInfo, (receiptGiver, selectedTourEntry) async {
|
||||||
var answer = await _createAnswerHeader(taskInfo);
|
var answer = await _createAnswerHeader(taskInfo);
|
||||||
answer.code = selectedTourEntry.code;
|
answer.code = selectedTourEntry.code;
|
||||||
@@ -371,7 +381,9 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
|||||||
taskInfo.additionalText = receiptGiver;
|
taskInfo.additionalText = receiptGiver;
|
||||||
taskInfo.completed = true;
|
taskInfo.completed = true;
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
_finishTaskProcessing(taskInfo);
|
_finishTaskProcessing(taskInfo);
|
||||||
});
|
});
|
||||||
@@ -380,8 +392,10 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
|||||||
void _processPickupDeliveryStatusTask(TaskInfo taskInfo) {
|
void _processPickupDeliveryStatusTask(TaskInfo taskInfo) {
|
||||||
Util.logInfo('Task ${taskInfo.task.sId} called');
|
Util.logInfo('Task ${taskInfo.task.sId} called');
|
||||||
|
|
||||||
|
final currentContext = context;
|
||||||
Future.delayed(const Duration(seconds: 1), () async {
|
Future.delayed(const Duration(seconds: 1), () async {
|
||||||
showPickupDeliveryStatusPopup(context, taskInfo, (tourEntry, remark) async {
|
if (!mounted) return;
|
||||||
|
showPickupDeliveryStatusPopup(currentContext, taskInfo, (tourEntry, remark) async {
|
||||||
var answer = await _createAnswerHeader(taskInfo);
|
var answer = await _createAnswerHeader(taskInfo);
|
||||||
answer.code = tourEntry!.code;
|
answer.code = tourEntry!.code;
|
||||||
answer.val = remark;
|
answer.val = remark;
|
||||||
@@ -392,7 +406,9 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
|||||||
|
|
||||||
_finishTaskProcessing(taskInfo);
|
_finishTaskProcessing(taskInfo);
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -404,8 +420,10 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
|||||||
|
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
|
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
|
||||||
|
|
||||||
|
final currentContext = context;
|
||||||
Future.delayed(const Duration(seconds: 1), () async {
|
Future.delayed(const Duration(seconds: 1), () async {
|
||||||
showSignaturePopup(context, taskInfo, (String? signature) async {
|
if (!mounted) return;
|
||||||
|
showSignaturePopup(currentContext, taskInfo, (String? signature) async {
|
||||||
MyApp.suppressAcceptDialog = false;
|
MyApp.suppressAcceptDialog = false;
|
||||||
|
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||||
|
|||||||
+19
-4
@@ -211,7 +211,7 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin, Produc
|
|||||||
|
|
||||||
final ValueNotifier<bool> _connectionLostValueNotifier = ValueNotifier<bool>(true);
|
final ValueNotifier<bool> _connectionLostValueNotifier = ValueNotifier<bool>(true);
|
||||||
|
|
||||||
late AnimationController? _animationController = null;
|
late AnimationController? _animationController;
|
||||||
late Animation<double> _animation;
|
late Animation<double> _animation;
|
||||||
|
|
||||||
Timer? _checkForNewState0JobsJobsTimer;
|
Timer? _checkForNewState0JobsJobsTimer;
|
||||||
@@ -426,20 +426,28 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin, Produc
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _replaceContentView(ContentViewWidget widget) async {
|
void _replaceContentView(ContentViewWidget widget) async {
|
||||||
|
final currentContext = context;
|
||||||
Future.delayed(const Duration(seconds: 0), () async {
|
Future.delayed(const Duration(seconds: 0), () async {
|
||||||
contentStack.clear();
|
contentStack.clear();
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_currentContent = widget;
|
_currentContent = widget;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_currentTitleWidget = await _currentContent.getHeaderWidget(context);
|
if (mounted) {
|
||||||
|
_currentTitleWidget = await _currentContent.getHeaderWidget(currentContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _popContentView(int count) {
|
void _popContentView(int count) {
|
||||||
|
final currentContext = context;
|
||||||
Future.delayed(const Duration(seconds: 0), () async {
|
Future.delayed(const Duration(seconds: 0), () async {
|
||||||
for (int i = 0; i < count - 1; i++) {
|
for (int i = 0; i < count - 1; i++) {
|
||||||
contentStack.pop();
|
contentStack.pop();
|
||||||
@@ -449,19 +457,26 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin, Produc
|
|||||||
|
|
||||||
_currentContent = previousContentView;
|
_currentContent = previousContentView;
|
||||||
|
|
||||||
_currentTitleWidget = await _currentContent.getHeaderWidget(context);
|
if (mounted) {
|
||||||
|
_currentTitleWidget = await _currentContent.getHeaderWidget(currentContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _pushContentView(ContentViewWidget widget) {
|
void _pushContentView(ContentViewWidget widget) {
|
||||||
|
final currentContext = context;
|
||||||
Future.delayed(const Duration(seconds: 0), () async {
|
Future.delayed(const Duration(seconds: 0), () async {
|
||||||
contentStack.push(_currentContent);
|
contentStack.push(_currentContent);
|
||||||
|
|
||||||
_currentContent = widget;
|
_currentContent = widget;
|
||||||
|
|
||||||
_currentTitleWidget = await _currentContent.getHeaderWidget(context);
|
if (mounted) {
|
||||||
|
_currentTitleWidget = await _currentContent.getHeaderWidget(currentContext);
|
||||||
|
}
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|||||||
@@ -198,9 +198,7 @@ Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFini
|
|||||||
payload: RemoveJobMessage(id: job.id),
|
payload: RemoveJobMessage(id: job.id),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (mounted) {
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
@@ -217,9 +215,7 @@ Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFini
|
|||||||
payload: RemoveJobMessage(id: job.id),
|
payload: RemoveJobMessage(id: job.id),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (mounted) {
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,10 +6,16 @@ showTaskArrivedPopup(BuildContext context, TaskInfo taskInfo, Function() onFinis
|
|||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return WillPopScope(
|
return PopScope(
|
||||||
onWillPop: () async {
|
canPop: false,
|
||||||
return await taskDialogSecurityException(context);
|
onPopInvoked: (bool didPop) async {
|
||||||
}, // False will prevent and true will allow to dismiss
|
if (!didPop) {
|
||||||
|
final shouldPop = await taskDialogSecurityException(context);
|
||||||
|
if (shouldPop && context.mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
shadowColor: Colors.transparent,
|
shadowColor: Colors.transparent,
|
||||||
|
|||||||
@@ -7,9 +7,15 @@ showComissionNumberPopup(BuildContext context, TaskInfo taskInfo, Function(Strin
|
|||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return WillPopScope(
|
return PopScope(
|
||||||
onWillPop: () async {
|
canPop: false,
|
||||||
return await taskDialogSecurityException(context);
|
onPopInvoked: (bool didPop) async {
|
||||||
|
if (!didPop) {
|
||||||
|
final shouldPop = await taskDialogSecurityException(context);
|
||||||
|
if (shouldPop && context.mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
|
|||||||
@@ -18,9 +18,15 @@ showPickupDeliveryStatusPopup(BuildContext context, TaskInfo taskInfo, Function(
|
|||||||
TextEditingController controller = TextEditingController();
|
TextEditingController controller = TextEditingController();
|
||||||
TextEditingController remController = TextEditingController();
|
TextEditingController remController = TextEditingController();
|
||||||
|
|
||||||
return WillPopScope(
|
return PopScope(
|
||||||
onWillPop: () async {
|
canPop: false,
|
||||||
return await taskDialogSecurityException(context);
|
onPopInvoked: (bool didPop) async {
|
||||||
|
if (!didPop) {
|
||||||
|
final shouldPop = await taskDialogSecurityException(context);
|
||||||
|
if (shouldPop && context.mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
|
|||||||
@@ -17,9 +17,15 @@ showReceiptGiverPopup(BuildContext context, TaskInfo taskInfo, Function(String,
|
|||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return WillPopScope(
|
return PopScope(
|
||||||
onWillPop: () async {
|
canPop: false,
|
||||||
return await taskDialogSecurityException(context);
|
onPopInvoked: (bool didPop) async {
|
||||||
|
if (!didPop) {
|
||||||
|
final shouldPop = await taskDialogSecurityException(context);
|
||||||
|
if (shouldPop && context.mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
|
|||||||
@@ -8,15 +8,18 @@ showSignaturePopup(BuildContext context, TaskInfo taskInfo, Function(String?) on
|
|||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return WillPopScope(
|
return PopScope(
|
||||||
onWillPop: () async {
|
canPop: false,
|
||||||
var result = await taskDialogSecurityException(context);
|
onPopInvoked: (bool didPop) async {
|
||||||
|
if (!didPop) {
|
||||||
if (result) {
|
final shouldPop = await taskDialogSecurityException(context);
|
||||||
|
if (shouldPop) {
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||||
|
if (context.mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
},
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
|
|||||||
@@ -7,9 +7,15 @@ showStationNoticePopup(BuildContext context, TaskInfo taskInfo, Function(String)
|
|||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return WillPopScope(
|
return PopScope(
|
||||||
onWillPop: () async {
|
canPop: false,
|
||||||
return await taskDialogSecurityException(context);
|
onPopInvoked: (bool didPop) async {
|
||||||
|
if (!didPop) {
|
||||||
|
final shouldPop = await taskDialogSecurityException(context);
|
||||||
|
if (shouldPop && context.mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
|
|||||||
@@ -16,9 +16,15 @@ Future<void> showTakePhotosPopup(BuildContext context, TaskInfo taskInfo, Functi
|
|||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return WillPopScope(
|
return PopScope(
|
||||||
onWillPop: () async {
|
canPop: false,
|
||||||
return await taskDialogSecurityException(context);
|
onPopInvoked: (bool didPop) async {
|
||||||
|
if (!didPop) {
|
||||||
|
final shouldPop = await taskDialogSecurityException(context);
|
||||||
|
if (shouldPop && context.mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
|
|||||||
@@ -5,9 +5,15 @@ showZipPopup(BuildContext context, String text, String buttonText, Function(Stri
|
|||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return WillPopScope(
|
return PopScope(
|
||||||
onWillPop: () async {
|
canPop: false,
|
||||||
return await taskDialogSecurityException(context);
|
onPopInvoked: (bool didPop) async {
|
||||||
|
if (!didPop) {
|
||||||
|
final shouldPop = await taskDialogSecurityException(context);
|
||||||
|
if (shouldPop && context.mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:archive/archive.dart';
|
import 'package:archive/archive.dart';
|
||||||
@@ -274,6 +275,10 @@ class MqttCore with ProducerMixin, ConsumerMixin {
|
|||||||
_messageAcknowledgeReceived(jsonDecode(payloadString));
|
_messageAcknowledgeReceived(jsonDecode(payloadString));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "command/logout":
|
||||||
|
_commandLogoutReceived(jsonDecode(payloadString));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Util.logInfo('Unknown topic: $topic');
|
Util.logInfo('Unknown topic: $topic');
|
||||||
break;
|
break;
|
||||||
@@ -724,6 +729,25 @@ class MqttCore with ProducerMixin, ConsumerMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _commandLogoutReceived(Map<String, dynamic> payload) {
|
||||||
|
try {
|
||||||
|
String timestamp = payload['timestamp'] ?? 'Unknown timestamp';
|
||||||
|
Util.logInfo('Command logout received with timestamp: $timestamp');
|
||||||
|
|
||||||
|
// Disconnect MQTT client gracefully
|
||||||
|
_disconnectMqttClient();
|
||||||
|
|
||||||
|
// Exit the application reliably
|
||||||
|
Future.delayed(const Duration(milliseconds: 500), () {
|
||||||
|
exit(0);
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
Util.logException('Error processing logout command: ${ex.toString()}');
|
||||||
|
// Force exit even if there's an error
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String _encapsulateMessage(String messageId, bool requiresAck, Map<String, dynamic> message) {
|
String _encapsulateMessage(String messageId, bool requiresAck, Map<String, dynamic> message) {
|
||||||
var messageHeader = MessageHeader();
|
var messageHeader = MessageHeader();
|
||||||
messageHeader.messageId = messageId;
|
messageHeader.messageId = messageId;
|
||||||
|
|||||||
Reference in new issue
Block a user