From 4070fc81a6cf457361e77255e0226032ec9a1ad4 Mon Sep 17 00:00:00 2001 From: Sven Carstensen Date: Wed, 28 Feb 2024 20:42:22 +0100 Subject: [PATCH] Fehlerkorrekturen --- lib/content_views/messages_page.dart | 4 +- lib/content_views/task_list_page.dart | 17 +- lib/main.dart | 4 +- lib/model/enqueued_message.dart | 14 + lib/model/enqueued_message.g.dart | 633 ++++++++++++++++++++++++++ lib/tools/mqtt_core.dart | 60 ++- 6 files changed, 706 insertions(+), 26 deletions(-) create mode 100644 lib/model/enqueued_message.dart create mode 100644 lib/model/enqueued_message.g.dart diff --git a/lib/content_views/messages_page.dart b/lib/content_views/messages_page.dart index fe1f225..03b3e76 100644 --- a/lib/content_views/messages_page.dart +++ b/lib/content_views/messages_page.dart @@ -130,7 +130,7 @@ class _MessagesPageState extends State { } text = text.trim(); - _messages.insert(0, types.TextMessage( + _messages.add(types.TextMessage( author: message.from == _sid ? _user : _central, createdAt: DateTime .parse(message.time) @@ -139,6 +139,8 @@ class _MessagesPageState extends State { text: text, )); + _messages.sort((a, b) => b.createdAt! > a.createdAt! ? 1 : 0); + message.read = true; MyApp.isarInstance.writeTxnSync(() { MyApp.isarInstance.messages.putSync(message); diff --git a/lib/content_views/task_list_page.dart b/lib/content_views/task_list_page.dart index 2f11aeb..603bb4d 100644 --- a/lib/content_views/task_list_page.dart +++ b/lib/content_views/task_list_page.dart @@ -163,12 +163,16 @@ class _TaskListPageState extends State { ), ), const SizedBox(height: 5), - Text( - taskInfo.additionalText ?? '', - textAlign: TextAlign.left, - style: TextStyle( - color: textColor, - fontSize: 12.0, + SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + child: Text( + taskInfo.additionalText ?? '', + textAlign: TextAlign.left, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: textColor, + fontSize: 12.0, + ), ), ), ], @@ -317,6 +321,7 @@ class _TaskListPageState extends State { answer.val = notice; taskInfo.answer = jsonEncode(answer.toJson()); + taskInfo.additionalText = notice; taskInfo.completed = true; _finishTaskProcessing(taskInfo); diff --git a/lib/main.dart b/lib/main.dart index 4f411b2..74db0b9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,6 +5,7 @@ import 'package:geolocator/geolocator.dart'; import 'package:isar/isar.dart'; import 'package:path_provider/path_provider.dart'; import 'package:stadtbote/messages/pop_content_view_message.dart'; +import 'package:stadtbote/model/enqueued_message.dart'; import 'package:stadtbote/model/message.dart'; import 'package:stadtbote/model/ranking.dart'; import 'package:stadtbote/model/status.dart'; @@ -34,7 +35,8 @@ Future main() async { JobSchema, TaskInfoSchema, MessageSchema, - RankingSchema + RankingSchema, + EnqueuedMessageSchema, ], directory: dir.path); runZonedGuarded(() {}, (error, stackTrace) { diff --git a/lib/model/enqueued_message.dart b/lib/model/enqueued_message.dart new file mode 100644 index 0000000..6cd3b34 --- /dev/null +++ b/lib/model/enqueued_message.dart @@ -0,0 +1,14 @@ +import 'package:isar/isar.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'enqueued_message.g.dart'; + +@collection +class EnqueuedMessage { + Id id = DateTime.now().millisecondsSinceEpoch; + + late String topic; + + late String payload; +} + diff --git a/lib/model/enqueued_message.g.dart b/lib/model/enqueued_message.g.dart new file mode 100644 index 0000000..41c3d7a --- /dev/null +++ b/lib/model/enqueued_message.g.dart @@ -0,0 +1,633 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'enqueued_message.dart'; + +// ************************************************************************** +// IsarCollectionGenerator +// ************************************************************************** + +// 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 + +extension GetEnqueuedMessageCollection on Isar { + IsarCollection get enqueuedMessages => this.collection(); +} + +const EnqueuedMessageSchema = CollectionSchema( + name: r'EnqueuedMessage', + id: 884922652682878785, + properties: { + r'payload': PropertySchema( + id: 0, + name: r'payload', + type: IsarType.string, + ), + r'receiver': PropertySchema( + id: 1, + name: r'receiver', + type: IsarType.string, + ) + }, + estimateSize: _enqueuedMessageEstimateSize, + serialize: _enqueuedMessageSerialize, + deserialize: _enqueuedMessageDeserialize, + deserializeProp: _enqueuedMessageDeserializeProp, + idName: r'id', + indexes: {}, + links: {}, + embeddedSchemas: {}, + getId: _enqueuedMessageGetId, + getLinks: _enqueuedMessageGetLinks, + attach: _enqueuedMessageAttach, + version: '3.1.0+1', +); + +int _enqueuedMessageEstimateSize( + EnqueuedMessage object, + List offsets, + Map> allOffsets, +) { + var bytesCount = offsets.last; + bytesCount += 3 + object.payload.length * 3; + bytesCount += 3 + object.topic.length * 3; + return bytesCount; +} + +void _enqueuedMessageSerialize( + EnqueuedMessage object, + IsarWriter writer, + List offsets, + Map> allOffsets, +) { + writer.writeString(offsets[0], object.payload); + writer.writeString(offsets[1], object.topic); +} + +EnqueuedMessage _enqueuedMessageDeserialize( + Id id, + IsarReader reader, + List offsets, + Map> allOffsets, +) { + final object = EnqueuedMessage(); + object.id = id; + object.payload = reader.readString(offsets[0]); + object.topic = reader.readString(offsets[1]); + return object; +} + +P _enqueuedMessageDeserializeProp

( + IsarReader reader, + int propertyId, + int offset, + Map> allOffsets, +) { + switch (propertyId) { + case 0: + return (reader.readString(offset)) as P; + case 1: + return (reader.readString(offset)) as P; + default: + throw IsarError('Unknown property with id $propertyId'); + } +} + +Id _enqueuedMessageGetId(EnqueuedMessage object) { + return object.id; +} + +List> _enqueuedMessageGetLinks(EnqueuedMessage object) { + return []; +} + +void _enqueuedMessageAttach( + IsarCollection col, Id id, EnqueuedMessage object) { + object.id = id; +} + +extension EnqueuedMessageQueryWhereSort + on QueryBuilder { + QueryBuilder anyId() { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(const IdWhereClause.any()); + }); + } +} + +extension EnqueuedMessageQueryWhere + on QueryBuilder { + QueryBuilder idEqualTo( + Id id) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IdWhereClause.between( + lower: id, + upper: id, + )); + }); + } + + QueryBuilder + idNotEqualTo(Id id) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: false), + ) + .addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: false), + ); + } else { + return query + .addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: false), + ) + .addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: false), + ); + } + }); + } + + QueryBuilder + idGreaterThan(Id id, {bool include = false}) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: include), + ); + }); + } + + QueryBuilder idLessThan( + Id id, + {bool include = false}) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: include), + ); + }); + } + + QueryBuilder idBetween( + Id lowerId, + Id upperId, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IdWhereClause.between( + lower: lowerId, + includeLower: includeLower, + upper: upperId, + includeUpper: includeUpper, + )); + }); + } +} + +extension EnqueuedMessageQueryFilter + on QueryBuilder { + QueryBuilder + idEqualTo(Id value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'id', + value: value, + )); + }); + } + + QueryBuilder + idGreaterThan( + Id value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'id', + value: value, + )); + }); + } + + QueryBuilder + idLessThan( + Id value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'id', + value: value, + )); + }); + } + + QueryBuilder + idBetween( + Id lower, + Id upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'id', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder + payloadEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'payload', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + payloadGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'payload', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + payloadLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'payload', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + payloadBetween( + 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'payload', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + payloadStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'payload', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + payloadEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'payload', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + payloadContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'payload', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + payloadMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'payload', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + payloadIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'payload', + value: '', + )); + }); + } + + QueryBuilder + payloadIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'payload', + value: '', + )); + }); + } + + QueryBuilder + receiverEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'receiver', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + receiverGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'receiver', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + receiverLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'receiver', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + receiverBetween( + 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'receiver', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + receiverStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'receiver', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + receiverEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'receiver', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + receiverContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'receiver', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + receiverMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'receiver', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + receiverIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'receiver', + value: '', + )); + }); + } + + QueryBuilder + receiverIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'receiver', + value: '', + )); + }); + } +} + +extension EnqueuedMessageQueryObject + on QueryBuilder {} + +extension EnqueuedMessageQueryLinks + on QueryBuilder {} + +extension EnqueuedMessageQuerySortBy + on QueryBuilder { + QueryBuilder sortByPayload() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'payload', Sort.asc); + }); + } + + QueryBuilder + sortByPayloadDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'payload', Sort.desc); + }); + } + + QueryBuilder + sortByReceiver() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'receiver', Sort.asc); + }); + } + + QueryBuilder + sortByReceiverDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'receiver', Sort.desc); + }); + } +} + +extension EnqueuedMessageQuerySortThenBy + on QueryBuilder { + QueryBuilder thenById() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'id', Sort.asc); + }); + } + + QueryBuilder thenByIdDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'id', Sort.desc); + }); + } + + QueryBuilder thenByPayload() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'payload', Sort.asc); + }); + } + + QueryBuilder + thenByPayloadDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'payload', Sort.desc); + }); + } + + QueryBuilder + thenByReceiver() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'receiver', Sort.asc); + }); + } + + QueryBuilder + thenByReceiverDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'receiver', Sort.desc); + }); + } +} + +extension EnqueuedMessageQueryWhereDistinct + on QueryBuilder { + QueryBuilder distinctByPayload( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'payload', caseSensitive: caseSensitive); + }); + } + + QueryBuilder distinctByReceiver( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'receiver', caseSensitive: caseSensitive); + }); + } +} + +extension EnqueuedMessageQueryProperty + on QueryBuilder { + QueryBuilder idProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'id'); + }); + } + + QueryBuilder payloadProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'payload'); + }); + } + + QueryBuilder receiverProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'receiver'); + }); + } +} diff --git a/lib/tools/mqtt_core.dart b/lib/tools/mqtt_core.dart index 957daf3..a5aa718 100644 --- a/lib/tools/mqtt_core.dart +++ b/lib/tools/mqtt_core.dart @@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart'; import 'package:isar/isar.dart'; import 'package:mqtt_client/mqtt_client.dart'; import 'package:mqtt_client/mqtt_server_client.dart'; +import 'package:stadtbote/model/enqueued_message.dart'; import 'package:stadtbote/model/ranking.dart'; import 'package:stadtbote/model/status.dart'; import 'package:stadtbote/protocoll_messages/bootstrap_request.dart'; @@ -131,31 +132,27 @@ class MqttCore { } publishText(String topic, String text) { - try { - var buffer = Uint8Buffer(); - buffer.addAll(text.codeUnits); + var buffer = Uint8Buffer(); + buffer.addAll(text.codeUnits); - _mqttClient.publishMessage(topic, MqttQos.exactlyOnce, buffer); + _mqttClient.publishMessage(topic, MqttQos.exactlyOnce, buffer); - Util.logInfo("message $text send to $topic"); - } catch (e) { - Util.logException(e.toString()); - } + Util.logInfo("message $text send to $topic"); } - publishPayloadMessage(String receiver, Map payload) { + publishPayloadMessage(String topic, Map payload) { + var payloadContainer = PayloadContainer(); + payloadContainer.id = const Uuid().v4().toString(); + payloadContainer.recv = topic; + payloadContainer.store = true; + payloadContainer.payload = payload; + + var json = jsonEncode(payloadContainer.toJson()); + try { - var payloadContainer = PayloadContainer(); - payloadContainer.id = const Uuid().v4().toString(); - payloadContainer.recv = receiver; - payloadContainer.store = true; - payloadContainer.payload = payload; - - var json = jsonEncode(payloadContainer.toJson()); - publishText(_toServerTopic, json); } catch (e) { - Util.logException(e.toString()); + _enqueueMessage(topic, jsonEncode(payloadContainer.toJson())); } } @@ -234,6 +231,8 @@ class MqttCore { await _sendSyncMessage(); + await _sendEnqueuedMessages(); + var sessionStatusMessage = SessionStatus.fromJson(payloadData['status']); await MyApp.isarInstance.writeTxn(() async { @@ -457,4 +456,29 @@ class MqttCore { _trackTimer = null; } } + + void _enqueueMessage(String receiver, String payload) async { + var enqueuedMessage = EnqueuedMessage(); + enqueuedMessage.topic = receiver; + enqueuedMessage.payload = payload; + + await MyApp.isarInstance.writeTxn(() async { + await MyApp.isarInstance.enqueuedMessages.put(enqueuedMessage); + }); + } + + _sendEnqueuedMessages() async { + var enqueuedMessages = await MyApp.isarInstance.enqueuedMessages.where().findAll(); + if (enqueuedMessages.isNotEmpty) { + for (var enqueuedMessage in enqueuedMessages) { + try { + publishText(enqueuedMessage.topic, enqueuedMessage.payload); + + await MyApp.isarInstance.writeTxn(() async { + await MyApp.isarInstance.enqueuedMessages.delete(enqueuedMessage.id); + }); + } catch (ex) {} + } + } + } }