From c69a5644a1c00174983b5d5e645ee8a5de888e94 Mon Sep 17 00:00:00 2001 From: Sven Carstensen Date: Thu, 8 Feb 2024 14:30:30 +0100 Subject: [PATCH] Erweiterungen --- lib/content_views/main_page.dart | 8 +++ lib/content_views/messages_page.dart | 17 +++-- lib/model/message.dart | 22 +++++++ lib/model/message.g.dart | 97 ++++++++++++++++++++++++---- lib/tools/mqtt_core.dart | 2 +- 5 files changed, 128 insertions(+), 18 deletions(-) diff --git a/lib/content_views/main_page.dart b/lib/content_views/main_page.dart index cb108c6..d600b25 100644 --- a/lib/content_views/main_page.dart +++ b/lib/content_views/main_page.dart @@ -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'; @@ -8,11 +9,13 @@ import 'package:stadtbote/content_views/messages_page.dart'; import 'package:stadtbote/content_views/utils/content_view_widget.dart'; import 'package:stadtbote/content_views/utils/header_info.dart'; import 'package:stadtbote/model/job.dart'; +import 'package:stadtbote/model/message.dart'; import 'package:stadtbote/model/status.dart'; import 'package:stadtbote/popups/accept_jobs_popup.dart'; import 'package:stadtbote/popups/infos_popup.dart'; import 'package:stadtbote/tools/message_service.dart'; import 'package:stadtbote/tools/messages/job_received_message.dart'; +import 'package:stadtbote/tools/messages/message_message.dart'; import 'package:stadtbote/tools/messages/session_info_update.dart'; import 'package:badges/badges.dart' as badges; @@ -243,6 +246,10 @@ class _MainPageState extends State { MessageService().subscribe(Constants.messageTopicJobReceived, this, (JobReceivedMessage jobReceivedMessage) { _jobReceived(jobReceivedMessage.job); }); + + MessageService().subscribe(Constants.messageTopicMessageReceived, this, (MessageReceivedMessage mesage) { + _refreshBadges(); + }); } void _exitMessages() { @@ -254,6 +261,7 @@ class _MainPageState extends State { void _refreshBadges() async { _assignedJobsValueNotifier.value = await MyApp.isarInstance.jobs.filter().stateEqualTo(0).count(); _acceptedJobsValueNotifier.value = await MyApp.isarInstance.jobs.filter().stateEqualTo(1).count(); + _messagesValueNotifier.value = await MyApp.isarInstance.messages.filter().readEqualTo(false).count(); } void _jobReceived(Job job) { diff --git a/lib/content_views/messages_page.dart b/lib/content_views/messages_page.dart index 4de35b3..4a227ab 100644 --- a/lib/content_views/messages_page.dart +++ b/lib/content_views/messages_page.dart @@ -90,11 +90,15 @@ class _MessagesPageState extends State { } void _handleSendPressed(types.PartialText text) async { + var now = DateTime.now(); + var message = sbmessage.Message(); message.text = [text.text]; message.from = _sid; message.subj = ''; - message.time = DateFormat("yyyy.mm.dd HH:mm").format(DateTime.now()); + message.time = now.toIso8601String(); + message.read = true; + message.id = await sbmessage.Message.getNextId(); MyApp.isarInstance.writeTxnSync(() { @@ -105,7 +109,7 @@ class _MessagesPageState extends State { _messages.insert(0, types.TextMessage( author: _user, - createdAt: DateTime.now().millisecondsSinceEpoch, + createdAt: now.millisecondsSinceEpoch, id: const Uuid().v4().toString(), text: text.text, )); @@ -125,14 +129,17 @@ class _MessagesPageState extends State { _messages.insert(0, types.TextMessage( author: message.from == _sid ? _user : _central, - createdAt: DateTime.now().millisecondsSinceEpoch, + createdAt: DateTime.parse(message.time).millisecondsSinceEpoch, id: const Uuid().v4().toString(), text: text, )); - setState(() {}); + message.read = true; + MyApp.isarInstance.writeTxnSync(() { + MyApp.isarInstance.messages.putSync(message); + }); } - Util.logInfo(''); + setState(() {}); } } diff --git a/lib/model/message.dart b/lib/model/message.dart index 67d26f1..20500aa 100644 --- a/lib/model/message.dart +++ b/lib/model/message.dart @@ -1,5 +1,6 @@ import 'package:isar/isar.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:stadtbote/main.dart'; import 'package:stadtbote/tools/util.dart'; part 'message.g.dart'; @@ -17,12 +18,33 @@ class Message { late List text; + late bool? read = false; + Message(); factory Message.fromJson(Map json) => _$MessageFromJson(json); Map toJson() => _$MessageToJson(this); + static Future mergeFromJson(Map json) async { + var availableMessage = await MyApp.isarInstance.messages.filter().idEqualTo(json["id"]).findFirst(); + + if (availableMessage != null) { + availableMessage.id = json["id"]; + availableMessage.time = json["time"]; + availableMessage.from = json["from"]; + availableMessage.subj = json["subj"]; + availableMessage.text = (json['text'] as List).map((e) => e as String).toList(); + + return availableMessage; + } else { + var message = Message.fromJson(json); + message.read = false; + + return message; + } + } + static Future getNextId() async { int currentExport500Id = await Util.preferencesGetInt('next_message_id', 0) as int; diff --git a/lib/model/message.g.dart b/lib/model/message.g.dart index c5b5b5a..4a485f7 100644 --- a/lib/model/message.g.dart +++ b/lib/model/message.g.dart @@ -22,18 +22,23 @@ const MessageSchema = CollectionSchema( name: r'from', type: IsarType.string, ), - r'subj': PropertySchema( + r'read': PropertySchema( id: 1, + name: r'read', + type: IsarType.bool, + ), + r'subj': PropertySchema( + id: 2, name: r'subj', type: IsarType.string, ), r'text': PropertySchema( - id: 2, + id: 3, name: r'text', type: IsarType.stringList, ), r'time': PropertySchema( - id: 3, + id: 4, name: r'time', type: IsarType.string, ) @@ -78,9 +83,10 @@ void _messageSerialize( Map> allOffsets, ) { writer.writeString(offsets[0], object.from); - writer.writeString(offsets[1], object.subj); - writer.writeStringList(offsets[2], object.text); - writer.writeString(offsets[3], object.time); + writer.writeBool(offsets[1], object.read); + writer.writeString(offsets[2], object.subj); + writer.writeStringList(offsets[3], object.text); + writer.writeString(offsets[4], object.time); } Message _messageDeserialize( @@ -92,9 +98,10 @@ Message _messageDeserialize( final object = Message(); object.from = reader.readString(offsets[0]); object.id = id; - object.subj = reader.readString(offsets[1]); - object.text = reader.readStringList(offsets[2]) ?? []; - object.time = reader.readString(offsets[3]); + object.read = reader.readBoolOrNull(offsets[1]); + object.subj = reader.readString(offsets[2]); + object.text = reader.readStringList(offsets[3]) ?? []; + object.time = reader.readString(offsets[4]); return object; } @@ -108,10 +115,12 @@ P _messageDeserializeProp

