diff --git a/lib/pangea/controllers/my_analytics_controller.dart b/lib/pangea/controllers/my_analytics_controller.dart index 808355b47..eb3969bd1 100644 --- a/lib/pangea/controllers/my_analytics_controller.dart +++ b/lib/pangea/controllers/my_analytics_controller.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; +import 'package:fluffychat/pangea/matrix_event_wrappers/construct_analytics_event.dart'; import 'package:fluffychat/pangea/models/student_analytics_summary_model.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:flutter/foundation.dart'; @@ -111,4 +112,48 @@ class MyAnalyticsController { ErrorHandler.logError(e: err, s: s); } } + + // used to aggregate ConstructEvents, from multiple senders (students) with the same lemma + List aggregateConstructData( + List constructs, + ) { + final Map> lemmasToConstructs = {}; + for (final construct in constructs) { + lemmasToConstructs[construct.content.lemma] ??= []; + lemmasToConstructs[construct.content.lemma]!.add(construct); + } + + final List aggregatedConstructs = []; + for (final lemmaToConstructs in lemmasToConstructs.entries) { + final List lemmaConstructs = lemmaToConstructs.value; + final AggregateConstructUses aggregatedData = AggregateConstructUses( + constructs: lemmaConstructs, + ); + aggregatedConstructs.add(aggregatedData); + } + return aggregatedConstructs; + } +} + +class AggregateConstructUses { + final List _constructs; + + AggregateConstructUses({required List constructs}) + : _constructs = constructs; + + String get lemma { + assert( + _constructs.isNotEmpty && + _constructs.every( + (construct) => + construct.content.lemma == _constructs.first.content.lemma, + ), + ); + return _constructs.first.content.lemma; + } + + List get uses => _constructs + .map((construct) => construct.content.uses) + .expand((element) => element) + .toList(); } diff --git a/lib/pangea/pages/analytics/class_list/class_list.dart b/lib/pangea/pages/analytics/class_list/class_list.dart index 6ce8b994d..e96538a11 100644 --- a/lib/pangea/pages/analytics/class_list/class_list.dart +++ b/lib/pangea/pages/analytics/class_list/class_list.dart @@ -1,11 +1,10 @@ import 'dart:async'; +import 'package:fluffychat/pangea/enum/time_span.dart'; +import 'package:fluffychat/pangea/pages/analytics/class_list/class_list_view.dart'; import 'package:flutter/material.dart'; - import 'package:matrix/matrix.dart'; -import 'package:fluffychat/pangea/enum/time_span.dart'; -import 'package:fluffychat/pangea/pages/analytics/class_list/class_list_view.dart'; import '../../../../widgets/matrix.dart'; import '../../../constants/pangea_event_types.dart'; import '../../../controllers/pangea_controller.dart'; @@ -42,7 +41,11 @@ class AnalyticsClassListController extends State { if (!(refreshTimer[newState.room.id]?.isActive ?? false)) { refreshTimer[newState.room.id] = Timer( const Duration(seconds: 3), - () => updateClassAnalytics(context, newState.room), + () { + if (newState.room.isSpace) { + updateClassAnalytics(context, newState.room); + } + }, ); } } diff --git a/lib/pangea/pages/analytics/construct_list.dart b/lib/pangea/pages/analytics/construct_list.dart index ffcf0e79a..ca48d4d92 100644 --- a/lib/pangea/pages/analytics/construct_list.dart +++ b/lib/pangea/pages/analytics/construct_list.dart @@ -3,9 +3,9 @@ import 'dart:async'; import 'package:collection/collection.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; +import 'package:fluffychat/pangea/controllers/my_analytics_controller.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; -import 'package:fluffychat/pangea/matrix_event_wrappers/construct_analytics_event.dart'; import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_representation_event.dart'; import 'package:fluffychat/pangea/models/constructs_analytics_model.dart'; @@ -169,7 +169,7 @@ class ConstructListViewState extends State { int get lemmaIndex => constructs?.indexWhere( - (element) => element.content.lemma == widget.controller.currentLemma, + (element) => element.lemma == widget.controller.currentLemma, ) ?? -1; @@ -217,7 +217,7 @@ class ConstructListViewState extends State { setState(() => fetchingUses = true); try { - final List uses = currentConstruct!.content.uses; + final List uses = currentConstruct!.uses; _msgEvents.clear(); for (final OneConstructUse use in uses) { @@ -236,16 +236,20 @@ class ConstructListViewState extends State { ErrorHandler.logError( e: err, s: s, - m: "Failed to fetch uses for current construct ${currentConstruct?.content.lemma}", + m: "Failed to fetch uses for current construct ${currentConstruct?.lemma}", ); } } - List? get constructs => - widget.pangeaController.analytics.constructs; + List? get constructs => + widget.pangeaController.analytics.constructs != null + ? widget.pangeaController.myAnalytics.aggregateConstructData( + widget.pangeaController.analytics.constructs!, + ) + : null; - ConstructEvent? get currentConstruct => constructs?.firstWhereOrNull( - (element) => element.content.lemma == widget.controller.currentLemma, + AggregateConstructUses? get currentConstruct => constructs?.firstWhereOrNull( + (element) => element.lemma == widget.controller.currentLemma, ); // given the current lemma and list of message events, return a list of @@ -303,13 +307,13 @@ class ConstructListViewState extends State { itemBuilder: (context, index) { return ListTile( title: Text( - constructs![index].content.lemma, + constructs![index].lemma, ), subtitle: Text( - '${L10n.of(context)!.total} ${constructs![index].content.uses.length}', + '${L10n.of(context)!.total} ${constructs![index].uses.length}', ), onTap: () { - final String lemma = constructs![index].content.lemma; + final String lemma = constructs![index].lemma; widget.controller.setCurrentLemma(lemma); fetchUses(); }, @@ -321,8 +325,7 @@ class ConstructListViewState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (constructs![lemmaIndex].content.uses.length > - _msgEvents.length) + if (constructs![lemmaIndex].uses.length > _msgEvents.length) Center( child: Padding( padding: const EdgeInsets.all(8.0),