From 9a0f5682ef52306a1e420fe562d1c9c4bdb0681e Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 27 Jun 2025 12:19:47 -0400 Subject: [PATCH] chore: send all message / constructs from the level to request for construct summary, show loading and error messages when needed --- .../get_analytics_controller.dart | 50 ++- lib/pangea/analytics_misc/level_up.dart | 296 ++++++++++-------- 2 files changed, 202 insertions(+), 144 deletions(-) diff --git a/lib/pangea/analytics_misc/get_analytics_controller.dart b/lib/pangea/analytics_misc/get_analytics_controller.dart index dcdcafd65..5f8997a7d 100644 --- a/lib/pangea/analytics_misc/get_analytics_controller.dart +++ b/lib/pangea/analytics_misc/get_analytics_controller.dart @@ -477,8 +477,8 @@ class GetAnalyticsController extends BaseController { // generate level up analytics as a construct summary ConstructSummary summary; try { - final int maxXP = constructListModel.calculateXpWithLevel(upperLevel); - final int minXP = constructListModel.calculateXpWithLevel(lowerLevel); + final int minXP = constructListModel.calculateXpWithLevel(upperLevel); + final int maxXP = constructListModel.calculateXpWithLevel(lowerLevel); int diffXP = maxXP - minXP; if (diffXP < 0) diffXP = 0; @@ -492,23 +492,41 @@ class GetAnalyticsController extends BaseController { } // extract construct use message bodies for analytics - List? constructUseMessageContentBodies = []; + final Map> useEventIds = {}; for (final use in constructUseOfCurrentLevel) { - try { - final useMessage = await use.getEvent(_client); - final useMessageBody = useMessage?.content["body"]; - if (useMessageBody is String) { - constructUseMessageContentBodies.add(useMessageBody); - } else { - constructUseMessageContentBodies.add(null); + if (use.metadata.roomId == null) continue; + if (use.metadata.eventId == null) continue; + useEventIds[use.metadata.roomId!] ??= {}; + useEventIds[use.metadata.roomId!]!.add(use.metadata.eventId!); + } + + final List constructUseMessageContentBodies = []; + for (final entry in useEventIds.entries) { + final String roomId = entry.key; + final room = _client.getRoomById(roomId); + if (room == null) continue; + final List messageBodies = []; + for (final eventId in entry.value) { + try { + final Event? event = await room.getEventById(eventId); + if (event?.content["body"] is! String) continue; + final String body = event?.content["body"] as String; + if (body.isEmpty) continue; + messageBodies.add(body); + } catch (e, s) { + debugPrint("Error getting event by ID: $e"); + ErrorHandler.logError( + e: e, + s: s, + data: { + 'roomId': roomId, + 'eventId': eventId, + }, + ); + continue; } - } catch (e) { - constructUseMessageContentBodies.add(null); } - } - if (constructUseMessageContentBodies.length != - constructUseOfCurrentLevel.length) { - constructUseMessageContentBodies = null; + constructUseMessageContentBodies.addAll(messageBodies); } final request = ConstructSummaryRequest( diff --git a/lib/pangea/analytics_misc/level_up.dart b/lib/pangea/analytics_misc/level_up.dart index ab57cd03d..6e348aa13 100644 --- a/lib/pangea/analytics_misc/level_up.dart +++ b/lib/pangea/analytics_misc/level_up.dart @@ -91,6 +91,7 @@ class LevelUpBannerState extends State ConstructSummary? _constructSummary; String? _error; + bool _loading = true; @override void initState() { @@ -143,6 +144,7 @@ class LevelUpBannerState extends State Future _setConstructSummary() async { try { + setState(() => _loading = true); _constructSummary = await MatrixState.pangeaController.getAnalytics .generateLevelUpAnalytics( widget.level, @@ -150,6 +152,10 @@ class LevelUpBannerState extends State ); } catch (e) { _error = e.toString(); + } finally { + if (mounted) { + setState(() => _loading = false); + } } } @@ -364,144 +370,178 @@ class LevelUpBannerState extends State borderRadius: BorderRadius.circular(8), ), padding: const EdgeInsets.all(16), - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - spacing: 24.0, - children: [ - Table( - columnWidths: const { - 0: IntrinsicColumnWidth(), - 1: FlexColumnWidth(), - 2: IntrinsicColumnWidth(), - }, - defaultVerticalAlignment: - TableCellVerticalAlignment.middle, - children: [ - ...LearningSkillsEnum.values - .where( - (v) => - v.isVisible && _skillsPoints(v) > -1, + child: _loading + ? const Center( + child: CircularProgressIndicator.adaptive(), + ) + : _error != null + ? Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Icon( + Icons.error, + color: Theme.of(context) + .colorScheme + .error, + ), + const SizedBox(width: 8.0), + Text( + L10n.of(context) + .oopsSomethingWentWrong, + ), + ], ) - .map((skill) { - return TableRow( + : SingleChildScrollView( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + spacing: 24.0, children: [ - Padding( - padding: const EdgeInsets.symmetric( - vertical: 9.0, - horizontal: 18.0, - ), - child: Icon( - skill.icon, - size: 25, - color: Colors.white, - ), + Table( + columnWidths: const { + 0: IntrinsicColumnWidth(), + 1: FlexColumnWidth(), + 2: IntrinsicColumnWidth(), + }, + defaultVerticalAlignment: + TableCellVerticalAlignment + .middle, + children: [ + ...LearningSkillsEnum.values + .where( + (v) => + v.isVisible && + _skillsPoints(v) > -1, + ) + .map((skill) { + return TableRow( + children: [ + Padding( + padding: const EdgeInsets + .symmetric( + vertical: 9.0, + horizontal: 18.0, + ), + child: Icon( + skill.icon, + size: 25, + color: Colors.white, + ), + ), + Padding( + padding: const EdgeInsets + .symmetric( + vertical: 9.0, + horizontal: 18.0, + ), + child: Text( + skill.tooltip(context), + style: const TextStyle( + fontSize: 16, + fontWeight: + FontWeight.w600, + color: Colors.white, + ), + textAlign: + TextAlign.center, + ), + ), + Padding( + padding: const EdgeInsets + .symmetric( + vertical: 9.0, + horizontal: 18.0, + ), + child: Text( + "+ ${_skillsPoints(skill)} XP", + style: const TextStyle( + fontSize: 16, + fontWeight: + FontWeight.w600, + color: Colors.white, + ), + textAlign: + TextAlign.center, + ), + ), + ], + ); + }), + ], ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: 9.0, - horizontal: 18.0, - ), - child: Text( - skill.tooltip(context), - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Colors.white, - ), - textAlign: TextAlign.center, - ), + CachedNetworkImage( + imageUrl: + "${AppConfig.assetsBaseURL}/${LevelUpConstants.dinoLevelUPFileName}", + width: 400, + fit: BoxFit.cover, ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: 9.0, - horizontal: 18.0, - ), - child: Text( - "+ ${_skillsPoints(skill)} XP", - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Colors.white, + if (_constructSummary?.textSummary != + null) + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Theme.of(context) + .colorScheme + .secondaryContainer, + borderRadius: + BorderRadius.circular(8), + ), + child: Text( + _constructSummary!.textSummary, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Theme.of(context) + .colorScheme + .onSecondaryContainer, + ), + textAlign: TextAlign.center, ), - textAlign: TextAlign.center, ), + const SizedBox( + height: 24, ), + // Share button, currently no functionality + // ElevatedButton( + // onPressed: () { + // // Add share functionality + // }, + // style: ElevatedButton.styleFrom( + // backgroundColor: Colors.white, + // foregroundColor: Colors.black, + // padding: const EdgeInsets.symmetric( + // vertical: 12, + // horizontal: 24, + // ), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // child: const Row( + // mainAxisSize: MainAxisSize + // .min, + // children: [ + // Text( + // "Share with Friends", + // style: TextStyle( + // fontSize: 16, + // fontWeight: FontWeight.bold, + // ), + // ), + // SizedBox( + // width: 8, + // ), + // Icon( + // Icons.ios_share, + // size: 20, + // ), + // ), + // ), + // ), ], - ); - }), - ], - ), - CachedNetworkImage( - imageUrl: - "${AppConfig.assetsBaseURL}/${LevelUpConstants.dinoLevelUPFileName}", - width: 400, - fit: BoxFit.cover, - ), - if (_constructSummary?.textSummary != null) - Container( - padding: const EdgeInsets.all(12), - decoration: BoxDecoration( - color: Theme.of(context) - .colorScheme - .secondaryContainer, - borderRadius: BorderRadius.circular(8), - ), - child: Text( - _constructSummary!.textSummary, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Theme.of(context) - .colorScheme - .onSecondaryContainer, ), - textAlign: TextAlign.center, ), - ), - const SizedBox( - height: 24, - ), - // Share button, currently no functionality - // ElevatedButton( - // onPressed: () { - // // Add share functionality - // }, - // style: ElevatedButton.styleFrom( - // backgroundColor: Colors.white, - // foregroundColor: Colors.black, - // padding: const EdgeInsets.symmetric( - // vertical: 12, - // horizontal: 24, - // ), - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(8), - // ), - // ), - // child: const Row( - // mainAxisSize: MainAxisSize - // .min, - // children: [ - // Text( - // "Share with Friends", - // style: TextStyle( - // fontSize: 16, - // fontWeight: FontWeight.bold, - // ), - // ), - // SizedBox( - // width: 8, - // ), - // Icon( - // Icons.ios_share, - // size: 20, - // ), - // ), - // ), - // ), - ], - ), - ), ), ), ],