Erweiterungen
This commit is contained in:
1 parent
85e973c3dd
commit
fbdd2a4338
14 files changed
+296
-116
No files matched your search
@@ -1,6 +1,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mqtt_client/mqtt_client.dart';
|
||||
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
|
||||
import 'package:stadtbote/content_views/utils/header_info.dart';
|
||||
import 'package:stadtbote/main.dart';
|
||||
@@ -211,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()));
|
||||
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "set_zip", message: setPosMessage.toJson(), qos: MqttQos.exactlyOnce));
|
||||
}
|
||||
|
||||
_initMessages() {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import 'package:expandable/expandable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mqtt_client/mqtt_client.dart';
|
||||
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
|
||||
import 'package:stadtbote/content_views/utils/header_info.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@@ -199,7 +200,7 @@ 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()));
|
||||
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);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mqtt_client/mqtt_client.dart';
|
||||
import 'package:stadtbote/content_views/accepted_jobs_page.dart';
|
||||
import 'package:stadtbote/content_views/approach_area_page.dart';
|
||||
import 'package:stadtbote/content_views/assigned_jobs_page.dart';
|
||||
@@ -380,6 +381,6 @@ class _MainPageState extends State<MainPage> {
|
||||
logoutMessage.pos!.acc = position.accuracy.toInt();
|
||||
}
|
||||
|
||||
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "logout", message: logoutMessage.toJson()));
|
||||
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "logout", message: logoutMessage.toJson(), qos: MqttQos.exactlyOnce));
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
|
||||
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mqtt_client/mqtt_client.dart';
|
||||
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
|
||||
import 'package:stadtbote/content_views/utils/header_info.dart';
|
||||
import 'package:stadtbote/main.dart';
|
||||
@@ -109,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()));
|
||||
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "message", message: message.toJson(), qos: MqttQos.exactlyOnce));
|
||||
|
||||
_messages.insert(0, types.TextMessage(
|
||||
author: _user,
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mqtt_client/mqtt_client.dart';
|
||||
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
|
||||
import 'package:stadtbote/content_views/utils/header_info.dart';
|
||||
import 'package:stadtbote/messages/pop_content_view_message.dart';
|
||||
@@ -482,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()));
|
||||
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "fin_task", message: message.toJson(), qos: MqttQos.exactlyOnce));
|
||||
}
|
||||
|
||||
FinTourTask _createAnswerHeader(TaskInfo taskInfo) {
|
||||
@@ -526,7 +527,7 @@ class _TaskListPageState extends State<TaskListPage> {
|
||||
}
|
||||
}
|
||||
|
||||
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "fin_tour", message: finTourMessage.toJson()));
|
||||
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "fin_tour", message: finTourMessage.toJson(), qos: MqttQos.exactlyOnce));
|
||||
|
||||
widget.tour.state = Constants.stateFinishedNotConfirmed;
|
||||
|
||||
@@ -551,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()));
|
||||
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);
|
||||
|
||||
+12
-1
@@ -56,7 +56,9 @@ Future<void> main() async {
|
||||
Future<void> _clearLog() async {
|
||||
var dateTime = DateTime.now().add(const Duration(days: -7));
|
||||
|
||||
await MyApp.isarInstance.logEntrys.where().filter().timeLessThan(dateTime).deleteAll();
|
||||
await MyApp.isarInstance.writeTxn(() async {
|
||||
await MyApp.isarInstance.logEntrys.where().filter().timeLessThan(dateTime).deleteAll();
|
||||
});
|
||||
}
|
||||
|
||||
void _traceUncaughtExceptions(Object error, StackTrace stackTrace) {
|
||||
@@ -342,6 +344,13 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin {
|
||||
}
|
||||
|
||||
void _initMessages() {
|
||||
MessageService().unsubscribe(Constants.messageTopicPushContentView, this);
|
||||
MessageService().unsubscribe(Constants.messageTopicPopContentView, this);
|
||||
MessageService().unsubscribe(Constants.messageTopicReplaceContentView, this);
|
||||
MessageService().unsubscribe(Constants.messageTopicHideRightButton, this);
|
||||
MessageService().unsubscribe(Constants.messageTopicConnectionStatusChanged, this);
|
||||
MessageService().unsubscribe(Constants.messageTopicJobReceived, this);
|
||||
|
||||
MessageService().subscribe<ContentViewWidget>(Constants.messageTopicPushContentView, this, (ContentViewWidget widget) {
|
||||
_pushContentView(widget);
|
||||
});
|
||||
@@ -441,6 +450,8 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin {
|
||||
}
|
||||
|
||||
void _connectionStatusChanged(ConnectionStatus connectionStatus) {
|
||||
Util.logInfo("_connectionStatusChanged called: $connectionStatus");
|
||||
|
||||
_connectionLostValueNotifier.value = connectionStatus.status == ConnectionStatusEnum.notConnected;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,17 @@ class Job {
|
||||
late int vhtId;
|
||||
@JsonKey(name: 'rem')
|
||||
late String rem;
|
||||
@JsonKey(name: 'delayOrderTime')
|
||||
late int delayOrderTime;
|
||||
@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);
|
||||
|
||||
+135
-31
@@ -22,44 +22,49 @@ const JobSchema = CollectionSchema(
|
||||
name: r'crFilter',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'global': PropertySchema(
|
||||
r'delayOrderTime': PropertySchema(
|
||||
id: 1,
|
||||
name: r'delayOrderTime',
|
||||
type: IsarType.long,
|
||||
),
|
||||
r'global': PropertySchema(
|
||||
id: 2,
|
||||
name: r'global',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'offsWarn': PropertySchema(
|
||||
id: 2,
|
||||
id: 3,
|
||||
name: r'offsWarn',
|
||||
type: IsarType.long,
|
||||
),
|
||||
r'ordertime': PropertySchema(
|
||||
id: 3,
|
||||
id: 4,
|
||||
name: r'ordertime',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'rem': PropertySchema(
|
||||
id: 4,
|
||||
id: 5,
|
||||
name: r'rem',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'state': PropertySchema(
|
||||
id: 5,
|
||||
id: 6,
|
||||
name: r'state',
|
||||
type: IsarType.long,
|
||||
),
|
||||
r'tours': PropertySchema(
|
||||
id: 6,
|
||||
id: 7,
|
||||
name: r'tours',
|
||||
type: IsarType.objectList,
|
||||
target: r'JobTour',
|
||||
),
|
||||
r'ver': PropertySchema(
|
||||
id: 7,
|
||||
id: 8,
|
||||
name: r'ver',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'vhtId': PropertySchema(
|
||||
id: 8,
|
||||
id: 9,
|
||||
name: r'vhtId',
|
||||
type: IsarType.long,
|
||||
)
|
||||
@@ -116,19 +121,20 @@ void _jobSerialize(
|
||||
Map<Type, List<int>> allOffsets,
|
||||
) {
|
||||
writer.writeString(offsets[0], object.crFilter);
|
||||
writer.writeBool(offsets[1], object.global);
|
||||
writer.writeLong(offsets[2], object.offsWarn);
|
||||
writer.writeString(offsets[3], object.ordertime);
|
||||
writer.writeString(offsets[4], object.rem);
|
||||
writer.writeLong(offsets[5], object.state);
|
||||
writer.writeLong(offsets[1], object.delayOrderTime);
|
||||
writer.writeBool(offsets[2], object.global);
|
||||
writer.writeLong(offsets[3], object.offsWarn);
|
||||
writer.writeString(offsets[4], object.ordertime);
|
||||
writer.writeString(offsets[5], object.rem);
|
||||
writer.writeLong(offsets[6], object.state);
|
||||
writer.writeObjectList<JobTour>(
|
||||
offsets[6],
|
||||
offsets[7],
|
||||
allOffsets,
|
||||
JobTourSchema.serialize,
|
||||
object.tours,
|
||||
);
|
||||
writer.writeString(offsets[7], object.ver);
|
||||
writer.writeLong(offsets[8], object.vhtId);
|
||||
writer.writeString(offsets[8], object.ver);
|
||||
writer.writeLong(offsets[9], object.vhtId);
|
||||
}
|
||||
|
||||
Job _jobDeserialize(
|
||||
@@ -139,21 +145,22 @@ Job _jobDeserialize(
|
||||
) {
|
||||
final object = Job();
|
||||
object.crFilter = reader.readStringOrNull(offsets[0]);
|
||||
object.global = reader.readBool(offsets[1]);
|
||||
object.delayOrderTime = reader.readLong(offsets[1]);
|
||||
object.global = reader.readBool(offsets[2]);
|
||||
object.id = id;
|
||||
object.offsWarn = reader.readLong(offsets[2]);
|
||||
object.ordertime = reader.readString(offsets[3]);
|
||||
object.rem = reader.readString(offsets[4]);
|
||||
object.state = reader.readLong(offsets[5]);
|
||||
object.offsWarn = reader.readLong(offsets[3]);
|
||||
object.ordertime = reader.readString(offsets[4]);
|
||||
object.rem = reader.readString(offsets[5]);
|
||||
object.state = reader.readLong(offsets[6]);
|
||||
object.tours = reader.readObjectList<JobTour>(
|
||||
offsets[6],
|
||||
offsets[7],
|
||||
JobTourSchema.deserialize,
|
||||
allOffsets,
|
||||
JobTour(),
|
||||
) ??
|
||||
[];
|
||||
object.ver = reader.readString(offsets[7]);
|
||||
object.vhtId = reader.readLong(offsets[8]);
|
||||
object.ver = reader.readString(offsets[8]);
|
||||
object.vhtId = reader.readLong(offsets[9]);
|
||||
return object;
|
||||
}
|
||||
|
||||
@@ -167,16 +174,18 @@ P _jobDeserializeProp<P>(
|
||||
case 0:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 1:
|
||||
return (reader.readBool(offset)) as P;
|
||||
case 2:
|
||||
return (reader.readLong(offset)) as P;
|
||||
case 2:
|
||||
return (reader.readBool(offset)) as P;
|
||||
case 3:
|
||||
return (reader.readString(offset)) as P;
|
||||
return (reader.readLong(offset)) as P;
|
||||
case 4:
|
||||
return (reader.readString(offset)) as P;
|
||||
case 5:
|
||||
return (reader.readLong(offset)) as P;
|
||||
return (reader.readString(offset)) as P;
|
||||
case 6:
|
||||
return (reader.readLong(offset)) as P;
|
||||
case 7:
|
||||
return (reader.readObjectList<JobTour>(
|
||||
offset,
|
||||
JobTourSchema.deserialize,
|
||||
@@ -184,9 +193,9 @@ P _jobDeserializeProp<P>(
|
||||
JobTour(),
|
||||
) ??
|
||||
[]) as P;
|
||||
case 7:
|
||||
return (reader.readString(offset)) as P;
|
||||
case 8:
|
||||
return (reader.readString(offset)) as P;
|
||||
case 9:
|
||||
return (reader.readLong(offset)) as P;
|
||||
default:
|
||||
throw IsarError('Unknown property with id $propertyId');
|
||||
@@ -425,6 +434,59 @@ extension JobQueryFilter on QueryBuilder<Job, Job, QFilterCondition> {
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QAfterFilterCondition> delayOrderTimeEqualTo(
|
||||
int value) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'delayOrderTime',
|
||||
value: value,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QAfterFilterCondition> delayOrderTimeGreaterThan(
|
||||
int value, {
|
||||
bool include = false,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
include: include,
|
||||
property: r'delayOrderTime',
|
||||
value: value,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QAfterFilterCondition> delayOrderTimeLessThan(
|
||||
int value, {
|
||||
bool include = false,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.lessThan(
|
||||
include: include,
|
||||
property: r'delayOrderTime',
|
||||
value: value,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QAfterFilterCondition> delayOrderTimeBetween(
|
||||
int lower,
|
||||
int upper, {
|
||||
bool includeLower = true,
|
||||
bool includeUpper = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.between(
|
||||
property: r'delayOrderTime',
|
||||
lower: lower,
|
||||
includeLower: includeLower,
|
||||
upper: upper,
|
||||
includeUpper: includeUpper,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QAfterFilterCondition> globalEqualTo(bool value) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
@@ -1134,6 +1196,18 @@ extension JobQuerySortBy on QueryBuilder<Job, Job, QSortBy> {
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QAfterSortBy> sortByDelayOrderTime() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'delayOrderTime', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QAfterSortBy> sortByDelayOrderTimeDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'delayOrderTime', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QAfterSortBy> sortByGlobal() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'global', Sort.asc);
|
||||
@@ -1232,6 +1306,18 @@ extension JobQuerySortThenBy on QueryBuilder<Job, Job, QSortThenBy> {
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QAfterSortBy> thenByDelayOrderTime() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'delayOrderTime', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QAfterSortBy> thenByDelayOrderTimeDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'delayOrderTime', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QAfterSortBy> thenByGlobal() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'global', Sort.asc);
|
||||
@@ -1337,6 +1423,12 @@ extension JobQueryWhereDistinct on QueryBuilder<Job, Job, QDistinct> {
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QDistinct> distinctByDelayOrderTime() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'delayOrderTime');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, Job, QDistinct> distinctByGlobal() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'global');
|
||||
@@ -1394,6 +1486,12 @@ extension JobQueryProperty on QueryBuilder<Job, Job, QQueryProperty> {
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, int, QQueryOperations> delayOrderTimeProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'delayOrderTime');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Job, bool, QQueryOperations> globalProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'global');
|
||||
@@ -1457,9 +1555,13 @@ Job _$JobFromJson(Map<String, dynamic> json) => Job()
|
||||
..global = json['global'] as bool
|
||||
..vhtId = json['vht_id'] as int
|
||||
..rem = json['rem'] as String
|
||||
..delayOrderTime = json['delayOrderTime'] as int
|
||||
..tours = (json['tours'] as List<dynamic>)
|
||||
.map((e) => JobTour.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
.toList()
|
||||
..firstDisplayTime = json['firstDisplayTime'] == null
|
||||
? null
|
||||
: DateTime.parse(json['firstDisplayTime'] as String);
|
||||
|
||||
Map<String, dynamic> _$JobToJson(Job instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
@@ -1471,5 +1573,7 @@ Map<String, dynamic> _$JobToJson(Job instance) => <String, dynamic>{
|
||||
'global': instance.global,
|
||||
'vht_id': instance.vhtId,
|
||||
'rem': instance.rem,
|
||||
'delayOrderTime': instance.delayOrderTime,
|
||||
'tours': instance.tours,
|
||||
'firstDisplayTime': instance.firstDisplayTime?.toIso8601String(),
|
||||
};
|
||||
@@ -1,7 +1,11 @@
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:expandable/expandable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mqtt_client/mqtt_client.dart';
|
||||
import 'package:stadtbote/main.dart';
|
||||
import 'package:stadtbote/protocoll_messages/accept_job_message.dart';
|
||||
import 'package:stadtbote/model/job.dart';
|
||||
@@ -17,15 +21,13 @@ 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 {
|
||||
var jobsSet = jobs.toSet();
|
||||
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
MessageService().unsubscribe(Constants.messageTopicJobDeleted, jobsSet);
|
||||
MessageService().unsubscribe(Constants.messageTopicJobReceived, jobsSet);
|
||||
MessageService().unsubscribe(Constants.messageTopicJobDeleted, jobs);
|
||||
MessageService().unsubscribe(Constants.messageTopicJobReceived, jobs);
|
||||
|
||||
Navigator.of(context).pop();
|
||||
|
||||
@@ -38,27 +40,27 @@ Future<void> showAcceptJobsPopup(BuildContext context, List<Job> jobs, Function(
|
||||
shadowColor: Colors.transparent,
|
||||
backgroundColor: Colors.white,
|
||||
content: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
||||
if (jobsSet.isEmpty) {
|
||||
if (jobs.isEmpty) {
|
||||
Navigator.of(context).pop();
|
||||
|
||||
onFinished();
|
||||
}
|
||||
|
||||
MessageService().unsubscribe(Constants.messageTopicJobDeleted, jobsSet);
|
||||
MessageService().unsubscribe(Constants.messageTopicJobReceived, jobsSet);
|
||||
MessageService().unsubscribe(Constants.messageTopicJobDeleted, jobs);
|
||||
MessageService().unsubscribe(Constants.messageTopicJobReceived, jobs);
|
||||
|
||||
MessageService().subscribe<JobDeletedMessage>(Constants.messageTopicJobDeleted, jobsSet, (jobDeletedMessage) async {
|
||||
jobsSet.removeWhere((value) => value.id == jobDeletedMessage.id);
|
||||
MessageService().subscribe<JobDeletedMessage>(Constants.messageTopicJobDeleted, jobs, (jobDeletedMessage) async {
|
||||
jobs.removeWhere((value) => value.id == jobDeletedMessage.id);
|
||||
|
||||
if (context.mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
|
||||
MessageService().subscribe<JobReceivedMessage>(Constants.messageTopicJobReceived, jobsSet, (jobdMessage) async {
|
||||
jobsSet.removeWhere((value) => value.id == jobdMessage.job.id);
|
||||
MessageService().subscribe<JobReceivedMessage>(Constants.messageTopicJobReceived, jobs, (jobdMessage) async {
|
||||
jobs.removeWhere((value) => value.id == jobdMessage.job.id);
|
||||
|
||||
jobsSet.add(jobdMessage.job);
|
||||
jobs.add(jobdMessage.job);
|
||||
|
||||
if (context.mounted) {
|
||||
setState(() {});
|
||||
@@ -73,9 +75,24 @@ Future<void> showAcceptJobsPopup(BuildContext context, List<Job> jobs, Function(
|
||||
height: 100,
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: ListView.builder(
|
||||
itemCount: jobsSet.length,
|
||||
itemCount: jobs.length,
|
||||
itemBuilder: (_, i) {
|
||||
var job = jobsSet.toList()[i];
|
||||
var job = jobs[i];
|
||||
|
||||
for (var job in jobs) {
|
||||
int enableDelay = job.delayOrderTime;
|
||||
if (job.firstDisplayTime == null) {
|
||||
MyApp.isarInstance.writeTxn(() async {
|
||||
job.firstDisplayTime = DateTime.now();
|
||||
|
||||
await MyApp.isarInstance.jobs.put(job);
|
||||
});
|
||||
} else {
|
||||
enableDelay = max(0, DateTime.now().difference(job.firstDisplayTime!).inSeconds);
|
||||
}
|
||||
|
||||
job.enableDelay = enableDelay;
|
||||
}
|
||||
|
||||
return ExpandableNotifier(
|
||||
child: ListTile(
|
||||
@@ -173,17 +190,17 @@ Future<void> showAcceptJobsPopup(BuildContext context, List<Job> jobs, Function(
|
||||
() {
|
||||
_sendAnswer(job, !job.global ? 2 : 3);
|
||||
|
||||
jobsSet.removeWhere((value) => value.id == job.id);
|
||||
jobs.removeWhere((value) => value.id == job.id);
|
||||
|
||||
setState(() {});
|
||||
}),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
Expanded(
|
||||
child: getDefaultButton('Annehmen', () {
|
||||
child: getDefaultButton('Annehmen', enabledTimerActive: job.global == false && job.enableDelay > 0, enabledTimerDelay: job.enableDelay, () {
|
||||
_sendAnswer(job, 1);
|
||||
|
||||
jobsSet.removeWhere((value) => value.id == job.id);
|
||||
jobs.removeWhere((value) => value.id == job.id);
|
||||
|
||||
setState(() {});
|
||||
}),
|
||||
@@ -217,7 +234,7 @@ _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()));
|
||||
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);
|
||||
|
||||
@@ -37,6 +37,22 @@ class MessageService {
|
||||
if (entry.owner == owner) {
|
||||
_callbackMaps[topic]!.remove(entry);
|
||||
|
||||
unsubscribe(topic, owner);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsubscribeAll<T>(dynamic owner) {
|
||||
for (var callbackMapsEntry in _callbackMaps.entries) {
|
||||
for (var entry in callbackMapsEntry.value.toList()) {
|
||||
if (entry.owner == owner) {
|
||||
_callbackMaps[callbackMapsEntry.key]!.remove(entry);
|
||||
|
||||
unsubscribeAll(owner);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import 'package:mqtt_client/mqtt_client.dart';
|
||||
|
||||
class PublishPayloadMessage {
|
||||
final String topic;
|
||||
|
||||
final Map<String, dynamic> message;
|
||||
|
||||
PublishPayloadMessage({required this.topic, required this.message});
|
||||
final MqttQos qos;
|
||||
|
||||
PublishPayloadMessage({required this.topic, required this.message, required this.qos});
|
||||
}
|
||||
+17
-22
@@ -119,31 +119,29 @@ class MqttCore {
|
||||
|
||||
_reconnectDelay = 0;
|
||||
|
||||
_setupMqtt();
|
||||
await _setupMqtt();
|
||||
|
||||
_initSession();
|
||||
} else {
|
||||
Util.logInfo('Verbindung zum MQTT-Broker fehlgeschlagen!');
|
||||
|
||||
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged,
|
||||
arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
|
||||
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));
|
||||
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
|
||||
}
|
||||
}
|
||||
|
||||
bool _publishText(String topic, String text, {bool enqueueOnError = true}) {
|
||||
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>);
|
||||
|
||||
var messageTopic = "$_toServerTopic$_clientId/$topic";
|
||||
|
||||
_mqttClient!.publishMessage(messageTopic, MqttQos.exactlyOnce, buffer);
|
||||
_mqttClient!.publishMessage(messageTopic, qos, buffer);
|
||||
|
||||
Util.logInfo("message\n$text\nsend to $messageTopic");
|
||||
Util.logInfo("size in bytes: ${buffer.length}");
|
||||
@@ -158,7 +156,7 @@ class MqttCore {
|
||||
return false;
|
||||
}
|
||||
|
||||
void _setupMqtt() async {
|
||||
Future<void> _setupMqtt() async {
|
||||
Util.logInfo('_setupMqtt called');
|
||||
|
||||
_mqttClient!.updates?.listen((List<MqttReceivedMessage<MqttMessage>> messages) {
|
||||
@@ -368,7 +366,7 @@ class MqttCore {
|
||||
|
||||
var json = jsonEncode(deviceLog.toJson());
|
||||
|
||||
_publishText("device_log", json);
|
||||
_publishText("device_log", json, MqttQos.atMostOnce);
|
||||
}
|
||||
|
||||
void _startBootstrapReconnectTimer() {
|
||||
@@ -398,19 +396,17 @@ class MqttCore {
|
||||
|
||||
_startTrackTimer();
|
||||
|
||||
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged,
|
||||
arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
|
||||
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
|
||||
}
|
||||
|
||||
void _clientConnected() {
|
||||
Util.logInfo("_clientDisconnected called");
|
||||
Util.logInfo("_clientConnected called");
|
||||
|
||||
connectionState = ConnectionStateEnum.connected;
|
||||
|
||||
_initSession();
|
||||
|
||||
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged,
|
||||
arguments: ConnectionStatus(status: ConnectionStatusEnum.connected));
|
||||
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.connected));
|
||||
}
|
||||
|
||||
void _processBootstrap() async {
|
||||
@@ -434,7 +430,6 @@ class MqttCore {
|
||||
|
||||
var jsonMap = handshakeMessage.toJson();
|
||||
var json = Uri.encodeFull(jsonEncode(jsonMap));
|
||||
//var uri = "https://test-app-server.assecutor.org/bootstrap?json=$json";
|
||||
var uri = "https://bootstrap.assecutor.de/bootstrap?json=$json";
|
||||
|
||||
Util.logInfo("Bootstrap request: $uri");
|
||||
@@ -454,7 +449,7 @@ class MqttCore {
|
||||
|
||||
_connectToBroker();
|
||||
} catch (ex) {
|
||||
Util.logException("bootstrap failed");
|
||||
Util.logException("bootstrap failed: {$ex}");
|
||||
|
||||
_startBootstrapReconnectTimer();
|
||||
}
|
||||
@@ -464,7 +459,7 @@ class MqttCore {
|
||||
var startSessionMessage = StartSessionMessage();
|
||||
var jsonMap = startSessionMessage.toJson();
|
||||
var json = jsonEncode(jsonMap);
|
||||
_publishText("session", json);
|
||||
_publishText("session", json, MqttQos.exactlyOnce);
|
||||
}
|
||||
|
||||
_sendSyncMessage() async {
|
||||
@@ -482,7 +477,7 @@ class MqttCore {
|
||||
answer.sync.jobs.add(syncJob);
|
||||
}
|
||||
|
||||
_publishText("sync", jsonEncode(answer.toJson()));
|
||||
_publishText("sync", jsonEncode(answer.toJson()), MqttQos.exactlyOnce);
|
||||
}
|
||||
|
||||
void _startTrackTimer() {
|
||||
@@ -495,7 +490,7 @@ class MqttCore {
|
||||
trackMessage.long = position.longitude;
|
||||
trackMessage.acc = position.accuracy.toInt();
|
||||
|
||||
_publishText("track", jsonEncode(trackMessage.toJson()));
|
||||
_publishText("track", jsonEncode(trackMessage.toJson()), MqttQos.atMostOnce);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -522,7 +517,7 @@ class MqttCore {
|
||||
if (enqueuedMessages.isNotEmpty) {
|
||||
for (var enqueuedMessage in enqueuedMessages) {
|
||||
try {
|
||||
if (_publishText(enqueuedMessage.topic, enqueuedMessage.payload, enqueueOnError: false)) {
|
||||
if (_publishText(enqueuedMessage.topic, enqueuedMessage.payload, MqttQos.exactlyOnce, enqueueOnError: false)) {
|
||||
await MyApp.isarInstance.writeTxn(() async {
|
||||
await MyApp.isarInstance.enqueuedMessages.delete(enqueuedMessage.id);
|
||||
});
|
||||
@@ -541,12 +536,12 @@ class MqttCore {
|
||||
message.ver = job.ver;
|
||||
message.utc = DateTime.now().millisecondsSinceEpoch;
|
||||
|
||||
_publishText('job_received', jsonEncode(message.toJson()));
|
||||
_publishText('job_received', jsonEncode(message.toJson()), MqttQos.exactlyOnce);
|
||||
}
|
||||
|
||||
void initMessages() {
|
||||
MessageService().subscribe<PublishPayloadMessage>(Constants.messageTopicPublishPayload, this, (PublishPayloadMessage payloadMessage) {
|
||||
_publishText(payloadMessage.topic, jsonEncode(payloadMessage.message));
|
||||
_publishText(payloadMessage.topic, jsonEncode(payloadMessage.message), payloadMessage.qos);
|
||||
});
|
||||
|
||||
MessageService().subscribe<DisconnectClientMessage>(Constants.messageTopicDisconnectClient, this,
|
||||
|
||||
+55
-35
@@ -220,43 +220,63 @@ class Util {
|
||||
}
|
||||
}
|
||||
|
||||
Widget getDefaultButton(String text, Function() onPressed, {Image? image, double? buttonHeight}) {
|
||||
return SizedBox(
|
||||
height: buttonHeight ?? 50,
|
||||
child: MaterialButton(
|
||||
color: const Color.fromARGB(255, 220, 220, 220),
|
||||
disabledColor: Colors.indigo[400],
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(15),
|
||||
Widget getDefaultButton(String text, Function() onPressed, {Image? image, double? buttonHeight, bool enabledTimerActive = true, int enabledTimerDelay = 0}) {
|
||||
bool enabledState = enabledTimerActive;
|
||||
|
||||
return StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
||||
if (!enabledState) {
|
||||
Future.delayed(Duration(seconds: enabledTimerDelay), () {
|
||||
enabledState = true;
|
||||
|
||||
if (context.mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
}
|
||||
return SizedBox(
|
||||
height: buttonHeight ?? 50,
|
||||
child: MaterialButton(
|
||||
color: const Color.fromARGB(255, 220, 220, 220),
|
||||
disabledColor: const Color.fromARGB(255, 220, 220, 220),
|
||||
disabledElevation: 5,
|
||||
elevation: 5,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(15),
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
if (enabledState) {
|
||||
Util.logInfo("Button \"$text\" clicked");
|
||||
|
||||
onPressed();
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Visibility(
|
||||
visible: image != null,
|
||||
child: CircleAvatar(
|
||||
backgroundColor: Colors.transparent,
|
||||
child: image,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Opacity(
|
||||
opacity: enabledState ? 1.0 : 0.3,
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(color: Colors.black, fontSize: 14.0),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Util.logInfo("Button \"$text\" clicked");
|
||||
|
||||
onPressed();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Visibility(
|
||||
visible: image != null,
|
||||
child: CircleAvatar(
|
||||
backgroundColor: Colors.transparent,
|
||||
child: image,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(color: Colors.black, fontSize: 14.0),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
String mapVehicleTypeToImageName(int vehType)
|
||||
|
||||
Reference in new issue
Block a user