( case 0: return (reader.readString(offset)) as P; case 1: - return (reader.readString(offset)) as P; + return (reader.readBoolOrNull(offset)) as P; case 2: - return (reader.readStringList(offset) ?? []) as P; + return (reader.readString(offset)) as P; case 3: + return (reader.readStringList(offset) ?? []) as P; + case 4: return (reader.readString(offset)) as P; default: throw IsarError('Unknown property with id $propertyId'); @@ -389,6 +398,32 @@ extension MessageQueryFilter }); } + QueryBuilder readIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'read', + )); + }); + } + + QueryBuilder readIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'read', + )); + }); + } + + QueryBuilder readEqualTo( + bool? value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'read', + value: value, + )); + }); + } + QueryBuilder subjEqualTo( String value, { bool caseSensitive = true, @@ -884,6 +919,18 @@ extension MessageQuerySortBy on QueryBuilder { }); } + QueryBuilder sortByRead() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'read', Sort.asc); + }); + } + + QueryBuilder sortByReadDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'read', Sort.desc); + }); + } + QueryBuilder sortBySubj() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'subj', Sort.asc); @@ -935,6 +982,18 @@ extension MessageQuerySortThenBy }); } + QueryBuilder thenByRead() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'read', Sort.asc); + }); + } + + QueryBuilder thenByReadDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'read', Sort.desc); + }); + } + QueryBuilder thenBySubj() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'subj', Sort.asc); @@ -969,6 +1028,12 @@ extension MessageQueryWhereDistinct }); } + QueryBuilder distinctByRead() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'read'); + }); + } + QueryBuilder distinctBySubj( {bool caseSensitive = true}) { return QueryBuilder.apply(this, (query) { @@ -1004,6 +1069,12 @@ extension MessageQueryProperty }); } + QueryBuilder readProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'read'); + }); + } + QueryBuilder subjProperty() { return QueryBuilder.apply(this, (query) { return query.addPropertyName(r'subj'); @@ -1032,7 +1103,8 @@ Message _$MessageFromJson(Map json) => Message() ..time = json['time'] as String ..from = json['from'] as String ..subj = json['subj'] as String - ..text = (json['text'] as List).map((e) => e as String).toList(); + ..text = (json['text'] as List).map((e) => e as String).toList() + ..read = json['read'] as bool?; Map _$MessageToJson(Message instance) => { 'id': instance.id, @@ -1040,4 +1112,5 @@ Map _$MessageToJson(Message instance) => { 'from': instance.from, 'subj': instance.subj, 'text': instance.text, + 'read': instance.read, }; diff --git a/lib/tools/mqtt_core.dart b/lib/tools/mqtt_core.dart index 8a26220..fc7d3d9 100644 --- a/lib/tools/mqtt_core.dart +++ b/lib/tools/mqtt_core.dart @@ -271,7 +271,7 @@ class MqttCore { } void _messageMessageReceived(Map payloadData) async { - var newMessage = Message.fromJson(payloadData); + var newMessage = await Message.mergeFromJson(payloadData); await MyApp.isarInstance.writeTxn(() async { await MyApp.isarInstance.messages.put(newMessage);