diff --git a/lib/pangea/matrix_event_wrappers/pangea_message_event.dart b/lib/pangea/matrix_event_wrappers/pangea_message_event.dart index 3f2f23616..cb7cba52a 100644 --- a/lib/pangea/matrix_event_wrappers/pangea_message_event.dart +++ b/lib/pangea/matrix_event_wrappers/pangea_message_event.dart @@ -564,17 +564,20 @@ class PangeaMessageEvent { return langCode ?? LanguageKeys.unknownLanguage; } - PangeaMatch? firstErrorStep(String lemma) { + List? errorSteps(String lemma) { final RepresentationEvent? repEvent = originalSent ?? originalWritten; if (repEvent?.choreo == null) return null; - final PangeaMatch? step = repEvent!.choreo!.choreoSteps - .firstWhereOrNull( - (element) => - element.acceptedOrIgnoredMatch?.match.shortMessage == lemma, + final List steps = repEvent!.choreo!.choreoSteps + .where( + (choreoStep) => + choreoStep.acceptedOrIgnoredMatch != null && + choreoStep.acceptedOrIgnoredMatch?.match.shortMessage == lemma, ) - ?.acceptedOrIgnoredMatch; - return step; + .map((element) => element.acceptedOrIgnoredMatch) + .cast() + .toList(); + return steps; } // List get activities => diff --git a/lib/pangea/pages/analytics/class_analytics/class_analytics_view.dart b/lib/pangea/pages/analytics/class_analytics/class_analytics_view.dart index dfb44e106..88c15bdf5 100644 --- a/lib/pangea/pages/analytics/class_analytics/class_analytics_view.dart +++ b/lib/pangea/pages/analytics/class_analytics/class_analytics_view.dart @@ -1,3 +1,4 @@ +import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -20,7 +21,12 @@ class ClassAnalyticsView extends StatelessWidget { .map( (room) => TabItem( avatar: room.avatarUrl, - displayName: room.name ?? "", + displayName: room.name ?? + Matrix.of(context) + .client + .getRoomById(room.roomId) + ?.getLocalizedDisplayname() ?? + "", id: room.roomId, ), ) diff --git a/lib/pangea/pages/analytics/construct_list.dart b/lib/pangea/pages/analytics/construct_list.dart index 838f766a3..ffcf0e79a 100644 --- a/lib/pangea/pages/analytics/construct_list.dart +++ b/lib/pangea/pages/analytics/construct_list.dart @@ -248,6 +248,38 @@ class ConstructListViewState extends State { (element) => element.content.lemma == widget.controller.currentLemma, ); + // given the current lemma and list of message events, return a list of + // MessageEventMatch objects, which contain one PangeaMessageEvent to one PangeaMatch + // this is because some message events may have has more than one PangeaMatch of a + // given lemma type. + List getMessageEventMatches() { + if (widget.controller.currentLemma == null) return []; + final List allMsgErrorSteps = []; + + for (final msgEvent in _msgEvents) { + if (allMsgErrorSteps.any( + (element) => element.msgEvent.eventId == msgEvent.eventId, + )) { + continue; + } + // get all the pangea matches in that message which have that lemma + final List? msgErrorSteps = msgEvent.errorSteps( + widget.controller.currentLemma!, + ); + if (msgErrorSteps == null) continue; + + allMsgErrorSteps.addAll( + msgErrorSteps.map( + (errorStep) => MessageEventMatch( + msgEvent: msgEvent, + lemmaMatch: errorStep, + ), + ), + ); + } + return allMsgErrorSteps; + } + @override Widget build(BuildContext context) { if (!widget.init || fetchingUses) { @@ -262,6 +294,8 @@ class ConstructListViewState extends State { ); } + final msgEventMatches = getMessageEventMatches(); + return widget.controller.currentLemma == null ? Expanded( child: ListView.builder( @@ -299,11 +333,12 @@ class ConstructListViewState extends State { child: ListView.separated( separatorBuilder: (context, index) => const Divider(height: 1), - itemCount: _msgEvents.length, + itemCount: msgEventMatches.length, itemBuilder: (context, index) { return ConstructMessage( - msgEvent: _msgEvents[index], + msgEvent: msgEventMatches[index].msgEvent, lemma: widget.controller.currentLemma!, + errorMessage: msgEventMatches[index].lemmaMatch, ); }, ), @@ -316,21 +351,18 @@ class ConstructListViewState extends State { class ConstructMessage extends StatelessWidget { final PangeaMessageEvent msgEvent; + final PangeaMatch errorMessage; final String lemma; const ConstructMessage({ super.key, required this.msgEvent, + required this.errorMessage, required this.lemma, }); @override Widget build(BuildContext context) { - final PangeaMatch? errorMessage = msgEvent.firstErrorStep(lemma); - if (errorMessage == null) { - return const SizedBox.shrink(); - } - final String? chosen = errorMessage.match.choices ?.firstWhereOrNull( (element) => element.selected == true, @@ -488,6 +520,14 @@ class ConstructMessageMetadata extends StatelessWidget { @override Widget build(BuildContext context) { + final String roomName = msgEvent.event.room.name.isEmpty + ? Matrix.of(context) + .client + .getRoomById(msgEvent.event.room.id) + ?.getLocalizedDisplayname() ?? + "" + : msgEvent.event.room.name; + return Padding( padding: const EdgeInsets.fromLTRB(10, 0, 30, 0), child: Column( @@ -496,9 +536,19 @@ class ConstructMessageMetadata extends StatelessWidget { msgEvent.event.originServerTs.localizedTime(context), style: TextStyle(fontSize: 13 * AppConfig.fontSizeFactor), ), - Text(msgEvent.event.room.name), + Text(roomName), ], ), ); } } + +class MessageEventMatch { + final PangeaMessageEvent msgEvent; + final PangeaMatch lemmaMatch; + + MessageEventMatch({ + required this.msgEvent, + required this.lemmaMatch, + }); +}