From 867004243f948d589f325176dd201947a2b061a1 Mon Sep 17 00:00:00 2001 From: ggurdin <46800240+ggurdin@users.noreply.github.com> Date: Thu, 7 Aug 2025 11:49:57 -0400 Subject: [PATCH] =?UTF-8?q?chore:=20don't=20lazy=20load=20members,=20accou?= =?UTF-8?q?nt=20for=20left=20memebers=20when=20determ=E2=80=A6=20(#3653)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: don't lazy load members, account for left memebers when determining if activity is finished * chore: always show continue button in unfinished activities --- lib/pages/chat/chat_view.dart | 9 +- .../events/room_creation_state_event.dart | 4 + .../activity_finished_status_message.dart | 4 + .../activity_pinned_message.dart | 194 +++++++++--------- .../activity_room_extension.dart | 13 +- .../activity_unfinished_status_message.dart | 84 ++++---- .../client_analytics_extension.dart | 11 - .../get_analytics_controller.dart | 1 - .../pages/pangea_invitation_selection.dart | 30 +-- .../space_analytics/space_analytics.dart | 6 - .../spaces/utils/load_participants_util.dart | 6 - .../widgets/knocking_users_indicator.dart | 11 +- lib/utils/client_manager.dart | 6 +- 13 files changed, 175 insertions(+), 204 deletions(-) diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 7e5d89038..f1914204a 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -202,11 +202,6 @@ class ChatView extends StatelessWidget { if (scrollUpBannerEventId != null) { appbarBottomHeight += ChatAppBarListTile.fixedHeight; } - // #Pangea - if (controller.room.isActiveInActivity) { - appbarBottomHeight += ChatAppBarListTile.fixedHeight; - } - // Pangea# return Scaffold( appBar: AppBar( // #Pangea @@ -281,9 +276,6 @@ class ChatView extends StatelessWidget { child: Text(L10n.of(context).jump), ), ), - // #Pangea - ActivityPinnedMessage(controller), - // Pangea# ], ), ), @@ -474,6 +466,7 @@ class ChatView extends StatelessWidget { ], ), ), + ActivityPinnedMessage(controller), // Pangea# ], ), diff --git a/lib/pages/chat/events/room_creation_state_event.dart b/lib/pages/chat/events/room_creation_state_event.dart index f02770ee1..576e84b0b 100644 --- a/lib/pages/chat/events/room_creation_state_event.dart +++ b/lib/pages/chat/events/room_creation_state_event.dart @@ -6,6 +6,7 @@ import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/l10n/l10n.dart'; +import 'package:fluffychat/pangea/activity_planner/activity_room_extension.dart'; import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart'; import 'package:fluffychat/utils/date_time_extension.dart'; @@ -66,6 +67,9 @@ class RoomCreationStateEventState extends State { // child: ConstrainedBox( child: Column( children: [ + // https://github.com/pangeachat/client/issues/3639 + if (widget.event.room.isActiveInActivity) + const SizedBox(height: 60.0), ConstrainedBox( // Pangea# constraints: const BoxConstraints(maxWidth: 256), diff --git a/lib/pangea/activity_planner/activity_finished_status_message.dart b/lib/pangea/activity_planner/activity_finished_status_message.dart index 40025b9df..f3559a44f 100644 --- a/lib/pangea/activity_planner/activity_finished_status_message.dart +++ b/lib/pangea/activity_planner/activity_finished_status_message.dart @@ -38,6 +38,10 @@ class ActivityFinishedStatusMessageState void initState() { super.initState(); _setDefaultHighlightedRole(); + + if (widget.room.activityIsFinished && widget.room.activitySummary == null) { + widget.room.fetchSummaries(); + } } @override diff --git a/lib/pangea/activity_planner/activity_pinned_message.dart b/lib/pangea/activity_planner/activity_pinned_message.dart index f3580fbf0..30e10d40e 100644 --- a/lib/pangea/activity_planner/activity_pinned_message.dart +++ b/lib/pangea/activity_planner/activity_pinned_message.dart @@ -73,111 +73,119 @@ class ActivityPinnedMessageState extends State { final theme = Theme.of(context); final isColumnMode = FluffyThemes.isColumnMode(context); - return Column( - children: [ - AnimatedContainer( - duration: FluffyThemes.animationDuration, - decoration: BoxDecoration( - color: _showDropdown - ? theme.colorScheme.surfaceContainerHighest - : theme.colorScheme.surface, - ), - child: ChatAppBarListTile( - title: "🎯 ${room.activityPlan!.learningObjective}", - leading: const SizedBox(width: 18.0), - trailing: Padding( - padding: const EdgeInsets.only(right: 12.0), - child: ElevatedButton( - onPressed: _showDropdown ? null : () => _setShowDropdown(true), - style: ElevatedButton.styleFrom( - minimumSize: Size.zero, - padding: const EdgeInsets.symmetric( - horizontal: 12.0, - vertical: 4.0, + return Positioned( + top: 0, + left: 0, + right: 0, + bottom: _showDropdown ? 0 : null, + child: Column( + children: [ + AnimatedContainer( + duration: FluffyThemes.animationDuration, + decoration: BoxDecoration( + color: _showDropdown + ? theme.colorScheme.surfaceContainerHighest + : theme.colorScheme.surface, + ), + child: ChatAppBarListTile( + title: "🎯 ${room.activityPlan!.learningObjective}", + leading: const SizedBox(width: 18.0), + trailing: Padding( + padding: const EdgeInsets.only(right: 12.0), + child: ElevatedButton( + onPressed: + _showDropdown ? null : () => _setShowDropdown(true), + style: ElevatedButton.styleFrom( + minimumSize: Size.zero, + padding: const EdgeInsets.symmetric( + horizontal: 12.0, + vertical: 4.0, + ), + backgroundColor: AppConfig.yellowDark, + foregroundColor: theme.colorScheme.surface, + disabledBackgroundColor: + AppConfig.yellowDark.withAlpha(100), + disabledForegroundColor: + theme.colorScheme.surface.withAlpha(100), ), - backgroundColor: AppConfig.yellowDark, - foregroundColor: theme.colorScheme.surface, - disabledBackgroundColor: AppConfig.yellowDark.withAlpha(100), - disabledForegroundColor: - theme.colorScheme.surface.withAlpha(100), - ), - child: Text( - L10n.of(context).endActivityTitle, - style: const TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.w900, + child: Text( + L10n.of(context).endActivityTitle, + style: const TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w900, + ), ), ), ), + onTap: _scrollToActivity, ), - onTap: _scrollToActivity, ), - ), - AnimatedSize( - duration: FluffyThemes.animationDuration, - curve: Curves.easeInOut, - child: ClipRect( - child: _showDropdown - ? Container( - decoration: BoxDecoration( - color: theme.colorScheme.surfaceContainerHighest, - ), - padding: const EdgeInsets.symmetric( - horizontal: 12.0, - vertical: 16.0, - ), - child: Column( - spacing: 12.0, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - L10n.of(context).endActivityDesc, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: isColumnMode ? 16.0 : 12.0, - ), - ), - CachedNetworkImage( - imageUrl: - "${AppConfig.assetsBaseURL}/${ActivitySuggestionsConstants.endActivityAssetPath}", - width: isColumnMode ? 240.0 : 120.0, - ), - ElevatedButton( - style: ElevatedButton.styleFrom( - padding: const EdgeInsets.symmetric( - horizontal: 12.0, - vertical: 8.0, + AnimatedSize( + duration: FluffyThemes.animationDuration, + curve: Curves.easeInOut, + child: ClipRect( + child: _showDropdown + ? Container( + decoration: BoxDecoration( + color: theme.colorScheme.surfaceContainerHighest, + ), + padding: const EdgeInsets.symmetric( + horizontal: 12.0, + vertical: 16.0, + ), + child: Column( + spacing: 12.0, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + L10n.of(context).endActivityDesc, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: isColumnMode ? 16.0 : 12.0, ), - foregroundColor: theme.colorScheme.onSecondary, - backgroundColor: theme.colorScheme.secondary, ), - onPressed: _finishActivity, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - L10n.of(context).endActivityTitle, - style: TextStyle( - fontSize: isColumnMode ? 16.0 : 12.0, - ), + CachedNetworkImage( + imageUrl: + "${AppConfig.assetsBaseURL}/${ActivitySuggestionsConstants.endActivityAssetPath}", + width: isColumnMode ? 240.0 : 120.0, + ), + ElevatedButton( + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric( + horizontal: 12.0, + vertical: 8.0, ), - ], + foregroundColor: theme.colorScheme.onSecondary, + backgroundColor: theme.colorScheme.secondary, + ), + onPressed: _finishActivity, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + L10n.of(context).endActivityTitle, + style: TextStyle( + fontSize: isColumnMode ? 16.0 : 12.0, + ), + ), + ], + ), ), - ), - ], - ), - ) - : const SizedBox.shrink(), - ), - ), - if (_showDropdown) - Expanded( - child: GestureDetector( - onTap: () => _setShowDropdown(false), - child: Container(color: Colors.black.withAlpha(100)), + ], + ), + ) + : const SizedBox.shrink(), ), ), - ], + if (_showDropdown) + Expanded( + child: GestureDetector( + onTap: () => _setShowDropdown(false), + child: Container(color: Colors.black.withAlpha(100)), + ), + ), + ], + ), ); } } diff --git a/lib/pangea/activity_planner/activity_room_extension.dart b/lib/pangea/activity_planner/activity_room_extension.dart index e57768c9d..762834198 100644 --- a/lib/pangea/activity_planner/activity_room_extension.dart +++ b/lib/pangea/activity_planner/activity_room_extension.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'dart:typed_data'; +import 'package:collection/collection.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/pangea/activity_planner/activity_plan_model.dart'; @@ -262,7 +263,17 @@ extension ActivityRoomExtension on Room { activityRole(client.userID!)?.isFinished ?? false; bool get activityIsFinished { - return activityRoles.isNotEmpty && activityRoles.every((r) => r.isFinished); + return activityRoles.isNotEmpty && + activityRoles.every((r) { + if (r.isFinished) return true; + + // if the user is in the chat (not null && membership is join), + // then the activity is not finished for them + final user = getParticipants().firstWhereOrNull( + (u) => u.id == r.userId, + ); + return user == null || user.membership != Membership.join; + }); } int? get numberOfParticipants { diff --git a/lib/pangea/activity_planner/activity_unfinished_status_message.dart b/lib/pangea/activity_planner/activity_unfinished_status_message.dart index b31d85a33..2b648aaec 100644 --- a/lib/pangea/activity_planner/activity_unfinished_status_message.dart +++ b/lib/pangea/activity_planner/activity_unfinished_status_message.dart @@ -31,19 +31,22 @@ class ActivityUnfinishedStatusMessageState @override Widget build(BuildContext context) { - final unassignedRoles = widget.room.remainingRoles; + debugPrint("HELLO. remainingRoles: ${widget.room.remainingRoles}"); final theme = Theme.of(context); final isColumnMode = FluffyThemes.isColumnMode(context); + final remainingRoles = widget.room.remainingRoles; + final completed = widget.room.hasCompletedActivity; + return Column( children: [ - if (!widget.room.hasCompletedActivity) ...[ - if (unassignedRoles > 0) + if (!completed) ...[ + if (remainingRoles > 0) Wrap( spacing: 12.0, runSpacing: 12.0, - children: List.generate(unassignedRoles, (index) { + children: List.generate(remainingRoles, (index) { return ActivityParticipantIndicator( selected: _selectedRole == index, onTap: () => _selectRole(index), @@ -52,7 +55,7 @@ class ActivityUnfinishedStatusMessageState ), const SizedBox(height: 16.0), Text( - unassignedRoles > 0 + remainingRoles > 0 ? L10n.of(context).unjoinedActivityMessage : L10n.of(context).fullActivityMessage, textAlign: TextAlign.center, @@ -62,45 +65,44 @@ class ActivityUnfinishedStatusMessageState ), const SizedBox(height: 16.0), ], - if (unassignedRoles > 0) - ElevatedButton( - style: ElevatedButton.styleFrom( - padding: const EdgeInsets.symmetric( - horizontal: 12.0, - vertical: 8.0, - ), - foregroundColor: theme.colorScheme.onPrimaryContainer, - backgroundColor: theme.colorScheme.primaryContainer, + ElevatedButton( + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric( + horizontal: 12.0, + vertical: 8.0, ), - onPressed: widget.room.hasCompletedActivity - ? () { - showFutureLoadingDialog( - context: context, - future: widget.room.continueActivity, - ); - } - : _selectedRole != null - ? () { - showFutureLoadingDialog( - context: context, - future: widget.room.startActivity, - ); - } - : null, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - widget.room.hasCompletedActivity - ? L10n.of(context).continueText - : L10n.of(context).confirmRole, - style: TextStyle( - fontSize: isColumnMode ? 16.0 : 12.0, - ), + foregroundColor: theme.colorScheme.onPrimaryContainer, + backgroundColor: theme.colorScheme.primaryContainer, + ), + onPressed: completed + ? () { + showFutureLoadingDialog( + context: context, + future: widget.room.continueActivity, + ); + } + : _selectedRole != null + ? () { + showFutureLoadingDialog( + context: context, + future: widget.room.startActivity, + ); + } + : null, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + completed + ? L10n.of(context).continueText + : L10n.of(context).confirmRole, + style: TextStyle( + fontSize: isColumnMode ? 16.0 : 12.0, ), - ], - ), + ), + ], ), + ), ], ); } diff --git a/lib/pangea/analytics_misc/client_analytics_extension.dart b/lib/pangea/analytics_misc/client_analytics_extension.dart index 04e884d7b..ca92ff2cc 100644 --- a/lib/pangea/analytics_misc/client_analytics_extension.dart +++ b/lib/pangea/analytics_misc/client_analytics_extension.dart @@ -108,17 +108,6 @@ extension AnalyticsClientExtension on Client { } } - Future loadAnalyticsRequests() async { - if (prevBatch == null) await onSync.stream.first; - if (userID == null || userID == BotName.byEnvironment) return; - - for (final analyticsRoom in allMyAnalyticsRooms) { - if (!isLogged()) return; - analyticsRoom.requestParticipants([Membership.knock], false, true); - analyticsRoom.postLoad(); - } - } - /// Space admins join analytics rooms in spaces via the space hierarchy, /// so other members of the space need to add their analytics rooms to the space. Future addAnalyticsRoomsToSpaces() async { diff --git a/lib/pangea/analytics_misc/get_analytics_controller.dart b/lib/pangea/analytics_misc/get_analytics_controller.dart index addc7e760..3ae310545 100644 --- a/lib/pangea/analytics_misc/get_analytics_controller.dart +++ b/lib/pangea/analytics_misc/get_analytics_controller.dart @@ -78,7 +78,6 @@ class GetAnalyticsController extends BaseController { await GetStorage.init("analytics_storage"); _client.updateAnalyticsRoomJoinRules(); _client.addAnalyticsRoomsToSpaces(); - _client.loadAnalyticsRequests(); _analyticsUpdateSubscription ??= _pangeaController .putAnalytics.analyticsUpdateStream.stream diff --git a/lib/pangea/chat_settings/pages/pangea_invitation_selection.dart b/lib/pangea/chat_settings/pages/pangea_invitation_selection.dart index a051a2fe1..0d705f35b 100644 --- a/lib/pangea/chat_settings/pages/pangea_invitation_selection.dart +++ b/lib/pangea/chat_settings/pages/pangea_invitation_selection.dart @@ -79,7 +79,7 @@ class PangeaInvitationSelectionController extends State { TextEditingController controller = TextEditingController(); - bool loading = true; + bool loading = false; List foundProfiles = []; Timer? coolDown; @@ -103,34 +103,6 @@ class PangeaInvitationSelectionController searchUser(context, ''); } - _room?.requestParticipants( - [ - Membership.join, - Membership.invite, - Membership.knock, - ], - false, - true, - ).then((_) { - if (mounted) { - setState(() { - loading = false; - }); - } - }); - - spaceParent?.requestParticipants( - [ - Membership.join, - Membership.invite, - Membership.knock, - ], - false, - true, - ).then((_) { - if (mounted) setState(() {}); - }); - controller.addListener(() { setState(() {}); }); diff --git a/lib/pangea/space_analytics/space_analytics.dart b/lib/pangea/space_analytics/space_analytics.dart index 98cda733c..7cb0397df 100644 --- a/lib/pangea/space_analytics/space_analytics.dart +++ b/lib/pangea/space_analytics/space_analytics.dart @@ -230,12 +230,6 @@ class SpaceAnalyticsState extends State { } Future _loadProfiles() async { - await room?.requestParticipants( - [Membership.join], - false, - true, - ); - final futures = _availableUsers.map((u) async { final resp = await MatrixState.pangeaController.userController .getPublicProfile(u.id); diff --git a/lib/pangea/spaces/utils/load_participants_util.dart b/lib/pangea/spaces/utils/load_participants_util.dart index eb95f2f6f..68615f09e 100644 --- a/lib/pangea/spaces/utils/load_participants_util.dart +++ b/lib/pangea/spaces/utils/load_participants_util.dart @@ -51,12 +51,6 @@ class LoadParticipantsUtilState extends State { error = null; }); - await widget.space.requestParticipants( - [Membership.join, Membership.invite, Membership.knock], - false, - true, - ); - await _cacheLevels(); } catch (err, s) { error = err.toString(); diff --git a/lib/pangea/spaces/widgets/knocking_users_indicator.dart b/lib/pangea/spaces/widgets/knocking_users_indicator.dart index b40519584..184962460 100644 --- a/lib/pangea/spaces/widgets/knocking_users_indicator.dart +++ b/lib/pangea/spaces/widgets/knocking_users_indicator.dart @@ -48,11 +48,12 @@ class KnockingUsersIndicatorState extends State { super.dispose(); } - Future _setKnockingUsers({bool loadParticipants = false}) async { - _knockingUsers = loadParticipants - ? await widget.room.requestParticipants([Membership.knock]) - : widget.room.getParticipants([Membership.knock]); - if (mounted) setState(() {}); + void _setKnockingUsers() { + if (mounted) { + setState(() { + _knockingUsers = widget.room.getParticipants([Membership.knock]); + }); + } } @override diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index 3dceed6d8..9b6392b1e 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -129,12 +129,13 @@ abstract class ClientManager { // #Pangea // The things in this list will be loaded in the first sync, without having // to postLoad to confirm that these state events are completely loaded + EventTypes.RoomPowerLevels, + EventTypes.RoomJoinRules, + EventTypes.RoomMember, PangeaEventTypes.rules, PangeaEventTypes.botOptions, PangeaEventTypes.capacity, - EventTypes.RoomPowerLevels, PangeaEventTypes.userSetLemmaInfo, - EventTypes.RoomJoinRules, PangeaEventTypes.activityPlan, PangeaEventTypes.activityRole, PangeaEventTypes.activitySummary, @@ -161,7 +162,6 @@ abstract class ClientManager { // #Pangea syncFilter: Filter( room: RoomFilter( - state: StateFilter(lazyLoadMembers: true), timeline: StateFilter( notTypes: [ PangeaEventTypes.construct,