From 62a4ea785a6a33f9c9bc7a5441f1961babf21104 Mon Sep 17 00:00:00 2001 From: Gabby Gurdin Date: Wed, 27 Mar 2024 12:26:15 -0400 Subject: [PATCH] remove former version of editted messages from analytics --- assets/l10n/intl_en.arb | 3 +- lib/pages/chat/chat.dart | 2 + .../controllers/my_analytics_controller.dart | 13 +++--- lib/pangea/extensions/client_extension.dart | 27 +++++++++++++ .../extensions/pangea_room_extension.dart | 31 ++++++++++++-- .../models/construct_analytics_event.dart | 21 +++++++++- .../models/student_analytics_event.dart | 40 ++++++++++++++++--- .../student_analytics_summary_model.dart | 9 ++++- .../student_analytics/student_analytics.dart | 4 -- 9 files changed, 128 insertions(+), 22 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 0783205a6..3d1fe90cb 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3952,5 +3952,6 @@ "joinToView": "Join this room to view details", "refresh": "Refresh", "autoPlayTitle": "Auto Play Messages", - "autoPlayDesc": "When enabled, the text-to-speech audio of messages will play automatically when selected." + "autoPlayDesc": "When enabled, the text-to-speech audio of messages will play automatically when selected.", + "messageAnalytics": "Message Analytics" } \ No newline at end of file diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 0d2e180a7..52c7bdcc7 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -628,6 +628,7 @@ class ChatController extends State useType: useType ?? UseType.un, time: DateTime.now(), ), + isEdit: previousEdit != null, ); if (choreo != null && @@ -641,6 +642,7 @@ class ChatController extends State ...choreo.toGrammarConstructUse(msgEventId, room.id), ], originalSent!.langCode, + isEdit: previousEdit != null, ); } }, diff --git a/lib/pangea/controllers/my_analytics_controller.dart b/lib/pangea/controllers/my_analytics_controller.dart index a33748fda..deafd8f2a 100644 --- a/lib/pangea/controllers/my_analytics_controller.dart +++ b/lib/pangea/controllers/my_analytics_controller.dart @@ -24,8 +24,9 @@ class MyAnalyticsController { //PTODO - locally cache and update periodically Future handleMessage( Room room, - RecentMessageRecord messageRecord, - ) async { + RecentMessageRecord messageRecord, { + bool isEdit = false, + }) async { try { debugPrint("in handle message with type ${messageRecord.useType}"); if (_userId == null) { @@ -48,7 +49,7 @@ class MyAnalyticsController { for (final event in events) { if (event != null) { - event.handleNewMessage(messageRecord); + event.handleNewMessage(messageRecord, isEdit: isEdit); } } } catch (err) { @@ -76,8 +77,9 @@ class MyAnalyticsController { Future saveConstructsMixed( List allUses, - String langCode, - ) async { + String langCode, { + bool isEdit = false, + }) async { try { final Map> aggregatedVocabUse = {}; for (final use in allUses) { @@ -96,6 +98,7 @@ class MyAnalyticsController { uses.key, uses.value.first.constructType!, uses.value, + isEdit: isEdit, ), ); } diff --git a/lib/pangea/extensions/client_extension.dart b/lib/pangea/extensions/client_extension.dart index f5a32c95e..973ece6b3 100644 --- a/lib/pangea/extensions/client_extension.dart +++ b/lib/pangea/extensions/client_extension.dart @@ -212,4 +212,31 @@ extension PangeaClient on Client { } return false; } + + Future> getEditHistory( + String roomId, + String eventId, + ) async { + final Room? room = getRoomById(roomId); + final Event? editEvent = await room?.getEventById(eventId); + final String? edittedEventId = + editEvent?.content.tryGetMap('m.relates_to')?['event_id']; + if (edittedEventId == null) return []; + + final Event? originalEvent = await room!.getEventById(edittedEventId); + if (originalEvent == null) return []; + + final Timeline timeline = await room.getTimeline(); + final List editEvents = originalEvent + .aggregatedEvents( + timeline, + RelationshipTypes.edit, + ) + .sorted( + (a, b) => b.originServerTs.compareTo(a.originServerTs), + ) + .toList(); + editEvents.add(originalEvent); + return editEvents.slice(1).map((e) => e.eventId).toList(); + } } diff --git a/lib/pangea/extensions/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension.dart index e617247de..7af3d6233 100644 --- a/lib/pangea/extensions/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension.dart @@ -692,16 +692,39 @@ extension PangeaRoom on Room { } } + Future> removeEdittedLemmas( + List lemmaUses, + ) async { + final List removeUses = []; + for (final use in lemmaUses) { + if (use.msgId == null) continue; + final List removeIds = await client.getEditHistory( + use.chatId, + use.msgId!, + ); + removeUses.addAll(removeIds); + } + lemmaUses.removeWhere((use) => removeUses.contains(use.msgId)); + final allEvents = await allConstructEvents; + for (final constructEvent in allEvents) { + await constructEvent.removeEdittedUses(removeUses, client); + } + return lemmaUses; + } + Future saveConstructUsesSameLemma( String lemma, ConstructType type, - List lemmaUses, - ) async { + List lemmaUses, { + bool isEdit = false, + }) async { final ConstructEvent? localEvent = _vocabEventLocal(lemma); + if (isEdit) { + lemmaUses = await removeEdittedLemmas(lemmaUses); + } + if (localEvent == null) { - final json = - ConstructUses(lemma: lemma, type: type, uses: lemmaUses).toJson(); await client.setRoomStateWithKey( id, PangeaEventTypes.vocab, diff --git a/lib/pangea/models/construct_analytics_event.dart b/lib/pangea/models/construct_analytics_event.dart index 66921b8a2..a97950cdd 100644 --- a/lib/pangea/models/construct_analytics_event.dart +++ b/lib/pangea/models/construct_analytics_event.dart @@ -1,6 +1,6 @@ +import 'package:fluffychat/pangea/models/constructs_analytics_model.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/pangea/models/constructs_analytics_model.dart'; import '../constants/pangea_event_types.dart'; class ConstructEvent { @@ -30,4 +30,23 @@ class ConstructEvent { content.uses.addAll(uses); event.content = content.toJson(); } + + Future removeEdittedUses( + List removeIds, + Client client, + ) async { + _contentCache ??= ConstructUses.fromJson(event.content); + final previousLength = _contentCache!.uses.length; + _contentCache!.uses.removeWhere( + (element) => removeIds.contains(element.msgId), + ); + if (previousLength > _contentCache!.uses.length) { + await client.setRoomStateWithKey( + _event.room.id, + _event.type, + _event.stateKey!, + _contentCache!.toJson(), + ); + } + } } diff --git a/lib/pangea/models/student_analytics_event.dart b/lib/pangea/models/student_analytics_event.dart index 738014bb8..1884b43b4 100644 --- a/lib/pangea/models/student_analytics_event.dart +++ b/lib/pangea/models/student_analytics_event.dart @@ -1,12 +1,12 @@ import 'dart:developer'; -import 'package:flutter/foundation.dart'; - -import 'package:matrix/matrix.dart'; - import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/extensions/client_extension.dart'; import 'package:fluffychat/pangea/models/student_analytics_summary_model.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:flutter/foundation.dart'; +import 'package:matrix/matrix.dart'; + import '../constants/pangea_event_types.dart'; import 'chart_analytics_model.dart'; @@ -41,8 +41,27 @@ class StudentAnalyticsEvent { return _contentCache!; } - Future handleNewMessage(RecentMessageRecord message) async { - debugPrint("handle new message"); + Future removeEdittedMessages( + RecentMessageRecord message, + ) async { + final List removeIds = await classRoom.client.getEditHistory( + message.chatId, + message.eventId, + ); + if (removeIds.isEmpty) return; + _messagesToSave.removeWhere( + (msg) => removeIds.any((e) => e == msg.eventId), + ); + content.removeEdittedMessages( + classRoom.client, + removeIds, + ); + } + + Future handleNewMessage( + RecentMessageRecord message, { + isEdit = false, + }) async { if (classRoom.client.userID != _event.stateKey) { debugger(when: kDebugMode); ErrorHandler.logError( @@ -50,6 +69,10 @@ class StudentAnalyticsEvent { ); return; } + + if (isEdit) { + await removeEdittedMessages(message); + } _addMessage(message); if (DateTime.now().difference(content.lastUpdated).inMinutes > @@ -66,6 +89,10 @@ class StudentAnalyticsEvent { ); return; } + for (final message in messages) { + await removeEdittedMessages(message); + } + _messagesToSave.addAll(messages); _updateStudentAnalytics(); } @@ -75,6 +102,7 @@ class StudentAnalyticsEvent { content.addAll(_messagesToSave); debugPrint("updating student analytics"); _clearMessages(); + await classRoom.client.setRoomStateWithKey( classRoom.id, _event.type, diff --git a/lib/pangea/models/student_analytics_summary_model.dart b/lib/pangea/models/student_analytics_summary_model.dart index 682768b28..69d237ea9 100644 --- a/lib/pangea/models/student_analytics_summary_model.dart +++ b/lib/pangea/models/student_analytics_summary_model.dart @@ -1,8 +1,9 @@ import 'dart:convert'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:flutter/foundation.dart'; +import 'package:matrix/matrix.dart'; -import 'package:fluffychat/pangea/utils/error_handler.dart'; import '../enum/use_type.dart'; class RecentMessageRecord { @@ -78,6 +79,12 @@ class StudentAnalyticsSummary { } } + void removeEdittedMessages(Client client, List removeEventIds) { + _messages.removeWhere( + (element) => removeEventIds.contains(element.eventId), + ); + } + List get messages => _messages; static const _messagesKey = "msgs"; diff --git a/lib/pangea/pages/analytics/student_analytics/student_analytics.dart b/lib/pangea/pages/analytics/student_analytics/student_analytics.dart index fe0e79629..44843bd41 100644 --- a/lib/pangea/pages/analytics/student_analytics/student_analytics.dart +++ b/lib/pangea/pages/analytics/student_analytics/student_analytics.dart @@ -49,10 +49,6 @@ class StudentAnalyticsController extends State { } Future initialize() async { - await _pangeaController.matrixState.client - .updateMyLearningAnalyticsForAllClassesImIn( - _pangeaController.pStoreService, - ); await getClassAndChatAnalytics(context); stateSub = _pangeaController.matrixState.client.onRoomState.stream .where(