Fehlerkorrekturen und Erweiterungen

This commit is contained in:
Sven committed 2025-02-05 09:57:51 +01:00
1 parent 81133905de
commit 080c5b22ef
11 files changed
+176 -88

No files matched your search

+7 -7
View File
@@ -53,7 +53,7 @@ class _MessagesPageState extends State<MessagesPage> with ProducerMixin {
var status = await MyApp.isarInstance.sessionStatus.where().findFirst(); var status = await MyApp.isarInstance.sessionStatus.where().findFirst();
_sid = status != null ? status.sid : 'Unbekannt'; _sid = status != null ? status.sid : 'Unbekannt';
_sendMessagesReceivedMessage(); _sendMessagesReadMessage();
await _fetchMessages(); await _fetchMessages();
@@ -191,7 +191,7 @@ class _MessagesPageState extends State<MessagesPage> with ProducerMixin {
}); });
} }
void _sendMessagesReceivedMessage() async { void _sendMessagesReadMessage() async {
var unreadChatMessages = await MyApp.isarInstance.chatMessages var unreadChatMessages = await MyApp.isarInstance.chatMessages
.filter() .filter()
.readEqualTo(false) .readEqualTo(false)
@@ -203,13 +203,13 @@ class _MessagesPageState extends State<MessagesPage> with ProducerMixin {
chatMessageIds.add(message.id.toString()); chatMessageIds.add(message.id.toString());
} }
var chatMessagesReceived = ChatMessagesReceived(); var chatMessagesShowed = ChatMessagesReceived();
chatMessagesReceived.ids = chatMessageIds; chatMessagesShowed.ids = chatMessageIds;
chatMessagesReceived.time = DateTime.now().toUtc().toIso8601String(); chatMessagesShowed.time = DateTime.now().toUtc().toIso8601String();
sendMessage( sendMessage(
routingKey: Constants.messageTopicChatMessagesReceived, routingKey: Constants.messageTopicPublishPayload,
payload: chatMessagesReceived, payload: PublishPayloadMessage(topic: "mssg_received", message: chatMessagesShowed.toJson(), acknowledgeRequired: false),
); );
} }
} }
-3
View File
@@ -477,13 +477,10 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
message.task.pos = null; message.task.pos = null;
} }
// TODO MESSAGING
sendMessage( sendMessage(
routingKey: Constants.messageTopicPublishPayload, routingKey: Constants.messageTopicPublishPayload,
payload: PublishPayloadMessage(topic: "fin_task", message: message.toJson(), acknowledgeRequired: true), payload: PublishPayloadMessage(topic: "fin_task", message: message.toJson(), acknowledgeRequired: true),
); );
//await MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "fin_task", message: message.toJson(), qos: MqttQos.exactlyOnce));
} }
FinTourTask _createAnswerHeader(TaskInfo taskInfo) { FinTourTask _createAnswerHeader(TaskInfo taskInfo) {
+4 -2
View File
@@ -347,13 +347,15 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin, Produc
callback: (message) async { callback: (message) async {
var removeJobMessage = message.payload as RemoveJobMessage; var removeJobMessage = message.payload as RemoveJobMessage;
var job = await MyApp.isarInstance.jobs.where().filter().idEqualTo(removeJobMessage.id).findFirst();
await MyApp.isarInstance.writeTxn(() async { await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.jobs.where().filter().idEqualTo(removeJobMessage.id).deleteAll(); await MyApp.isarInstance.jobs.where().filter().idEqualTo(removeJobMessage.id).deleteAll();
}); });
sendMessage( sendMessage(
routingKey: Constants.messageTopicJobDeleted, routingKey: Constants.messageTopicJobDeleted,
payload: JobDeletedMessage(id: removeJobMessage.id), payload: JobDeletedMessage(job: job!),
); );
sendMessage( sendMessage(
@@ -377,7 +379,7 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin, Produc
queueId: Constants.messageTopicJobDeleted, queueId: Constants.messageTopicJobDeleted,
callback: (message) async { callback: (message) async {
var jobDeleted = message.payload as JobDeletedMessage; var jobDeleted = message.payload as JobDeletedMessage;
await _jobMap!.remove(jobDeleted.id); await _jobMap!.remove(jobDeleted.job.id);
}, },
); );
+105 -45
View File
@@ -8,7 +8,10 @@ import 'package:stadtbote/main.dart';
import 'package:stadtbote/protocoll_messages/accept_job_message.dart'; import 'package:stadtbote/protocoll_messages/accept_job_message.dart';
import 'package:stadtbote/model/job.dart'; import 'package:stadtbote/model/job.dart';
import 'package:stadtbote/protocoll_messages/fin_task_message.dart'; import 'package:stadtbote/protocoll_messages/fin_task_message.dart';
import 'package:stadtbote/tools/ExtendedStatefulBuilder.dart';
import 'package:stadtbote/tools/constants.dart'; import 'package:stadtbote/tools/constants.dart';
import 'package:stadtbote/tools/messages/job_deleted_message.dart';
import 'package:stadtbote/tools/messages/job_received_message.dart';
import 'package:stadtbote/tools/messages/refresh_badges_message.dart'; import 'package:stadtbote/tools/messages/refresh_badges_message.dart';
import 'package:stadtbote/tools/messages/remove_job_message.dart'; import 'package:stadtbote/tools/messages/remove_job_message.dart';
import 'package:stadtbote/tools/util.dart'; import 'package:stadtbote/tools/util.dart';
@@ -16,15 +19,98 @@ import 'package:badges/badges.dart' as badges;
import '../tools/messages/publish_payload_message.dart'; import '../tools/messages/publish_payload_message.dart';
late bool _initTimer;
late Timer _checkForNewJobsTimer;
late Map<int, bool> _infoExpandedMap; late Map<int, bool> _infoExpandedMap;
Future<void> showAcceptJobsPopup(SharedMapReference mapReference, Function() onFinished) async { Future<void> showAcceptJobsPopup(SharedMapReference mapReference, Function() onFinished) async {
_initTimer = true;
_infoExpandedMap = {}; _infoExpandedMap = {};
await showDialog<void>( ExtendendStatefulBuilder extendedStatefulBuilder;
return showDialog<void>(
barrierDismissible: true,
context: MyApp.appNavigatorKey.currentContext!,
builder: (BuildContext context) {
List<Widget> widgets = [];
StateSetter? extendedStatefulBuilderStateSetter;
extendedStatefulBuilder = ExtendendStatefulBuilder(builder: (BuildContext context, StateSetter setState) {
extendedStatefulBuilderStateSetter = setState;
return SizedBox(
key: GlobalKey(),
height: 400,
width: MediaQuery.of(context).size.width * 1.2,
child: Container(
height: 400,
padding: const EdgeInsets.all(5),
child: FutureBuilder<List<Widget>>(
future: _fetchJobWidgets(setState, onFinished, mapReference),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Util.getWaitWidget(context);
} else {
return ListView(
children: snapshot.requireData,
);
}
},
),
));
});
extendedStatefulBuilder.subscribe(
queueId: Constants.messageTopicJobReceived,
callback: (message) {
var jobReceivedMessage = message.payload as JobReceivedMessage;
if (jobReceivedMessage.job.state == 0) {
extendedStatefulBuilderStateSetter!(() {});
}
},
);
extendedStatefulBuilder.subscribe(
queueId: Constants.messageTopicJobDeleted,
callback: (message) {
var jobDeletedMessage = message.payload as JobDeletedMessage;
if (jobDeletedMessage.job.state == 0) {
extendedStatefulBuilderStateSetter!(() {});
}
extendedStatefulBuilderStateSetter!(() {});
},
);
widgets.add(extendedStatefulBuilder);
widgets.add(getDefaultButton("Liste schliessen", () {
extendedStatefulBuilder.unsubscribe(queueId: Constants.messageTopicJobReceived);
extendedStatefulBuilder.unsubscribe(queueId: Constants.messageTopicJobDeleted);
Navigator.pop(context);
onFinished();
}));
return Material(
color: Colors.transparent,
child: Stack(
children: [
Align(
alignment: Alignment.bottomCenter,
child: Container(
padding: const EdgeInsets.all(5),
height: 480,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: widgets,
),
))
],
),
);
},
);
/*await showDialog<void>(
context: MyApp.appNavigatorKey.currentContext!, context: MyApp.appNavigatorKey.currentContext!,
builder: (BuildContext context) { builder: (BuildContext context) {
return WillPopScope( return WillPopScope(
@@ -50,7 +136,7 @@ Future<void> showAcceptJobsPopup(SharedMapReference mapReference, Function() onF
return SizedBox( return SizedBox(
key: GlobalKey(), key: GlobalKey(),
height: MediaQuery.of(context).size.height * 1, height: MediaQuery.of(context).size.height * 0.4,
width: MediaQuery.of(context).size.width * 1.2, width: MediaQuery.of(context).size.width * 1.2,
child: Container( child: Container(
height: 100, height: 100,
@@ -69,28 +155,28 @@ Future<void> showAcceptJobsPopup(SharedMapReference mapReference, Function() onF
), ),
)); ));
}))); })));
}); });*/
} }
void _startTimer(BuildContext context, SharedMapReference mapReference, StateSetter setState, Function() onFinished) { /*void _startTimer(BuildContext context, SharedMapReference mapReference, StateSetter setState, Function() onFinished) {
_checkForNewJobsTimer = Timer.periodic(const Duration(seconds: 5), (Timer t) async { _checkForNewJobsTimer = Timer.periodic(const Duration(seconds: 5), (Timer t) async {
var jobMap = SharedMap<int, Job>.fromSharedReference(mapReference); var jobMap = SharedMap<int, Job>.fromSharedReference(mapReference);
if (await jobMap.length() > 0) { if (await jobMap.length() > 0) {
setState(() { }); setState(() {});
} else { } else {
_stopTimer(); _stopTimer();
Navigator.of(MyApp.appNavigatorKey.currentContext!).pop(); Navigator.of(MyApp.appNavigatorKey.currentContext!).pop();
onFinished(); onFinished();
} }
}); });
} }*/
void _stopTimer() { /*void _stopTimer() {
_checkForNewJobsTimer.cancel(); _checkForNewJobsTimer.cancel();
} }*/
Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFinished, SharedMapReference mapReference) async { Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFinished, SharedMapReference mapReference) async {
List<Widget> widgets = []; List<Widget> widgets = [];
@@ -208,10 +294,6 @@ Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFini
Expanded( Expanded(
child: getDefaultButton(!job.global ? 'Ablehnen' : 'Ignorieren', () { child: getDefaultButton(!job.global ? 'Ablehnen' : 'Ignorieren', () {
dialogState(() { dialogState(() {
if (jobMap.length() == 1) {
_stopTimer();
}
_sendAnswer(mapReference, job, !job.global ? 2 : 3); _sendAnswer(mapReference, job, !job.global ? 2 : 3);
jobMap.remove(job.id); jobMap.remove(job.id);
@@ -222,12 +304,6 @@ Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFini
); );
setState(() {}); setState(() {});
if (jobMap.length() == 0) {
Navigator.of(context).pop();
onFinished();
}
}); });
}), }),
), ),
@@ -235,10 +311,6 @@ Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFini
Expanded( Expanded(
child: getDefaultButton('Annehmen', enabledTimerActive: false, () { child: getDefaultButton('Annehmen', enabledTimerActive: false, () {
dialogState(() { dialogState(() {
if (jobMap.length() == 1) {
_stopTimer();
}
_sendAnswer(mapReference, job, 1); _sendAnswer(mapReference, job, 1);
jobMap.remove(job.id); jobMap.remove(job.id);
@@ -249,12 +321,6 @@ Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFini
); );
setState(() {}); setState(() {});
if (jobMap.length() == 0) {
Navigator.of(context).pop();
onFinished();
}
}); });
}), }),
) )
@@ -286,19 +352,13 @@ _sendAnswer(SharedMapReference mapReference, Job job, int item) async {
message.track.pos!.long = currentPosition != null ? currentPosition.longitude : 0.0; message.track.pos!.long = currentPosition != null ? currentPosition.longitude : 0.0;
message.track.pos!.acc = currentPosition != null ? currentPosition.accuracy.toInt() : 0; message.track.pos!.acc = currentPosition != null ? currentPosition.accuracy.toInt() : 0;
// TODO MESSAGING
job.sendMessage( job.sendMessage(
routingKey: Constants.messageTopicPublishPayload, routingKey: Constants.messageTopicPublishPayload,
payload: PublishPayloadMessage(topic: "reaction", message: message.toJson(), acknowledgeRequired: true), payload: PublishPayloadMessage(topic: "reaction", message: message.toJson(), acknowledgeRequired: true),
); );
//await MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "reaction", message: message.toJson(), qos: MqttQos.exactlyOnce));
// TODO MESSAGING
job.sendMessage( job.sendMessage(
routingKey: Constants.messageTopicUpdateBadges, routingKey: Constants.messageTopicUpdateBadges,
payload: RefreshBadgesMessage(), payload: RefreshBadgesMessage(),
); );
//await MessageService().publish(Constants.messageTopicUpdateBadges, arguments: RefreshBadgesMessage());
} }
@@ -0,0 +1,15 @@
import 'package:json_annotation/json_annotation.dart';
part 'connection_lost_message.g.dart';
@JsonSerializable()
class ConnectionLostMessage {
@JsonKey(name: "connection_lost")
late bool connectionLost;
ConnectionLostMessage();
factory ConnectionLostMessage.fromJson(Map<String, dynamic> json) => _$ConnectionLostMessageFromJson(json);
Map<String, dynamic> toJson() => _$ConnectionLostMessageToJson(this);
}
@@ -0,0 +1,17 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'connection_lost_message.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ConnectionLostMessage _$ConnectionLostMessageFromJson(
Map<String, dynamic> json) =>
ConnectionLostMessage()..connectionLost = json['connection_lost'] as bool;
Map<String, dynamic> _$ConnectionLostMessageToJson(
ConnectionLostMessage instance) =>
<String, dynamic>{
'connection_lost': instance.connectionLost,
};
+6
View File
@@ -0,0 +1,6 @@
import 'package:dart_mq/dart_mq.dart';
import 'package:flutter/widgets.dart';
class ExtendendStatefulBuilder extends StatefulBuilder with ConsumerMixin {
ExtendendStatefulBuilder({super.key, required super.builder});
}
-1
View File
@@ -24,7 +24,6 @@ class Constants {
static const String messageTopicDisconnectClient = "disconnect_client"; static const String messageTopicDisconnectClient = "disconnect_client";
static const String messageTopicRequestConnectionStatus = "request_connection_status"; static const String messageTopicRequestConnectionStatus = "request_connection_status";
static const String messageTopicCurrentConnectionStatus = "current_connection_status"; static const String messageTopicCurrentConnectionStatus = "current_connection_status";
static const String messageTopicChatMessagesReceived = "mssg_received";
static const String messageShowPopup = "show_popup"; static const String messageShowPopup = "show_popup";
+4 -2
View File
@@ -1,6 +1,8 @@
import 'package:stadtbote/model/job.dart';
class JobDeletedMessage { class JobDeletedMessage {
final int id; final Job job;
JobDeletedMessage({required this.id}); JobDeletedMessage({required this.job});
} }
+17 -27
View File
@@ -19,6 +19,7 @@ import 'package:stadtbote/model/status.dart';
import 'package:stadtbote/protocoll_messages/acknowledge_job.dart'; import 'package:stadtbote/protocoll_messages/acknowledge_job.dart';
import 'package:stadtbote/protocoll_messages/bootstrap_request.dart'; import 'package:stadtbote/protocoll_messages/bootstrap_request.dart';
import 'package:stadtbote/protocoll_messages/bootstrap_response_payload.dart'; import 'package:stadtbote/protocoll_messages/bootstrap_response_payload.dart';
import 'package:stadtbote/protocoll_messages/connection_lost_message.dart';
import 'package:stadtbote/protocoll_messages/device_log_request.dart'; import 'package:stadtbote/protocoll_messages/device_log_request.dart';
import 'package:stadtbote/protocoll_messages/device_log_response.dart'; import 'package:stadtbote/protocoll_messages/device_log_response.dart';
import 'package:stadtbote/protocoll_messages/device_object.dart'; import 'package:stadtbote/protocoll_messages/device_object.dart';
@@ -88,14 +89,11 @@ class MqttCore with ProducerMixin, ConsumerMixin {
} }
_disconnectMqttClient() async { _disconnectMqttClient() async {
// TODO MESSAGING
sendMessage( sendMessage(
routingKey: Constants.messageTopicConnectionStatusChanged, routingKey: Constants.messageTopicConnectionStatusChanged,
payload: ConnectionStatus(status: ConnectionStatusEnum.notConnected), payload: ConnectionStatus(status: ConnectionStatusEnum.notConnected),
); );
//await MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
_disconnectInProgress = true; _disconnectInProgress = true;
_cancelReconnectTimer(); _cancelReconnectTimer();
@@ -134,6 +132,10 @@ class MqttCore with ProducerMixin, ConsumerMixin {
willProperties.messageExpiryInterval = 3600; willProperties.messageExpiryInterval = 3600;
willProperties.willDelayInterval = 0; willProperties.willDelayInterval = 0;
var connectionLostMessage = ConnectionLostMessage();
connectionLostMessage.connectionLost = true;
var connectionLostEncapsulatedMessage = _encapsulateMessage(const Uuid().v4(), false, connectionLostMessage.toJson());
_mqttClient!.connectionMessage = MqttConnectMessage() _mqttClient!.connectionMessage = MqttConnectMessage()
.withClientIdentifier(await Util.getAppUuid()) .withClientIdentifier(await Util.getAppUuid())
.authenticateAs("app", "apppwd") .authenticateAs("app", "apppwd")
@@ -142,7 +144,7 @@ class MqttCore with ProducerMixin, ConsumerMixin {
.withWillTopic("$_toServerTopic$_clientId/connection_lost") .withWillTopic("$_toServerTopic$_clientId/connection_lost")
.withWillQos(MqttQos.atMostOnce) .withWillQos(MqttQos.atMostOnce)
.keepAliveFor(60) .keepAliveFor(60)
.withWillPayload(MqttUtf8Encoding().toUtf8('{"connection_lost": true}')) .withWillPayload(MqttUtf8Encoding().toUtf8(connectionLostEncapsulatedMessage))
.will(); .will();
} }
@@ -159,13 +161,10 @@ class MqttCore with ProducerMixin, ConsumerMixin {
} else { } else {
Util.logInfo('Verbindung zum MQTT-Broker fehlgeschlagen!'); Util.logInfo('Verbindung zum MQTT-Broker fehlgeschlagen!');
// TODO MESSAGING
sendMessage( sendMessage(
routingKey: Constants.messageTopicConnectionStatusChanged, routingKey: Constants.messageTopicConnectionStatusChanged,
payload: ConnectionStatus(status: ConnectionStatusEnum.notConnected), payload: ConnectionStatus(status: ConnectionStatusEnum.notConnected),
); );
//await MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
} }
} catch (ex) { } catch (ex) {
Util.logInfo('Verbindung zum MQTT-Broker fehlgeschlagen!: $ex'); Util.logInfo('Verbindung zum MQTT-Broker fehlgeschlagen!: $ex');
@@ -400,32 +399,35 @@ class MqttCore with ProducerMixin, ConsumerMixin {
_acknowlegdeJob(newJob); _acknowlegdeJob(newJob);
// TODO MESSAGING
sendMessage( sendMessage(
routingKey: Constants.messageTopicJobReceived, routingKey: Constants.messageTopicJobReceived,
payload: JobReceivedMessage(job: newJob), payload: JobReceivedMessage(job: newJob),
); );
// await MessageService().publish<JobReceivedMessage>(Constants.messageTopicJobReceived, arguments: JobReceivedMessage(job: newJob));
} }
void _jobDeleteReceived(payloadData) async { void _jobDeleteReceived(payloadData) async {
var jobDelMessage = JobDelMessage.fromJson(payloadData); var jobDelMessage = JobDelMessage.fromJson(payloadData);
var job = await MyApp.isarInstance.jobs.where().filter().idEqualTo(jobDelMessage.id).findFirst();
await MyApp.isarInstance.writeTxn(() async { await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.jobs.where().filter().idEqualTo(jobDelMessage.id).deleteAll(); await MyApp.isarInstance.jobs.where().filter().idEqualTo(jobDelMessage.id).deleteAll();
}); });
sendMessage( if (job != null) {
routingKey: Constants.messageTopicJobDeleted, sendMessage(
payload: JobDeletedMessage(id: jobDelMessage.id), routingKey: Constants.messageTopicJobDeleted,
); payload: JobDeletedMessage(job: job!),
);
}
} }
void _syncRequestReceived(payloadData) async { void _syncRequestReceived(payloadData) async {
Util.logInfo('_syncRequestReceived'); Util.logInfo('_syncRequestReceived');
_sendSyncMessage(); await _sendEnqueuedMessages();
await _sendSyncMessage();
} }
void _messageMessageReceived(Map<String, dynamic> payloadData) async { void _messageMessageReceived(Map<String, dynamic> payloadData) async {
@@ -701,18 +703,6 @@ class MqttCore with ProducerMixin, ConsumerMixin {
); );
}, },
); );
/*MessageService().subscribe<RequestConnectionStatusMessage>(Constants.messageTopicRequestConnectionStatus, this,
(RequestConnectionStatusMessage requestConnectionStatusMessage) async {
bool connected = false;
if (_mqttClient != null && _mqttClient!.connectionStatus != null) {
if (_mqttClient!.connectionStatus!.state == MqttConnectionState.connected) {
connected = true;
}
}
await MessageService().publish<CurrentConnectionStatusMessage>(Constants.messageTopicCurrentConnectionStatus, arguments: CurrentConnectionStatusMessage(state: connected));
});*/
} }
String _encapsulateMessage(String messageId, bool requiresAck, Map<String, dynamic> message) { String _encapsulateMessage(String messageId, bool requiresAck, Map<String, dynamic> message) {
+1 -1
View File
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 327.0.0+327 version: 330.0.0+330
environment: environment:
sdk: '>=2.19.6 <3.0.0' sdk: '>=2.19.6 <3.0.0'