Erweiterungen

This commit is contained in:
Sven committed 2024-07-29 10:46:55 +02:00
1 parent 41d086e13e
commit 7015d83fd1
20 files changed
+182 -158

No files matched your search

+2 -2
View File
@@ -142,7 +142,7 @@ class _AcceptedJobsPageState extends State<AcceptedJobsPage> {
return jobWidgets;
}
void _clicked(Job job) {
MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TourListPage(job: job));
void _clicked(Job job) async {
await MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TourListPage(job: job));
}
}
+2 -2
View File
@@ -197,7 +197,7 @@ class _ApproachAreaPageState extends State<ApproachAreaPage> {
return columns;
}
_sendZip(Rank rank, String zip) {
_sendZip(Rank rank, String zip) async {
var position = MyApp.currentPosition;
var setPosMessage = ZipSetPos();
@@ -212,7 +212,7 @@ class _ApproachAreaPageState extends State<ApproachAreaPage> {
setPosMessage.track!.pos!.acc = position.accuracy.toInt();
}
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "set_zip", message: setPosMessage.toJson(), qos: MqttQos.exactlyOnce));
await MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "set_zip", message: setPosMessage.toJson(), qos: MqttQos.exactlyOnce));
}
_initMessages() {
+2 -2
View File
@@ -200,13 +200,13 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> {
message.track.pos!.long = currentPosition != null ? currentPosition.longitude : 0.0;
message.track.pos!.acc = currentPosition != null ? currentPosition.accuracy.toInt() : 0;
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "reaction", message: message.toJson(), qos: MqttQos.exactlyOnce));
await MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "reaction", message: message.toJson(), qos: MqttQos.exactlyOnce));
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.jobs.delete(job.id);
});
MessageService().publish<RefreshBadgesMessage>(Constants.messageTopicUpdateBadges, arguments: RefreshBadgesMessage());
await MessageService().publish<RefreshBadgesMessage>(Constants.messageTopicUpdateBadges, arguments: RefreshBadgesMessage());
_entries = await _createListEntries();
+2 -2
View File
@@ -130,7 +130,7 @@ class _FinishedJobsPageState extends State<FinishedJobsPage> {
return jobWidgets;
}
void _clicked(Job job) {
MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TourListPage(job: job, readOnly: true,));
void _clicked(Job job) async {
await MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TourListPage(job: job, readOnly: true,));
}
}
+12 -13
View File
@@ -143,8 +143,8 @@ class _MainPageState extends State<MainPage> {
child: getDefaultButton(
'Zugewiesene Aufträge',
image: Image.asset('assets/zugewiesene_auftraege.png', width: 30, height: 30),
() => {
MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const AssignedJobsPage())
() async => {
await MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const AssignedJobsPage())
}),
);
},
@@ -176,9 +176,8 @@ class _MainPageState extends State<MainPage> {
child: getDefaultButton(
'Angenommene Aufträge',
image: Image.asset('assets/angenommene_auftraege.png', width: 30, height: 30),
() => {
MessageService()
.publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const AcceptedJobsPage())
() async => {
await MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const AcceptedJobsPage())
}));
},
),
@@ -189,7 +188,7 @@ class _MainPageState extends State<MainPage> {
child: getDefaultButton(
'Erledigte Aufträge',
image: Image.asset('assets/erledigte_auftraege.png', width: 30, height: 30),
() => {MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const FinishedJobsPage())}),
() async => {await MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const FinishedJobsPage())}),
),
SizedBox(height: _loggedOut == true ? 0 : 20),
Visibility(
@@ -217,8 +216,8 @@ class _MainPageState extends State<MainPage> {
child: getDefaultButton(
'Nachrichten',
image: Image.asset('assets/nachrichten.png', width: 30, height: 30),
() =>
{MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const MessagesPage())}));
() async =>
{await MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const MessagesPage())}));
},
),
),
@@ -228,7 +227,7 @@ class _MainPageState extends State<MainPage> {
child: getDefaultButton(
'Anfahrtsbereich',
image: Image.asset('assets/anfahrtsbereich.png', width: 30, height: 30),
() => {MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const ApproachAreaPage())}),
() async => {await MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const ApproachAreaPage())}),
),
SizedBox(height: _loggedOut == true ? 0 : 20),
getDefaultButton(
@@ -315,11 +314,11 @@ class _MainPageState extends State<MainPage> {
}
}
_logout(context) {
_logout(context) async {
if (!_loggedOut) {
showLogoutAlertDialog(context);
} else {
MessageService().publish<ConnectClientMessage>(Constants.messageTopicConnectClient, arguments: ConnectClientMessage());
await MessageService().publish<ConnectClientMessage>(Constants.messageTopicConnectClient, arguments: ConnectClientMessage());
_loggedOut = false;
@@ -372,7 +371,7 @@ class _MainPageState extends State<MainPage> {
);
}
_sendLogoutMessage() {
_sendLogoutMessage() async {
var position = MyApp.currentPosition;
var logoutMessage = LogoutMessage();
@@ -384,6 +383,6 @@ class _MainPageState extends State<MainPage> {
logoutMessage.pos!.acc = position.accuracy.toInt();
}
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "logout", message: logoutMessage.toJson(), qos: MqttQos.exactlyOnce));
await MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "logout", message: logoutMessage.toJson(), qos: MqttQos.exactlyOnce));
}
}
+1 -1
View File
@@ -110,7 +110,7 @@ class _MessagesPageState extends State<MessagesPage> {
await MyApp.isarInstance.messages.put(message);
});
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "message", message: message.toJson(), qos: MqttQos.exactlyOnce));
await MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "message", message: message.toJson(), qos: MqttQos.exactlyOnce));
_messages.insert(0, types.TextMessage(
author: _user,
+6 -6
View File
@@ -415,7 +415,7 @@ class _TaskListPageState extends State<TaskListPage> {
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
Future.delayed(const Duration(seconds: 1), () async {
showSignaturePopup(context, taskInfo, (String? signature) {
showSignaturePopup(context, taskInfo, (String? signature) async {
MyApp.suppressAcceptDialog = false;
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
@@ -432,7 +432,7 @@ class _TaskListPageState extends State<TaskListPage> {
_finishTaskProcessing(taskInfo);
MessageService().publish<PopContentViewMessage>(Constants.messageTopicPopContentView, arguments: PopContentViewMessage(count: 2));
await MessageService().publish<PopContentViewMessage>(Constants.messageTopicPopContentView, arguments: PopContentViewMessage(count: 2));
}
});
});
@@ -467,7 +467,7 @@ class _TaskListPageState extends State<TaskListPage> {
return false;
}
_sendArrivedMessage(TaskInfo taskInfo) {
_sendArrivedMessage(TaskInfo taskInfo) async {
var message = FinTask();
message.trId = widget.tour.id;
message.task = Task();
@@ -483,7 +483,7 @@ class _TaskListPageState extends State<TaskListPage> {
message.task.pos = null;
}
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "fin_task", message: message.toJson(), qos: MqttQos.exactlyOnce));
await MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "fin_task", message: message.toJson(), qos: MqttQos.exactlyOnce));
}
FinTourTask _createAnswerHeader(TaskInfo taskInfo) {
@@ -527,7 +527,7 @@ class _TaskListPageState extends State<TaskListPage> {
}
}
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "fin_tour", message: finTourMessage.toJson(), qos: MqttQos.exactlyOnce));
await MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "fin_tour", message: finTourMessage.toJson(), qos: MqttQos.exactlyOnce));
widget.tour.state = Constants.stateFinishedNotConfirmed;
@@ -552,7 +552,7 @@ class _TaskListPageState extends State<TaskListPage> {
message.time = DateTime.now().millisecondsSinceEpoch;
message.data = picture.data;
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "pic", message: message.toJson(), qos: MqttQos.exactlyOnce));
await MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "pic", message: message.toJson(), qos: MqttQos.exactlyOnce));
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.pictures.delete(picture.id);
+2 -2
View File
@@ -142,9 +142,9 @@ class _TourDetailsPageState extends State<TourDetailsPage> {
),
),
const SizedBox(height: 10),
getDefaultButton('Weiter', () =>
getDefaultButton('Weiter', () async =>
{
MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TaskListPage(job: widget.job, tour: widget.tour, readOnly: widget.readOnly))
await MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TaskListPage(job: widget.job, tour: widget.tour, readOnly: widget.readOnly))
}),
],
),
+2 -2
View File
@@ -208,7 +208,7 @@ class _TourListPageState extends State<TourListPage> {
return readOnly;
}
void _clicked(JobTour tour, bool readOnly) {
MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TourDetailsPage(job: widget.job, tour: tour, readOnly: readOnly));
Future<void> _clicked(JobTour tour, bool readOnly) async {
await MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TourDetailsPage(job: widget.job, tour: tour, readOnly: readOnly));
}
}
+45 -32
View File
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:isar/isar.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_map/shared_map.dart';
import 'package:stadtbote/messages/pop_content_view_message.dart';
import 'package:stadtbote/model/enqueued_message.dart';
import 'package:stadtbote/model/log_entry.dart';
@@ -17,6 +18,7 @@ import 'package:stadtbote/tools/colored_safe_area.dart';
import 'package:stadtbote/model/session_status.dart';
import 'package:stadtbote/tools/connection_status.dart';
import 'package:stadtbote/tools/message_service.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/mqtt_core.dart';
@@ -29,28 +31,28 @@ import 'tools/constants.dart';
import 'tools/util.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized();
final dir = await getApplicationDocumentsDirectory();
MyApp.isarInstance = await Isar.open([
SessionStatusSchema,
LocationStatusSchema,
JobSchema,
TaskInfoSchema,
MessageSchema,
EnqueuedMessageSchema,
LogEntrySchema,
RankingSchema,
PictureSchema
], directory: dir.path, name: "database_v1");
final dir = await getApplicationDocumentsDirectory();
MyApp.isarInstance = await Isar.open([
SessionStatusSchema,
LocationStatusSchema,
JobSchema,
TaskInfoSchema,
MessageSchema,
EnqueuedMessageSchema,
LogEntrySchema,
RankingSchema,
PictureSchema
], directory: dir.path, name: "database_v1");
await _clearLog();
await _clearLog();
runZonedGuarded(() {}, (error, stackTrace) {
runApp(MyApp());
}, (error, stackTrace) {
_traceUncaughtExceptions(error, stackTrace);
});
runApp(MyApp());
}
Future<void> _clearLog() async {
@@ -177,8 +179,12 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<double> _animation;
Timer? _checkForNewState0JobsJobsTimer;
bool _dialogOpened = false;
late SharedMap<int, Job>? _jobMap;
@override
void initState() {
super.initState();
@@ -188,8 +194,13 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin {
_animation = Tween<double>(begin: 0.5, end: 1.0).animate(_animationController);
WidgetsBinding.instance.addPostFrameCallback((_) async {
var store1 = SharedStore('jobs');
_jobMap = await store1.getSharedMap<int, Job>('m1');
_initMessages();
_startCheckForNewState0JobsJobsTimer();
_currentContent = MainPage();
var headerInfo = await _currentContent.getHeaderInfo(context);
@@ -366,8 +377,15 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin {
MessageService().subscribe<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, this, (ConnectionStatus connectionStatus) {
_connectionStatusChanged(connectionStatus);
});
MessageService().subscribe<JobReceivedMessage>(Constants.messageTopicJobReceived, this, (JobReceivedMessage jobReceivedMessage) {
_jobReceived(jobReceivedMessage.job);
MessageService().subscribe<JobReceivedMessage>(Constants.messageTopicJobReceived, this, (JobReceivedMessage jobReceivedMessage) async {
if (jobReceivedMessage.job.state == 0) {
await _jobMap!.put(jobReceivedMessage.job.id, jobReceivedMessage.job);
}
});
MessageService().subscribe<JobDeletedMessage>(Constants.messageTopicJobDeleted, this, (JobDeletedMessage jobDeletedMessage) async {
await _jobMap!.remove(jobDeletedMessage.id);
});
}
@@ -457,19 +475,14 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin {
_connectionLostValueNotifier.value = newConnectionStatus.status == ConnectionStatusEnum.notConnected;
}
void _jobReceived(Job job) async {
if (!MyApp.suppressAcceptDialog) {
if (job.state == 0) {
if (!_dialogOpened) {
_dialogOpened = true;
await showAcceptJobsPopup(context, await MyApp.isarInstance.jobs.filter().stateEqualTo(0).findAll(), () {
_dialogOpened = false;
MessageService().publish(Constants.messageTopicUpdateBadges, arguments: RefreshBadgesMessage());
});
}
void _startCheckForNewState0JobsJobsTimer() {
_checkForNewState0JobsJobsTimer ??= Timer.periodic(const Duration(seconds: 5), (Timer t) async {
if (await _jobMap!.length() > 0 && !_dialogOpened) {
_dialogOpened = true;
await showAcceptJobsPopup(context, _jobMap!.sharedReference(), () async {
_dialogOpened = false;
});
}
}
});
}
}
-6
View File
@@ -31,12 +31,6 @@ class Job {
@JsonKey(name: 'tours')
late List<JobTour> tours;
@Ignore()
late DateTime? firstDisplayTime = null;
@Ignore()
late int enableDelay;
Job();
factory Job.fromJson(Map<String, dynamic> json) => _$JobFromJson(json);
+1 -5
View File
@@ -1558,10 +1558,7 @@ Job _$JobFromJson(Map<String, dynamic> json) => Job()
..delayOrderTime = json['delayOrderTime'] as int
..tours = (json['tours'] as List<dynamic>)
.map((e) => JobTour.fromJson(e as Map<String, dynamic>))
.toList()
..firstDisplayTime = json['firstDisplayTime'] == null
? null
: DateTime.parse(json['firstDisplayTime'] as String);
.toList();
Map<String, dynamic> _$JobToJson(Job instance) => <String, dynamic>{
'id': instance.id,
@@ -1575,5 +1572,4 @@ Map<String, dynamic> _$JobToJson(Job instance) => <String, dynamic>{
'rem': instance.rem,
'delayOrderTime': instance.delayOrderTime,
'tours': instance.tours,
'firstDisplayTime': instance.firstDisplayTime?.toIso8601String(),
};
+51 -54
View File
@@ -1,31 +1,34 @@
import 'dart:async';
import 'dart:math';
import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:shared_map/shared_map.dart';
import 'package:stadtbote/main.dart';
import 'package:stadtbote/protocoll_messages/accept_job_message.dart';
import 'package:stadtbote/model/job.dart';
import 'package:stadtbote/protocoll_messages/fin_task_message.dart';
import 'package:stadtbote/tools/constants.dart';
import 'package:stadtbote/tools/message_service.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/util.dart';
import 'package:badges/badges.dart' as badges;
import '../tools/messages/publish_payload_message.dart';
Future<void> showAcceptJobsPopup(BuildContext context, List<Job> jobs, Function() onFinished) async {
Timer? _checkForNewJobsTimer;
Map<int, DateTime> _firstDelayTimeMap = {};
Future<void> showAcceptJobsPopup(BuildContext context, SharedMapReference mapReference, Function() onFinished) async {
await showDialog<void>(
context: context,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async {
MessageService().unsubscribe(Constants.messageTopicJobDeleted, jobs);
MessageService().unsubscribe(Constants.messageTopicJobReceived, jobs);
_stopTimer();
Navigator.of(context).pop();
@@ -38,34 +41,7 @@ Future<void> showAcceptJobsPopup(BuildContext context, List<Job> jobs, Function(
shadowColor: Colors.transparent,
backgroundColor: Colors.white,
content: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
if (jobs.isEmpty) {
Navigator.of(context).pop();
onFinished();
}
MessageService().unsubscribe(Constants.messageTopicJobDeleted, jobs);
MessageService().unsubscribe(Constants.messageTopicJobReceived, jobs);
MessageService().subscribe<JobDeletedMessage>(Constants.messageTopicJobDeleted, jobs, (jobDeletedMessage) async {
jobs.removeWhere((value) => value.id == jobDeletedMessage.id);
if (context.mounted) {
setState(() {});
}
});
MessageService().subscribe<JobReceivedMessage>(Constants.messageTopicJobReceived, jobs, (jobMessage) async {
jobs.removeWhere((value) => value.id == jobMessage.job.id);
if (jobMessage.job.state == 0) {
jobs.add(jobMessage.job);
if (context.mounted) {
setState(() {});
}
}
});
_startTimer(mapReference, setState);
return SizedBox(
key: GlobalKey(),
@@ -75,7 +51,7 @@ Future<void> showAcceptJobsPopup(BuildContext context, List<Job> jobs, Function(
height: 100,
padding: const EdgeInsets.all(5),
child: FutureBuilder<List<Widget>>(
future: fetchJobWidgets(jobs),
future: _fetchJobWidgets(mapReference),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Util.getWaitWidget(context);
@@ -91,19 +67,41 @@ Future<void> showAcceptJobsPopup(BuildContext context, List<Job> jobs, Function(
});
}
Future<List<Widget>> fetchJobWidgets(List<Job> jobs) async {
void _startTimer(SharedMapReference mapReference, StateSetter setState) {
_checkForNewJobsTimer ??= Timer.periodic(const Duration(seconds: 5), (Timer t) async {
var jobMap = SharedMap<int, Job>.fromSharedReference(mapReference);
if (await jobMap.length() > 0) {
setState(() { });
}
});
}
void _stopTimer() {
if (_checkForNewJobsTimer != null) {
_checkForNewJobsTimer!.cancel();
_checkForNewJobsTimer = null;
}
}
Future<List<Widget>> _fetchJobWidgets(SharedMapReference mapReference) async {
List<Widget> widgets = [];
for (var job in jobs) {
int enableDelay = 3; //job.delayOrderTime;
if (job.firstDisplayTime == null) {
await MyApp.isarInstance.writeTxn(() async {
job.firstDisplayTime = DateTime.now();
var jobMap = SharedMap<int, Job>.fromSharedReference(mapReference);
await MyApp.isarInstance.jobs.put(job);
});
var entries = await jobMap.entries();
for (var jobEntry in entries) {
var job = jobEntry.value;
int enableDelay = 3; //job.delayOrderTime;
if (!_firstDelayTimeMap.containsKey(job.id)) {
_firstDelayTimeMap[job.id] = DateTime.now();
} else {
enableDelay = max(0, DateTime.now().difference(job.firstDisplayTime!).inSeconds);
DateTime firstDisplayTime = _firstDelayTimeMap[job.id]!;
int diffInSeconds = DateTime.now().difference(firstDisplayTime).inSeconds;
enableDelay = min(0, diffInSeconds);
}
widgets.add(StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
@@ -200,21 +198,21 @@ Future<List<Widget>> fetchJobWidgets(List<Job> jobs) async {
Row(children: [
Expanded(
child: getDefaultButton(!job.global ? 'Ablehnen' : 'Ignorieren', () {
_sendAnswer(job, !job.global ? 2 : 3);
setState(() {
_sendAnswer(job, !job.global ? 2 : 3);
jobs.removeWhere((value) => value.id == job.id);
setState(() {});
//jobs.removeWhere((value) => value.id == job.id);
});
}),
),
const SizedBox(width: 20),
Expanded(
child: getDefaultButton('Annehmen', enabledTimerActive: enableDelay > 0, enabledTimerDelay: enableDelay, () {
_sendAnswer(job, 1);
setState(() {
_sendAnswer(job, 1);
jobs.removeWhere((value) => value.id == job.id);
setState(() {});
//jobs.removeWhere((value) => value.id == job.id);
});
}),
)
])
@@ -245,12 +243,11 @@ _sendAnswer(Job job, int item) async {
message.track.pos!.long = currentPosition != null ? currentPosition.longitude : 0.0;
message.track.pos!.acc = currentPosition != null ? currentPosition.accuracy.toInt() : 0;
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload,
arguments: PublishPayloadMessage(topic: "reaction", message: message.toJson(), qos: MqttQos.exactlyOnce));
await MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "reaction", message: message.toJson(), qos: MqttQos.exactlyOnce));
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.jobs.delete(job.id);
});
MessageService().publish(Constants.messageTopicUpdateBadges, arguments: RefreshBadgesMessage());
await MessageService().publish(Constants.messageTopicUpdateBadges, arguments: RefreshBadgesMessage());
}
+1 -2
View File
@@ -14,8 +14,7 @@ void showInfosPopup(BuildContext context, SessionStatus? status) async {
late String connectedString = "Bitte warten...";
Future.delayed(const Duration(seconds: 2), () async {
MessageService()
.publish<RequestConnectionStatusMessage>(Constants.messageTopicRequestConnectionStatus, arguments: RequestConnectionStatusMessage());
await MessageService().publish<RequestConnectionStatusMessage>(Constants.messageTopicRequestConnectionStatus, arguments: RequestConnectionStatusMessage());
});
void unsubscribeMessages() {
@@ -42,6 +42,7 @@ showReceiptGiverPopup(BuildContext context, TaskInfo taskInfo, Function(String)
textInputType: TextInputType.text,
formatter: [FilteringTextInputFormatter.singleLineFormatter],
controller: textEditingController,
maxLength: 50,
autofocus: true),
const SizedBox(height: 20),
getDefaultButton('Übernehmen', () {
+8 -1
View File
@@ -1,3 +1,5 @@
import 'dart:async';
typedef EventHandler<T> = void Function(T args);
class _MapEntry {
@@ -59,13 +61,18 @@ class MessageService {
}
}
publish<T>(String topic, {T? arguments}) {
publish<T>(String topic, {T? arguments}) async {
Completer<void> completer = Completer();
var entries = _callbackMaps[topic];
if (entries != null) {
for (var entry in entries) {
entry.handler(arguments);
}
completer.complete();
}
await completer.future;
}
}
+33 -26
View File
@@ -4,6 +4,7 @@ import 'dart:math';
import 'package:archive/archive.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:isar/isar.dart';
import 'package:mqtt_client/mqtt_client.dart';
@@ -79,8 +80,8 @@ class MqttCore {
_processBootstrap();
}
_disconnectMqttClient() {
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
_disconnectMqttClient() async {
await MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
_disconnectInProgress = true;
@@ -93,7 +94,6 @@ class MqttCore {
}
connectionState = ConnectionStateEnum.notConnected;
}
_connectToBroker() async {
@@ -128,19 +128,23 @@ class MqttCore {
} else {
Util.logInfo('Verbindung zum MQTT-Broker fehlgeschlagen!');
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
await MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
}
} catch (ex) {
Util.logInfo('Verbindung zum MQTT-Broker fehlgeschlagen!: $ex');
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
await MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
}
}
bool _publishText(String topic, String text, MqttQos qos, {bool enqueueOnError = true}) {
try {
var buffer = Uint8Buffer();
buffer.addAll(GZipEncoder().encode(const Utf8Encoder().convert(text)) as Iterable<int>);
if (kDebugMode) {
buffer.addAll(const Utf8Encoder().convert(text));
} else {
buffer.addAll(GZipEncoder().encode(const Utf8Encoder().convert(text)) as Iterable<int>);
}
var messageTopic = "$_toServerTopic$_clientId/$topic";
@@ -174,8 +178,12 @@ class MqttCore {
Util.logInfo('message received\ntopic: $topic\n');
Util.logInfo("size in bytes: ${message.payload.message.length.toString()}");
var messageBytes = message.payload.message;
String payload = utf8.decode(GZipDecoder().decodeBytes(messageBytes));
String payload;
if (kDebugMode) {
payload = utf8.decode(message.payload.message);
} else {
payload = utf8.decode(GZipDecoder().decodeBytes(message.payload.message));
}
Util.logInfo('$topic\nmessage: $payload');
@@ -244,7 +252,7 @@ class MqttCore {
Util.logInfo('subscribed to topic: $fromServerTopic');
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.connected));
await MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.connected));
}
void _sessionMessageReceived(payloadData) async {
@@ -261,8 +269,7 @@ class MqttCore {
await MyApp.isarInstance.sessionStatus.put(sessionStatusMessage);
});
MessageService().publish<SessionStatusInfoUpdate>(Constants.messageTopicSessionStatusInfoUpdate,
arguments: SessionStatusInfoUpdate(status: sessionStatusMessage));
await MessageService().publish<SessionStatusInfoUpdate>(Constants.messageTopicSessionStatusInfoUpdate, arguments: SessionStatusInfoUpdate(status: sessionStatusMessage));
_startTrackTimer();
}
@@ -275,7 +282,7 @@ class MqttCore {
await MyApp.isarInstance.status.put(statusMessage);
});
MessageService().publish<StatusInfoUpdate>(Constants.messageTopicStatusInfoUpdated, arguments: StatusInfoUpdate(status: statusMessage));
await MessageService().publish<StatusInfoUpdate>(Constants.messageTopicStatusInfoUpdated, arguments: StatusInfoUpdate(status: statusMessage));
}
void _locationStatusMessageReceived(payloadData) async {
@@ -286,7 +293,7 @@ class MqttCore {
await MyApp.isarInstance.locationStatus.put(locationStatus);
});
MessageService().publish<LocationStatusUpdate>(Constants.messageTopicLocationStatusUpdated, arguments: LocationStatusUpdate(status: locationStatus));
await MessageService().publish<LocationStatusUpdate>(Constants.messageTopicLocationStatusUpdated, arguments: LocationStatusUpdate(status: locationStatus));
}
void _rankingMessageReceived(payloadData) async {
@@ -297,7 +304,7 @@ class MqttCore {
await MyApp.isarInstance.rankings.put(ranking);
});
MessageService().publish<RankingUpdated>(Constants.messageTopicRankingUpdated, arguments: RankingUpdated());
await MessageService().publish<RankingUpdated>(Constants.messageTopicRankingUpdated, arguments: RankingUpdated());
}
void _jobMessageReceived(payloadData) async {
@@ -318,7 +325,7 @@ class MqttCore {
_acknowlegdeJob(newJob);
try {
MessageService().publish<JobReceivedMessage>(Constants.messageTopicJobReceived, arguments: JobReceivedMessage(job: newJob));
await MessageService().publish<JobReceivedMessage>(Constants.messageTopicJobReceived, arguments: JobReceivedMessage(job: newJob));
} catch (ex) {
Util.logException("publish messageTopicJobReceived failed!");
}
@@ -333,7 +340,7 @@ class MqttCore {
await MyApp.isarInstance.jobs.delete(jobDelMessage.id);
});
MessageService().publish<JobDeletedMessage>(Constants.messageTopicJobDeleted, arguments: JobDeletedMessage(id: jobDelMessage.id));
await MessageService().publish<JobDeletedMessage>(Constants.messageTopicJobDeleted, arguments: JobDeletedMessage(id: jobDelMessage.id));
}
}
@@ -352,7 +359,7 @@ class MqttCore {
await Util.playMp3('asbeep.mp3');
MessageService().publish<MessageReceivedMessage>(Constants.messageTopicMessageReceived, arguments: MessageReceivedMessage(message: newMessage));
await MessageService().publish<MessageReceivedMessage>(Constants.messageTopicMessageReceived, arguments: MessageReceivedMessage(message: newMessage));
}
void _messageUploadDeviceLogReceived(payloadData) async {
@@ -394,24 +401,24 @@ class MqttCore {
}
}
void _clientDisconnected() {
Future<void> _clientDisconnected() async {
Util.logInfo("_clientDisconnected called");
connectionState = ConnectionStateEnum.notConnected;
_cancelTrackTimer();
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
await MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
}
void _clientConnected() {
Future<void> _clientConnected() async {
Util.logInfo("_clientConnected called");
connectionState = ConnectionStateEnum.connected;
_initSession();
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.connected));
await MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.connected));
}
void _processBootstrap() async {
@@ -446,8 +453,8 @@ class MqttCore {
var bootstrapResponsePayload = BootstrapResponse.fromJson(jsonDecode(responseText));
var brokerUriAndPortArray = bootstrapResponsePayload.broker.replaceFirst("mqtt://", "").split(":");
_brokerUri = brokerUriAndPortArray[0];
_brokerPort = int.parse(brokerUriAndPortArray[1]);
_brokerUri = "192.168.180.27"; //brokerUriAndPortArray[0];
_brokerPort = 1883; //int.parse(brokerUriAndPortArray[1]);
_clientId = bootstrapResponsePayload.id;
_fromServerTopic = bootstrapResponsePayload.fromServer;
_toServerTopic = bootstrapResponsePayload.toServer;
@@ -464,6 +471,7 @@ class MqttCore {
var startSessionMessage = StartSessionMessage();
var jsonMap = startSessionMessage.toJson();
var json = jsonEncode(jsonMap);
_publishText("session", json, MqttQos.exactlyOnce);
}
@@ -559,7 +567,7 @@ class MqttCore {
});
MessageService().subscribe<RequestConnectionStatusMessage>(Constants.messageTopicRequestConnectionStatus, this,
(RequestConnectionStatusMessage requestConnectionStatusMessage) {
(RequestConnectionStatusMessage requestConnectionStatusMessage) async {
bool connected = false;
if (_mqttClient != null && _mqttClient!.connectionStatus != null) {
if (_mqttClient!.connectionStatus!.state == MqttConnectionState.connected) {
@@ -567,8 +575,7 @@ class MqttCore {
}
}
MessageService().publish<CurrentConnectionStatusMessage>(Constants.messageTopicCurrentConnectionStatus,
arguments: CurrentConnectionStatusMessage(state: connected));
await MessageService().publish<CurrentConnectionStatusMessage>(Constants.messageTopicCurrentConnectionStatus, arguments: CurrentConnectionStatusMessage(state: connected));
});
}
}
+2
View File
@@ -152,6 +152,7 @@ class Util {
FocusNode? focusNode,
IconButton? iconButton,
int? maxLines = 1,
int? maxLength = 100,
TextInputType? textInputType,
List<TextInputFormatter>? formatter,
Function()? onTap,
@@ -172,6 +173,7 @@ class Util {
onTap: onTap,
keyboardType: textInputType,
inputFormatters: formatter,
maxLength: maxLength,
autofocus: (autofocus != null) ? autofocus : false,
decoration: InputDecoration(
hintText: hint,