Erweiterungen

This commit is contained in:
Sven committed 2024-02-02 09:57:08 +01:00
1 parent a39991bb63
commit 8e5462bc91
30 files changed
+173 -2664

No files matched your search

+1 -3
View File
@@ -7,10 +7,8 @@ import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart'; import 'package:stadtbote/content_views/utils/header_info.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:badges/badges.dart' as badges; import 'package:badges/badges.dart' as badges;
import 'package:stadtbote/model/accept_job_message.dart'; import 'package:stadtbote/protocoll_messages/accept_job_message.dart';
import 'package:stadtbote/model/payload_container.dart';
import 'package:stadtbote/tools/mqtt_core.dart'; import 'package:stadtbote/tools/mqtt_core.dart';
import 'package:uuid/uuid.dart';
import '../main.dart'; import '../main.dart';
import '../model/job.dart'; import '../model/job.dart';
+1 -1
View File
@@ -85,7 +85,7 @@ class _MainState extends State<Main> {
bool _initCompleted = false; bool _initCompleted = false;
final ValueNotifier<bool> _connectionLostValueNotifier = ValueNotifier<bool>(false); final ValueNotifier<bool> _connectionLostValueNotifier = ValueNotifier<bool>(true);
@override @override
void initState() { void initState() {
-104
View File
@@ -1,104 +0,0 @@
import 'package:isar/isar.dart';
import 'package:stadtbote/model/short_poll_question.dart';
part 'short_poll.g.dart';
@collection
class ShortPoll {
late Id id;
late int type;
late String text;
late String title;
late int validFrom;
late int validTo;
late int? imageWidth;
late int? imageHeight;
late String? imageModified;
late bool? commentsAllowed;
late bool read = false;
late String? url;
late String? pdfName;
late bool voted;
late int numberOfVotes;
late List<ShortPollQuestion> questions;
ShortPoll({
required this.id,
required this.type,
required this.text,
required this.title,
required this.validFrom,
required this.validTo,
this.imageWidth,
this.imageHeight,
this.imageModified,
this.commentsAllowed,
required this.read,
this.url,
this.pdfName,
required this.voted,
required this.numberOfVotes,
required this.questions,
});
/*factory ShortPoll.fromJson(Map<String, dynamic> json) {
List<ShortPollQuestion> questions = [];
if (json["answers"] != null) {
questions = List<ShortPollQuestion>.from(
json["answers"].map((x) => ShortPollQuestion.fromJson(x)));
}
return ShortPoll(
id: json["id"],
type: json["type"],
text: json["text"],
title: json["title"],
validFrom: json["validFrom"],
validTo: json["validTo"],
imageWidth: json["imageWidth"],
imageHeight: json["imageHeight"],
imageModified: json["imageModified"],
commentsAllowed: json["commentsAllowed"],
read: json["read"],
url: json["url"],
pdfName: json["pdfName"],
voted: json["voted"],
numberOfVotes: json["numberOfVotes"],
questions: questions,
);
}
Map<String, dynamic> toJson() => {
"id": id,
"type": type,
"text": text,
"title": title,
"validFrom": validFrom,
"validTo": validTo,
"imageWidth": imageWidth,
"imageHeight": imageHeight,
"imageModified": imageModified,
"commentsAllowed": commentsAllowed,
"read": read,
"url": url,
"pdfName": pdfName,
"voted": voted,
"numberOfVotes": numberOfVotes,
};*/
}
File diff suppressed because it is too large. Load diff
-35
View File
@@ -1,35 +0,0 @@
import 'package:isar/isar.dart';
part 'short_poll_question.g.dart';
@embedded
class ShortPollQuestion {
late int questionId;
late int shortPollId;
late String text;
/*@Ignore()
late String imageName = "assets/radiobutton.png";
@Ignore()
late bool selected = false;*/
ShortPollQuestion();
/*factory ShortPollQuestion.fromJson(Map<String, dynamic> json) {
var shortPollQuestion = ShortPollQuestion();
shortPollQuestion.questionId = json['id'];
shortPollQuestion.shortPollId = json["shortPollId"];
shortPollQuestion.text = json["text"];
return shortPollQuestion;
}
Map<String, dynamic> toJson() => {
"id": questionId,
"short_poll_id": shortPollId,
"text": text,
};*/
}
-342
View File
@@ -1,342 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'short_poll_question.dart';
// **************************************************************************
// IsarEmbeddedGenerator
// **************************************************************************
// coverage:ignore-file
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types
const ShortPollQuestionSchema = Schema(
name: r'ShortPollQuestion',
id: 899576032619711410,
properties: {
r'questionId': PropertySchema(
id: 0,
name: r'questionId',
type: IsarType.long,
),
r'shortPollId': PropertySchema(
id: 1,
name: r'shortPollId',
type: IsarType.long,
),
r'text': PropertySchema(
id: 2,
name: r'text',
type: IsarType.string,
)
},
estimateSize: _shortPollQuestionEstimateSize,
serialize: _shortPollQuestionSerialize,
deserialize: _shortPollQuestionDeserialize,
deserializeProp: _shortPollQuestionDeserializeProp,
);
int _shortPollQuestionEstimateSize(
ShortPollQuestion object,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
var bytesCount = offsets.last;
bytesCount += 3 + object.text.length * 3;
return bytesCount;
}
void _shortPollQuestionSerialize(
ShortPollQuestion object,
IsarWriter writer,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
writer.writeLong(offsets[0], object.questionId);
writer.writeLong(offsets[1], object.shortPollId);
writer.writeString(offsets[2], object.text);
}
ShortPollQuestion _shortPollQuestionDeserialize(
Id id,
IsarReader reader,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
final object = ShortPollQuestion();
object.questionId = reader.readLong(offsets[0]);
object.shortPollId = reader.readLong(offsets[1]);
object.text = reader.readString(offsets[2]);
return object;
}
P _shortPollQuestionDeserializeProp<P>(
IsarReader reader,
int propertyId,
int offset,
Map<Type, List<int>> allOffsets,
) {
switch (propertyId) {
case 0:
return (reader.readLong(offset)) as P;
case 1:
return (reader.readLong(offset)) as P;
case 2:
return (reader.readString(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
}
extension ShortPollQuestionQueryFilter
on QueryBuilder<ShortPollQuestion, ShortPollQuestion, QFilterCondition> {
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
questionIdEqualTo(int value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'questionId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
questionIdGreaterThan(
int value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'questionId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
questionIdLessThan(
int value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'questionId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
questionIdBetween(
int lower,
int upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'questionId',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
shortPollIdEqualTo(int value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'shortPollId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
shortPollIdGreaterThan(
int value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'shortPollId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
shortPollIdLessThan(
int value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'shortPollId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
shortPollIdBetween(
int lower,
int upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'shortPollId',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textEqualTo(
String value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'text',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textGreaterThan(
String value, {
bool include = false,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'text',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textLessThan(
String value, {
bool include = false,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'text',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textBetween(
String lower,
String upper, {
bool includeLower = true,
bool includeUpper = true,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'text',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textStartsWith(
String value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.startsWith(
property: r'text',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textEndsWith(
String value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.endsWith(
property: r'text',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textContains(String value, {bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.contains(
property: r'text',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textMatches(String pattern, {bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.matches(
property: r'text',
wildcard: pattern,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textIsEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'text',
value: '',
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textIsNotEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
property: r'text',
value: '',
));
});
}
}
extension ShortPollQuestionQueryObject
on QueryBuilder<ShortPollQuestion, ShortPollQuestion, QFilterCondition> {}
+1 -1
View File
@@ -4,7 +4,7 @@ import 'package:intl/intl.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:kumi_popup_window/kumi_popup_window.dart'; import 'package:kumi_popup_window/kumi_popup_window.dart';
import 'package:stadtbote/main.dart'; import 'package:stadtbote/main.dart';
import 'package:stadtbote/model/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/tools/constants.dart'; import 'package:stadtbote/tools/constants.dart';
import 'package:stadtbote/tools/mqtt_core.dart'; import 'package:stadtbote/tools/mqtt_core.dart';
@@ -1,5 +1,5 @@
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:stadtbote/model/device_object.dart'; import 'package:stadtbote/protocoll_messages/device_object.dart';
part 'bootstrap_request.g.dart'; part 'bootstrap_request.g.dart';
@@ -1,5 +1,5 @@
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:stadtbote/model/bootstrap_response_topics.dart'; import 'package:stadtbote/protocoll_messages/bootstrap_response_topics.dart';
part 'bootstrap_response_config.g.dart'; part 'bootstrap_response_config.g.dart';
@@ -1,5 +1,5 @@
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:stadtbote/model/bootstrap_response_config.dart'; import 'package:stadtbote/protocoll_messages/bootstrap_response_config.dart';
part 'bootstrap_response_payload.g.dart'; part 'bootstrap_response_payload.g.dart';
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,16 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:stadtbote/tools/util.dart';
part 'job_del_message.g.dart';
@JsonSerializable()
class JobDelMessage {
late List<int> jobDel;
JobDelMessage();
factory JobDelMessage.fromJson(Map<String, dynamic> json) => _$JobDelMessageFromJson(json);
Map<String, dynamic> toJson() => _$JobDelMessageToJson(this);
}
@@ -0,0 +1,17 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'job_del_message.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
JobDelMessage _$JobDelMessageFromJson(Map<String, dynamic> json) =>
JobDelMessage()
..jobDel =
(json['jobDel'] as List<dynamic>).map((e) => e as int).toList();
Map<String, dynamic> _$JobDelMessageToJson(JobDelMessage instance) =>
<String, dynamic>{
'jobDel': instance.jobDel,
};
@@ -0,0 +1,45 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:stadtbote/tools/util.dart';
part 'sync_jobs_message.g.dart';
@JsonSerializable()
class SyncJobsMessage {
late SyncJobMessageSync sync;
SyncJobsMessage();
factory SyncJobsMessage.fromJson(Map<String, dynamic> json) => _$SyncJobsMessageFromJson(json);
Map<String, dynamic> toJson() => _$SyncJobsMessageToJson(this);
}
@JsonSerializable()
class SyncJobMessageSync {
late int utcUnixTime;
late List<SyncJobMessageJob> jobs;
SyncJobMessageSync();
factory SyncJobMessageSync.fromJson(Map<String, dynamic> json) => _$SyncJobMessageSyncFromJson(json);
Map<String, dynamic> toJson() => _$SyncJobMessageSyncToJson(this);
}
@JsonSerializable()
class SyncJobMessageJob {
late int id;
late int ver;
late int state;
SyncJobMessageJob();
factory SyncJobMessageJob.fromJson(Map<String, dynamic> json) => _$SyncJobMessageJobFromJson(json);
Map<String, dynamic> toJson() => _$SyncJobMessageJobToJson(this);
}
@@ -0,0 +1,43 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'sync_jobs_message.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
SyncJobsMessage _$SyncJobsMessageFromJson(Map<String, dynamic> json) =>
SyncJobsMessage()
..sync =
SyncJobMessageSync.fromJson(json['sync'] as Map<String, dynamic>);
Map<String, dynamic> _$SyncJobsMessageToJson(SyncJobsMessage instance) =>
<String, dynamic>{
'sync': instance.sync,
};
SyncJobMessageSync _$SyncJobMessageSyncFromJson(Map<String, dynamic> json) =>
SyncJobMessageSync()
..utcUnixTime = json['utcUnixTime'] as int
..jobs = (json['jobs'] as List<dynamic>)
.map((e) => SyncJobMessageJob.fromJson(e as Map<String, dynamic>))
.toList();
Map<String, dynamic> _$SyncJobMessageSyncToJson(SyncJobMessageSync instance) =>
<String, dynamic>{
'utcUnixTime': instance.utcUnixTime,
'jobs': instance.jobs,
};
SyncJobMessageJob _$SyncJobMessageJobFromJson(Map<String, dynamic> json) =>
SyncJobMessageJob()
..id = json['id'] as int
..ver = json['ver'] as int
..state = json['state'] as int;
Map<String, dynamic> _$SyncJobMessageJobToJson(SyncJobMessageJob instance) =>
<String, dynamic>{
'id': instance.id,
'ver': instance.ver,
'state': instance.state,
};
+1
View File
@@ -8,6 +8,7 @@ class Constants {
static const String messageTopicSessionInfoUpdate = "status_info_updated"; static const String messageTopicSessionInfoUpdate = "status_info_updated";
static const String messageTopicStatusInfoUpdate = "session_info_updated"; static const String messageTopicStatusInfoUpdate = "session_info_updated";
static const String messageTopicJobReceived = "job_received"; static const String messageTopicJobReceived = "job_received";
static const String messageTopicJobDeleted = "job_deleted";
static const String messageTopicMessageReceived = "message_received"; static const String messageTopicMessageReceived = "message_received";
static const String messageTopicPushContentView = "push_content_view"; static const String messageTopicPushContentView = "push_content_view";
static const String messageTopicPopContentView = "pop_content_view"; static const String messageTopicPopContentView = "pop_content_view";
@@ -0,0 +1,7 @@
import 'package:stadtbote/model/job.dart';
class JobDeletedMessage {
final int jobId;
JobDeletedMessage({required this.jobId});
}
+38 -13
View File
@@ -3,16 +3,20 @@ import 'dart:convert';
import 'dart:math'; import 'dart:math';
import 'package:flutter_broadcast_receiver/flutter_broadcast_receiver.dart'; import 'package:flutter_broadcast_receiver/flutter_broadcast_receiver.dart';
import 'package:isar/isar.dart';
import 'package:mqtt_client/mqtt_client.dart'; import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart'; import 'package:mqtt_client/mqtt_server_client.dart';
import 'package:stadtbote/model/bootstrap_request.dart'; import 'package:stadtbote/protocoll_messages/bootstrap_request.dart';
import 'package:stadtbote/model/bootstrap_response_payload.dart'; import 'package:stadtbote/protocoll_messages/bootstrap_response_payload.dart';
import 'package:stadtbote/model/device_object.dart'; import 'package:stadtbote/protocoll_messages/device_object.dart';
import 'package:stadtbote/model/job.dart'; import 'package:stadtbote/model/job.dart';
import 'package:stadtbote/model/message.dart'; import 'package:stadtbote/model/message.dart';
import 'package:stadtbote/model/payload_container.dart'; import 'package:stadtbote/protocoll_messages/job_del_message.dart';
import 'package:stadtbote/model/start_session_message.dart'; import 'package:stadtbote/protocoll_messages/payload_container.dart';
import 'package:stadtbote/protocoll_messages/start_session_message.dart';
import 'package:stadtbote/protocoll_messages/sync_jobs_message.dart';
import 'package:stadtbote/tools/connection_status.dart'; import 'package:stadtbote/tools/connection_status.dart';
import 'package:stadtbote/tools/messages/job_deleted_message.dart';
import 'package:stadtbote/tools/messages/job_received_message.dart'; import 'package:stadtbote/tools/messages/job_received_message.dart';
import 'package:stadtbote/tools/messages/message_message.dart'; import 'package:stadtbote/tools/messages/message_message.dart';
import 'package:stadtbote/tools/messages/session_info_update.dart'; import 'package:stadtbote/tools/messages/session_info_update.dart';
@@ -186,6 +190,8 @@ class MqttCore {
} }
void _sessionMessageReceived(payloadData) async { void _sessionMessageReceived(payloadData) async {
await _sendSyncMessage();
var statusMessage = Status.fromJson(payloadData['status']); var statusMessage = Status.fromJson(payloadData['status']);
await MyApp.isarInstance.writeTxn(() async { await MyApp.isarInstance.writeTxn(() async {
@@ -219,18 +225,18 @@ class MqttCore {
} }
} }
void _jobDeleteReceived(payloadData) async { void _jobDeleteReceived(List<dynamic> payloadData) async {
Util.logInfo('_jobDeleteReceived'); Map<String, dynamic> map = {};
map["jobDel"] = payloadData;
/*for (var foundJobData in payloadData) { var jobDelMessage = JobDelMessage.fromJson(map);
Job newJob = Job.fromJson(foundJobData);
for(var jobId in jobDelMessage.jobDel) {
await MyApp.isarInstance.writeTxn(() async { await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.jobs.put(newJob); await MyApp.isarInstance.jobs.delete(jobId);
}); });
BroadcastReceiver().publish<JobReceivedMessage>(Constants.messageTopicJobReceived, arguments: JobReceivedMessage(job: newJob)); BroadcastReceiver().publish<JobDeletedMessage>(Constants.messageTopicJobDeleted, arguments: JobDeletedMessage(jobId: jobId));
}*/ }
} }
void _syncRequestReceived(payloadData) async { void _syncRequestReceived(payloadData) async {
@@ -335,4 +341,23 @@ class MqttCore {
var messageId = _mqttClient.publishMessage(topic, MqttQos.exactlyOnce, payload!); var messageId = _mqttClient.publishMessage(topic, MqttQos.exactlyOnce, payload!);
Util.logInfo("send start session json with messageId: $messageId"); Util.logInfo("send start session json with messageId: $messageId");
} }
_sendSyncMessage() async
{
var jobs = await MyApp.isarInstance.jobs.filter().stateGreaterThan(-1).findAll();
var answer = SyncJobsMessage();
answer.sync = SyncJobMessageSync();
answer.sync.jobs = [];
answer.sync.utcUnixTime = DateTime.now().toUtc().millisecondsSinceEpoch ~/ 1000;
for (var job in jobs) {
SyncJobMessageJob syncJob = SyncJobMessageJob();
syncJob.state = job.state;
syncJob.id = job.id;
syncJob.ver = job.ver;
answer.sync.jobs.add(syncJob);
}
MqttCore.instance.publishPayloadMessage("server", answer.toJson());
}
} }