From 4d58b66bf1ba28affbe261e01ce2a61b30ea6f9a Mon Sep 17 00:00:00 2001 From: ggurdin Date: Thu, 4 Dec 2025 12:59:17 -0500 Subject: [PATCH] feat: initial work for deleting lemmas from analytics --- lib/l10n/intl_en.arb | 3 +- lib/pages/chat/chat.dart | 26 +-- .../analytics_misc/construct_list_model.dart | 8 + .../get_analytics_controller.dart | 19 +- .../lemma_emoji_setter_mixin.dart | 41 ++-- .../put_analytics_controller.dart | 221 +++--------------- lib/pangea/analytics_page/analytics_page.dart | 38 ++- .../analytics_settings_extension.dart | 46 ++++ .../analytics_settings_model.dart | 34 +++ .../events/constants/pangea_event_types.dart | 2 + .../widgets/message_selection_overlay.dart | 40 ++-- .../toolbar/widgets/practice_controller.dart | 43 ++-- lib/utils/client_manager.dart | 1 + 13 files changed, 243 insertions(+), 279 deletions(-) create mode 100644 lib/pangea/analytics_settings/analytics_settings_extension.dart create mode 100644 lib/pangea/analytics_settings/analytics_settings_model.dart diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index b7e3482fd..0f3be7536 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -4990,5 +4990,6 @@ } }, "pickDifferentActivity": "Pick a different activity", - "messageLanguageMismatchMessage": "Your target language doesn't match this message. Update your target language?" + "messageLanguageMismatchMessage": "Your target language doesn't match this message. Update your target language?", + "blockLemmaConfirmation": "This vocab word will be permanently removed from your analytics" } diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 4bc911fa8..90cfaad2b 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -36,7 +36,6 @@ import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; import 'package:fluffychat/pangea/analytics_misc/get_analytics_controller.dart'; import 'package:fluffychat/pangea/analytics_misc/level_up/level_up_banner.dart'; import 'package:fluffychat/pangea/analytics_misc/message_analytics_feedback.dart'; -import 'package:fluffychat/pangea/analytics_misc/put_analytics_controller.dart'; import 'package:fluffychat/pangea/bot/utils/bot_name.dart'; import 'package:fluffychat/pangea/chat/utils/unlocked_morphs_snackbar.dart'; import 'package:fluffychat/pangea/chat/widgets/event_too_large_dialog.dart'; @@ -2106,14 +2105,11 @@ class ChatController extends State ]; _showAnalyticsFeedback(constructs, eventId); - - pangeaController.putAnalytics.setState( - AnalyticsStream( - eventId: eventId, - targetID: eventId, - roomId: room.id, - constructs: constructs, - ), + pangeaController.putAnalytics.addAnalytics( + constructs, + eventId: eventId, + targetId: eventId, + roomId: room.id, ); } } @@ -2160,13 +2156,11 @@ class ChatController extends State if (constructs.isEmpty) return; _showAnalyticsFeedback(constructs, eventId); - MatrixState.pangeaController.putAnalytics.setState( - AnalyticsStream( - eventId: eventId, - targetID: eventId, - roomId: room.id, - constructs: constructs, - ), + MatrixState.pangeaController.putAnalytics.addAnalytics( + constructs, + eventId: eventId, + targetId: eventId, + roomId: room.id, ); } catch (e, s) { ErrorHandler.logError( diff --git a/lib/pangea/analytics_misc/construct_list_model.dart b/lib/pangea/analytics_misc/construct_list_model.dart index 7e4e63ed8..a6cbb3a68 100644 --- a/lib/pangea/analytics_misc/construct_list_model.dart +++ b/lib/pangea/analytics_misc/construct_list_model.dart @@ -135,6 +135,14 @@ class ConstructListModel { level = calculateLevelWithXp(totalXP); } + void deleteLemma(String lemma, int offset) { + _uses.removeWhere((use) => use.lemma == lemma); + _constructMap.removeWhere( + (key, value) => value.lemma == lemma, + ); + updateConstructs([], offset); + } + List constructList({ConstructTypeEnum? type}) => _constructList .where( (constructUse) => type == null || constructUse.constructType == type, diff --git a/lib/pangea/analytics_misc/get_analytics_controller.dart b/lib/pangea/analytics_misc/get_analytics_controller.dart index 726826225..6b7db6d53 100644 --- a/lib/pangea/analytics_misc/get_analytics_controller.dart +++ b/lib/pangea/analytics_misc/get_analytics_controller.dart @@ -12,6 +12,7 @@ import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_event.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; import 'package:fluffychat/pangea/analytics_misc/put_analytics_controller.dart'; +import 'package:fluffychat/pangea/analytics_settings/analytics_settings_extension.dart'; import 'package:fluffychat/pangea/common/constants/local.key.dart'; import 'package:fluffychat/pangea/common/controllers/base_controller.dart'; import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart'; @@ -95,6 +96,20 @@ class GetAnalyticsController extends BaseController { final offset = _pangeaController.userController.analyticsProfile?.xpOffset ?? 0; + + final allUses = [ + ...(_getConstructsLocal() ?? []), + ..._locallyCachedConstructs, + ]; + + final Room? analyticsRoom = _client.analyticsRoomLocal(_l2!); + final blockedLemmas = analyticsRoom?.analyticsSettings?.blockedLemmas; + if (blockedLemmas != null && blockedLemmas.isNotEmpty) { + allUses.removeWhere( + (use) => blockedLemmas.contains(use.identifier.lemma), + ); + } + constructListModel.updateConstructs( [ ...(_getConstructsLocal() ?? []), @@ -129,7 +144,6 @@ class GetAnalyticsController extends BaseController { _joinSpaceSubscription = null; initCompleter = Completer(); _cache.clear(); - // perMessage.dispose(); } Future _onAnalyticsUpdate( @@ -286,8 +300,7 @@ class GetAnalyticsController extends BaseController { return formattedCache; } catch (err) { // if something goes wrong while trying to format the local data, clear it - _pangeaController.putAnalytics - .clearMessagesSinceUpdate(clearDrafts: true); + clearMessagesCache(); return {}; } } catch (exception, stackTrace) { diff --git a/lib/pangea/analytics_misc/lemma_emoji_setter_mixin.dart b/lib/pangea/analytics_misc/lemma_emoji_setter_mixin.dart index bccb467a3..74f0cb97f 100644 --- a/lib/pangea/analytics_misc/lemma_emoji_setter_mixin.dart +++ b/lib/pangea/analytics_misc/lemma_emoji_setter_mixin.dart @@ -1,6 +1,5 @@ import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; -import 'package:fluffychat/pangea/analytics_misc/put_analytics_controller.dart'; import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -28,27 +27,27 @@ mixin LemmaEmojiSetter { String? roomId, String? targetId, }) { - MatrixState.pangeaController.putAnalytics.setState( - AnalyticsStream( - eventId: eventId, - roomId: roomId, - targetID: targetId, - constructs: [ - OneConstructUse( - useType: ConstructUseTypeEnum.em, - lemma: constructId.lemma, - constructType: constructId.type, - metadata: ConstructUseMetaData( - roomId: roomId, - timeStamp: DateTime.now(), - eventId: eventId, - ), - category: constructId.category, - form: constructId.lemma, - xp: ConstructUseTypeEnum.em.pointValue, - ), - ], + final constructs = [ + OneConstructUse( + useType: ConstructUseTypeEnum.em, + lemma: constructId.lemma, + constructType: constructId.type, + metadata: ConstructUseMetaData( + roomId: roomId, + timeStamp: DateTime.now(), + eventId: eventId, + ), + category: constructId.category, + form: constructId.lemma, + xp: ConstructUseTypeEnum.em.pointValue, ), + ]; + + MatrixState.pangeaController.putAnalytics.addAnalytics( + constructs, + eventId: eventId, + roomId: roomId, + targetId: targetId, ); } } diff --git a/lib/pangea/analytics_misc/put_analytics_controller.dart b/lib/pangea/analytics_misc/put_analytics_controller.dart index eb1d9006c..e15bbb6e9 100644 --- a/lib/pangea/analytics_misc/put_analytics_controller.dart +++ b/lib/pangea/analytics_misc/put_analytics_controller.dart @@ -5,27 +5,24 @@ import 'package:flutter/foundation.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/pangea/analytics_misc/client_analytics_extension.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; -import 'package:fluffychat/pangea/common/controllers/base_controller.dart'; import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/learning_settings/models/language_model.dart'; +import 'package:fluffychat/pangea/user/controllers/user_controller.dart'; import 'package:fluffychat/widgets/matrix.dart'; -enum AnalyticsUpdateType { server, local, activities, init } +enum AnalyticsUpdateType { server, local, activities, init, delete } /// handles the processing of analytics for /// 1) messages sent by the user and /// 2) constructs used by the user, both in sending messages and doing practice activities -class PutAnalyticsController extends BaseController { +class PutAnalyticsController { late PangeaController _pangeaController; StreamController analyticsUpdateStream = StreamController.broadcast(); - StreamSubscription? _analyticsStream; StreamSubscription? _languageStream; Timer? _updateTimer; @@ -53,31 +50,20 @@ class PutAnalyticsController extends BaseController { } void initialize() { - // Listen for calls to setState on the analytics stream - // and update the analytics room if necessary - _analyticsStream ??= - stateStream.listen((data) => _onNewAnalyticsData(data)); - - // Listen for changes to the user's language settings - _languageStream ??= - _pangeaController.userController.languageStream.stream.listen((update) { - _onUpdateLanguages(update.prevTargetLang); - }); + _languageStream ??= _pangeaController.userController.languageStream.stream + .listen(_onUpdateLanguages); _refreshAnalyticsIfOutdated(); } /// Reset analytics last updated time to null. - @override void dispose() { _updateTimer?.cancel(); lastUpdated = null; lastUpdatedCompleter = Completer(); - _analyticsStream?.cancel(); - _analyticsStream = null; _languageStream?.cancel(); _languageStream = null; - clearMessagesSinceUpdate(); + MatrixState.pangeaController.getAnalytics.clearMessagesCache(); } /// If analytics haven't been updated in the last day, update them @@ -112,137 +98,18 @@ class PutAnalyticsController extends BaseController { /// Given new construct uses, format and cache /// the data locally and reset the update timer /// Decide whether to update the analytics room - void _onNewAnalyticsData(AnalyticsStream data) { - final String? eventID = data.eventId; - final String? roomID = data.roomId; - - final List constructs = []; - // if (roomID != null) { - // constructs = _getDraftUses(roomID); - // } - - constructs.addAll(data.constructs); - - if (kDebugMode) { - for (final use in constructs) { - debugPrint( - "_onNewAnalyticsData filtered use: ${use.constructType.string} ${use.useType.string} ${use.lemma} ${use.xp}", - ); - } - } - + void addAnalytics( + List constructs, { + String? eventId, + String? roomId, + String? targetId, + }) { final level = _pangeaController.getAnalytics.constructListModel.level; - - _addLocalMessage(eventID, constructs).then( - (_) { - if (roomID != null) _clearDraftUses(roomID); - _decideWhetherToUpdateAnalyticsRoom( - level, - data.targetID, - data.constructs, - ); - }, + _addLocalMessage(eventId, constructs).then( + (_) => _sendAnalytics(level, targetId, constructs), ); } - Future _onUpdateLanguages(LanguageModel? previousL2) async { - await sendLocalAnalyticsToAnalyticsRoom( - l2Override: previousL2, - ); - _pangeaController.resetAnalytics().then((_) { - final level = _pangeaController.getAnalytics.constructListModel.level; - _pangeaController.userController.updateAnalyticsProfile(level: level); - }); - } - - // void addDraftUses( - // List tokens, - // String roomID, - // ConstructUseTypeEnum useType, { - // String? targetID, - // }) { - // final metadata = ConstructUseMetaData( - // roomId: roomID, - // timeStamp: DateTime.now(), - // ); - - // // we only save those with saveVocab == true - // final tokensToSave = - // tokens.where((token) => token.lemma.saveVocab).toList(); - - // // get all our vocab constructs - // final uses = tokensToSave - // .map( - // (token) => OneConstructUse( - // useType: useType, - // lemma: token.lemma.text, - // form: token.text.content, - // constructType: ConstructTypeEnum.vocab, - // metadata: metadata, - // category: token.pos, - // ), - // ) - // .toList(); - - // // get all our grammar constructs - // for (final token in tokensToSave) { - // uses.add( - // OneConstructUse( - // useType: useType, - // lemma: token.pos, - // form: token.text.content, - // category: "POS", - // constructType: ConstructTypeEnum.morph, - // metadata: metadata, - // ), - // ); - // for (final entry in token.morph.entries) { - // uses.add( - // OneConstructUse( - // useType: useType, - // lemma: entry.value, - // form: token.text.content, - // category: entry.key, - // constructType: ConstructTypeEnum.morph, - // metadata: metadata, - // ), - // ); - // } - // } - - // if (kDebugMode) { - // for (final use in uses) { - // debugPrint( - // "Draft use: ${use.constructType.string} ${use.useType.string} ${use.lemma} ${use.useType.pointValue}", - // ); - // } - // } - - // final level = _pangeaController.getAnalytics.constructListModel.level; - - // // the list 'uses' gets altered in the _addLocalMessage method, - // // so copy it here to that the list of new uses is accurate - // final List newUses = List.from(uses); - // _addLocalMessage('draft$roomID', uses).then( - // (_) => _decideWhetherToUpdateAnalyticsRoom( - // level, - // targetID, - // newUses, - // ), - // ); - // } - - // List _getDraftUses(String roomID) { - // final currentCache = _pangeaController.getAnalytics.messagesSinceUpdate; - // return currentCache['draft$roomID'] ?? []; - // } - - void _clearDraftUses(String roomID) { - final currentCache = _pangeaController.getAnalytics.messagesSinceUpdate; - currentCache.remove('draft$roomID'); - _setMessagesSinceUpdate(currentCache); - } - /// Add a list of construct uses for a new message to the local /// cache of recently sent messages Future _addLocalMessage( @@ -255,7 +122,7 @@ class PutAnalyticsController extends BaseController { // if this is not a draft message, add the eventId to the metadata // if it's missing (it will be missing for draft constructs) - if (cacheKey != null && !cacheKey.startsWith('draft')) { + if (cacheKey != null) { constructs = constructs.map((construct) { if (construct.metadata.eventId != null) return construct; construct.metadata.eventId = cacheKey; @@ -283,7 +150,7 @@ class PutAnalyticsController extends BaseController { /// If the addition brought the total number of messages in the cache /// to the max, or if the addition triggered a level-up, update the analytics. /// Otherwise, add a local update to the alert stream. - void _decideWhetherToUpdateAnalyticsRoom( + void _sendAnalytics( int prevLevel, String? targetID, List newConstructs, @@ -311,25 +178,14 @@ class PutAnalyticsController extends BaseController { ); } - /// Clears the local cache of recently sent constructs. Called before updating analytics - void clearMessagesSinceUpdate({clearDrafts = false}) { - if (clearDrafts) { - MatrixState.pangeaController.getAnalytics.clearMessagesCache(); - return; - } - - final localCache = _pangeaController.getAnalytics.messagesSinceUpdate; - final draftKeys = localCache.keys.where((key) => key.startsWith('draft')); - if (draftKeys.isEmpty) { - MatrixState.pangeaController.getAnalytics.clearMessagesCache(); - return; - } - - final Map> newCache = {}; - for (final key in draftKeys) { - newCache[key] = localCache[key]!; - } - _setMessagesSinceUpdate(newCache); + Future _onUpdateLanguages(LanguageUpdate update) async { + await sendLocalAnalyticsToAnalyticsRoom( + l2Override: update.prevTargetLang, + ); + _pangeaController.resetAnalytics().then((_) { + final level = _pangeaController.getAnalytics.constructListModel.level; + _pangeaController.userController.updateAnalyticsProfile(level: level); + }); } /// Save the local cache of recently sent constructs to the local storage @@ -369,7 +225,7 @@ class PutAnalyticsController extends BaseController { _updateCompleter = Completer(); try { await _updateAnalytics(l2Override: l2Override); - clearMessagesSinceUpdate(); + MatrixState.pangeaController.getAnalytics.clearMessagesCache(); lastUpdated = DateTime.now(); analyticsUpdateStream.add( @@ -434,39 +290,16 @@ class PutAnalyticsController extends BaseController { ); } - Future removeActivityAnalytics(String roomId) async { - if (_pangeaController.matrixState.client.userID == null) return; - if (_pangeaController.languageController.userL2 == null) return; - - final Room? analyticsRoom = await _client.getMyAnalyticsRoom( - _pangeaController.languageController.userL2!, - ); - if (analyticsRoom == null) return; - await analyticsRoom.removeActivityRoomId(roomId); + Future onBlockLemma() async { analyticsUpdateStream.add( AnalyticsUpdate( - AnalyticsUpdateType.activities, + AnalyticsUpdateType.delete, [], ), ); } } -class AnalyticsStream { - final String? eventId; - final String? roomId; - final String? targetID; - - final List constructs; - - AnalyticsStream({ - required this.eventId, - required this.roomId, - required this.constructs, - this.targetID, - }); -} - class AnalyticsUpdate { final AnalyticsUpdateType type; final List newConstructs; diff --git a/lib/pangea/analytics_page/analytics_page.dart b/lib/pangea/analytics_page/analytics_page.dart index 0c485224a..30031b275 100644 --- a/lib/pangea/analytics_page/analytics_page.dart +++ b/lib/pangea/analytics_page/analytics_page.dart @@ -5,15 +5,19 @@ import 'package:go_router/go_router.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/analytics_details_popup/analytics_details_popup.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/put_analytics_controller.dart'; import 'package:fluffychat/pangea/analytics_page/activity_archive.dart'; import 'package:fluffychat/pangea/analytics_page/analytics_page_constants.dart'; +import 'package:fluffychat/pangea/analytics_settings/analytics_settings_extension.dart'; import 'package:fluffychat/pangea/analytics_summary/learning_progress_indicators.dart'; import 'package:fluffychat/pangea/analytics_summary/level_dialog_content.dart'; import 'package:fluffychat/pangea/analytics_summary/progress_indicators_enum.dart'; import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; +import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart'; +import 'package:fluffychat/widgets/future_loading_dialog.dart'; import 'package:fluffychat/widgets/matrix.dart'; class AnalyticsPage extends StatelessWidget { @@ -28,11 +32,43 @@ class AnalyticsPage extends StatelessWidget { this.isSidebar = false, }); + Future _blockLemma(BuildContext context) async { + final resp = await showOkCancelAlertDialog( + context: context, + title: L10n.of(context).areYouSure, + message: L10n.of(context).blockLemmaConfirmation, + isDestructive: true, + ); + + if (resp != OkCancelResult.ok) return; + final res = await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.blockLemma(construct!.lemma), + ); + + if (!res.isError) { + context.go("/rooms/analytics/${ConstructTypeEnum.vocab.name}"); + } + } + @override Widget build(BuildContext context) { final analyticsRoomId = GoRouterState.of(context).pathParameters['roomid']; return Scaffold( - appBar: construct != null ? AppBar() : null, + appBar: construct != null + ? AppBar( + actions: indicator == ProgressIndicatorEnum.wordsUsed + ? [ + IconButton( + icon: const Icon(Icons.delete_forever_outlined), + color: Theme.of(context).colorScheme.error, + tooltip: L10n.of(context).delete, + onPressed: () => _blockLemma(context), + ), + ] + : null, + ) + : null, body: SafeArea( child: StreamBuilder( stream: MatrixState diff --git a/lib/pangea/analytics_settings/analytics_settings_extension.dart b/lib/pangea/analytics_settings/analytics_settings_extension.dart new file mode 100644 index 000000000..1ae673a8d --- /dev/null +++ b/lib/pangea/analytics_settings/analytics_settings_extension.dart @@ -0,0 +1,46 @@ +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/analytics_misc/client_analytics_extension.dart'; +import 'package:fluffychat/pangea/analytics_settings/analytics_settings_model.dart'; +import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +extension AnalyticsSettingsRoomExtension on Room { + AnalyticsSettingsModel? get analyticsSettings { + final event = getState(PangeaEventTypes.analyticsSettings); + if (event == null) return null; + return AnalyticsSettingsModel.fromJson(event.content); + } + + Future setAnalyticsSettings( + AnalyticsSettingsModel settings, + ) async { + await client.setRoomStateWithKey( + id, + PangeaEventTypes.analyticsSettings, + "", + settings.toJson(), + ); + } +} + +extension AnalyticsSettingsClientExtension on Client { + Future blockLemma(String lemma) async { + final l2 = MatrixState.pangeaController.languageController.userL2!; + final analyticsRoom = await getMyAnalyticsRoom(l2); + if (analyticsRoom == null) { + throw Exception("Could not get or create analytics room"); + } + + final current = analyticsRoom.analyticsSettings; + final blockedLemmas = current?.blockedLemmas ?? {}; + final updated = current?.copyWith( + blockedLemmas: { + ...blockedLemmas, + lemma, + }, + ); + + await analyticsRoom.setAnalyticsSettings(updated!); + } +} diff --git a/lib/pangea/analytics_settings/analytics_settings_model.dart b/lib/pangea/analytics_settings/analytics_settings_model.dart new file mode 100644 index 000000000..24d923bf5 --- /dev/null +++ b/lib/pangea/analytics_settings/analytics_settings_model.dart @@ -0,0 +1,34 @@ +class AnalyticsSettingsModel { + final Set blockedLemmas; + + const AnalyticsSettingsModel({ + required this.blockedLemmas, + }); + + AnalyticsSettingsModel copyWith({ + Set? blockedLemmas, + }) { + return AnalyticsSettingsModel( + blockedLemmas: blockedLemmas ?? this.blockedLemmas, + ); + } + + factory AnalyticsSettingsModel.fromJson(Map json) { + final blockedLemmas = {}; + if (json['blocked_lemmas'] != null) { + final lemmas = json['blocked_lemmas'] as List; + for (final lemma in lemmas) { + blockedLemmas.add(lemma as String); + } + } + return AnalyticsSettingsModel( + blockedLemmas: blockedLemmas, + ); + } + + Map toJson() { + return { + 'blocked_lemmas': blockedLemmas.toList(), + }; + } +} diff --git a/lib/pangea/events/constants/pangea_event_types.dart b/lib/pangea/events/constants/pangea_event_types.dart index dbcc7ad7e..53cc39763 100644 --- a/lib/pangea/events/constants/pangea_event_types.dart +++ b/lib/pangea/events/constants/pangea_event_types.dart @@ -54,4 +54,6 @@ class PangeaEventTypes { static const courseUser = "p.course_user"; static const teacherMode = "pangea.teacher_mode"; static const courseChatList = "pangea.course_chat_list"; + + static const analyticsSettings = "pangea.analytics_settings"; } diff --git a/lib/pangea/toolbar/widgets/message_selection_overlay.dart b/lib/pangea/toolbar/widgets/message_selection_overlay.dart index 9753d9718..f7da55214 100644 --- a/lib/pangea/toolbar/widgets/message_selection_overlay.dart +++ b/lib/pangea/toolbar/widgets/message_selection_overlay.dart @@ -13,7 +13,6 @@ import 'package:fluffychat/pages/chat/chat.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; -import 'package:fluffychat/pangea/analytics_misc/put_analytics_controller.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/events/event_wrappers/pangea_representation_event.dart'; @@ -198,27 +197,26 @@ class MessageOverlayController extends State setState(() {}); if (selectedToken != null && isNewToken(selectedToken!)) { final token = selectedToken!; - MatrixState.pangeaController.putAnalytics.setState( - AnalyticsStream( - eventId: event.eventId, - roomId: event.room.id, - constructs: [ - OneConstructUse( - useType: ConstructUseTypeEnum.click, - lemma: token.lemma.text, - constructType: ConstructTypeEnum.vocab, - metadata: ConstructUseMetaData( - roomId: event.room.id, - timeStamp: DateTime.now(), - eventId: event.eventId, - ), - category: token.pos, - form: token.text.content, - xp: ConstructUseTypeEnum.click.pointValue, - ), - ], - targetID: "word-zoom-card-${token.text.uniqueKey}", + final constructs = [ + OneConstructUse( + useType: ConstructUseTypeEnum.click, + lemma: token.lemma.text, + constructType: ConstructTypeEnum.vocab, + metadata: ConstructUseMetaData( + roomId: event.room.id, + timeStamp: DateTime.now(), + eventId: event.eventId, + ), + category: token.pos, + form: token.text.content, + xp: ConstructUseTypeEnum.click.pointValue, ), + ]; + MatrixState.pangeaController.putAnalytics.addAnalytics( + constructs, + eventId: event.eventId, + roomId: event.room.id, + targetId: "word-zoom-card-${token.text.uniqueKey}", ); } } diff --git a/lib/pangea/toolbar/widgets/practice_controller.dart b/lib/pangea/toolbar/widgets/practice_controller.dart index 7df582262..10396bd7e 100644 --- a/lib/pangea/toolbar/widgets/practice_controller.dart +++ b/lib/pangea/toolbar/widgets/practice_controller.dart @@ -6,7 +6,6 @@ import 'package:collection/collection.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; -import 'package:fluffychat/pangea/analytics_misc/put_analytics_controller.dart'; import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/practice_activities/activity_type_enum.dart'; @@ -125,28 +124,28 @@ class PracticeController with ChangeNotifier { final constructUseType = _activity!.practiceTarget.record.responses.last .useType(_activity!.activityType); - MatrixState.pangeaController.putAnalytics.setState( - AnalyticsStream( - eventId: pangeaMessageEvent.eventId, - roomId: pangeaMessageEvent.room.id, - constructs: [ - OneConstructUse( - useType: constructUseType, - lemma: token.lemma.text, - constructType: ConstructTypeEnum.vocab, - metadata: ConstructUseMetaData( - roomId: pangeaMessageEvent.room.id, - timeStamp: DateTime.now(), - eventId: pangeaMessageEvent.eventId, - ), - category: token.pos, - // in the case of a wrong answer, the cId doesn't match the token - form: token.text.content, - xp: constructUseType.pointValue, - ), - ], - targetID: targetId, + final constructs = [ + OneConstructUse( + useType: constructUseType, + lemma: token.lemma.text, + constructType: ConstructTypeEnum.vocab, + metadata: ConstructUseMetaData( + roomId: pangeaMessageEvent.room.id, + timeStamp: DateTime.now(), + eventId: pangeaMessageEvent.eventId, + ), + category: token.pos, + // in the case of a wrong answer, the cId doesn't match the token + form: token.text.content, + xp: constructUseType.pointValue, ), + ]; + + MatrixState.pangeaController.putAnalytics.addAnalytics( + constructs, + eventId: pangeaMessageEvent.eventId, + roomId: pangeaMessageEvent.room.id, + targetId: targetId, ); } diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index 3fc7e5b35..24f1eaca6 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -152,6 +152,7 @@ abstract class ClientManager { PangeaEventTypes.courseUser, PangeaEventTypes.teacherMode, PangeaEventTypes.courseChatList, + PangeaEventTypes.analyticsSettings, // Pangea# }, logLevel: kReleaseMode ? Level.warning : Level.verbose,