From b1d9b30b294878ac483174e7bc0e57c478d0ae7f Mon Sep 17 00:00:00 2001 From: ggurdin <46800240+ggurdin@users.noreply.github.com> Date: Tue, 12 Aug 2025 11:49:19 -0400 Subject: [PATCH] Conditionally render participants (#3700) * chore: only show activity participants in state event widget it user has assigned role * chore: show participants in activity state event if there are no available roles --- .../activity_room_extension.dart | 26 ++-- .../activity_state_event.dart | 121 +++++++++--------- .../activity_status_message.dart | 2 +- .../activity_unfinished_status_message.dart | 75 +++++------ 4 files changed, 118 insertions(+), 106 deletions(-) diff --git a/lib/pangea/activity_sessions/activity_room_extension.dart b/lib/pangea/activity_sessions/activity_room_extension.dart index b539e2a76..96f2467e8 100644 --- a/lib/pangea/activity_sessions/activity_room_extension.dart +++ b/lib/pangea/activity_sessions/activity_room_extension.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/foundation.dart'; import 'package:collection/collection.dart'; @@ -55,7 +57,7 @@ extension ActivityRoomExtension on Room { Future continueActivity() async { final currentRoles = activityRoles ?? ActivityRolesModel.empty; - final role = currentRoles.role(client.userID!); + final role = ownRole; if (role == null || !role.isFinished) return; role.finishedAt = null; // Reset finished state @@ -75,7 +77,7 @@ extension ActivityRoomExtension on Room { } final currentRoles = activityRoles ?? ActivityRolesModel.empty; - final role = currentRoles.role(client.userID!); + final role = ownRole; if (role == null || role.isFinished) return; role.finishedAt = DateTime.now(); currentRoles.updateRole(role); @@ -101,7 +103,7 @@ extension ActivityRoomExtension on Room { Future archiveActivity() async { final currentRoles = activityRoles ?? ActivityRolesModel.empty; - final role = currentRoles.role(client.userID!); + final role = ownRole; if (role == null || !role.isFinished) return; role.archivedAt = DateTime.now(); @@ -256,6 +258,14 @@ extension ActivityRoomExtension on Room { } } + ActivityRoleModel? get ownRole => activityRoles?.role(client.userID!); + + int get remainingRoles { + final availableRoles = activityPlan!.roles; + final assignedRoles = activityRoles?.roles ?? {}; + return max(0, availableRoles.length - assignedRoles.length); + } + bool get showActivityChatUI { return activityPlan != null && powerForChangingStateEvent(PangeaEventTypes.activityRole) == 0 && @@ -264,18 +274,17 @@ extension ActivityRoomExtension on Room { bool get isActiveInActivity { if (!showActivityChatUI) return false; - final role = activityRoles?.role(client.userID!); + final role = ownRole; return role != null && !role.isFinished; } bool get isInactiveInActivity { if (!showActivityChatUI) return false; - final role = activityRoles?.role(client.userID!); + final role = ownRole; return role == null || role.isFinished; } - bool get hasCompletedActivity => - activityRoles?.role(client.userID!)?.isFinished ?? false; + bool get hasCompletedActivity => ownRole?.isFinished ?? false; bool get activityIsFinished { final roles = activityRoles?.roles.values.where( @@ -295,6 +304,5 @@ extension ActivityRoomExtension on Room { }); } - bool get isHiddenActivityRoom => - activityRoles?.role(client.userID!)?.isArchived ?? false; + bool get isHiddenActivityRoom => ownRole?.isArchived ?? false; } diff --git a/lib/pangea/activity_sessions/activity_state_event.dart b/lib/pangea/activity_sessions/activity_state_event.dart index 598a51c20..a62aedfb8 100644 --- a/lib/pangea/activity_sessions/activity_state_event.dart +++ b/lib/pangea/activity_sessions/activity_state_event.dart @@ -46,70 +46,73 @@ class ActivityStateEvent extends StatelessWidget { activity.markdown, style: const TextStyle(fontSize: 14.0), ), - Wrap( - alignment: WrapAlignment.center, - spacing: 12.0, - runSpacing: 12.0, - children: availableRoles.values.map((availableRole) { - final assignedRole = assignedRoles[availableRole.id]; - final user = event.room.getParticipants().firstWhereOrNull( - (u) => u.id == assignedRole?.userId, - ); + if (event.room.ownRole != null || + event.room.remainingRoles == 0) ...[ + Wrap( + alignment: WrapAlignment.center, + spacing: 12.0, + runSpacing: 12.0, + children: availableRoles.values.map((availableRole) { + final assignedRole = assignedRoles[availableRole.id]; + final user = event.room.getParticipants().firstWhereOrNull( + (u) => u.id == assignedRole?.userId, + ); - return ActivityParticipantIndicator( - availableRole: availableRole, - assignedRole: assignedRole, - opacity: assignedRole == null || assignedRole.isFinished - ? 0.5 - : 1.0, - avatarUrl: - availableRole.avatarUrl ?? user?.avatarUrl?.toString(), - ); - }).toList(), - ), - Wrap( - alignment: WrapAlignment.center, - spacing: 12.0, - runSpacing: 12.0, - children: remainingMembers.map((member) { - return Container( - decoration: BoxDecoration( - color: theme.colorScheme.primaryContainer, - borderRadius: BorderRadius.circular(18.0), - ), - padding: const EdgeInsets.all(4.0), - child: Opacity( - opacity: 0.5, - child: Row( - spacing: 4.0, - mainAxisSize: MainAxisSize.min, - children: [ - Avatar( - size: 18.0, - mxContent: member.avatarUrl, - name: member.calcDisplayname(), - userId: member.id, - ), - ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 80.0, + return ActivityParticipantIndicator( + availableRole: availableRole, + assignedRole: assignedRole, + opacity: assignedRole == null || assignedRole.isFinished + ? 0.5 + : 1.0, + avatarUrl: + availableRole.avatarUrl ?? user?.avatarUrl?.toString(), + ); + }).toList(), + ), + Wrap( + alignment: WrapAlignment.center, + spacing: 12.0, + runSpacing: 12.0, + children: remainingMembers.map((member) { + return Container( + decoration: BoxDecoration( + color: theme.colorScheme.primaryContainer, + borderRadius: BorderRadius.circular(18.0), + ), + padding: const EdgeInsets.all(4.0), + child: Opacity( + opacity: 0.5, + child: Row( + spacing: 4.0, + mainAxisSize: MainAxisSize.min, + children: [ + Avatar( + size: 18.0, + mxContent: member.avatarUrl, + name: member.calcDisplayname(), + userId: member.id, ), - child: Text( - member.calcDisplayname(), - style: TextStyle( - fontSize: 12.0, - color: theme.colorScheme.onPrimaryContainer, + ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 80.0, + ), + child: Text( + member.calcDisplayname(), + style: TextStyle( + fontSize: 12.0, + color: theme.colorScheme.onPrimaryContainer, + ), + overflow: TextOverflow.ellipsis, + maxLines: 1, ), - overflow: TextOverflow.ellipsis, - maxLines: 1, ), - ), - ], + ], + ), ), - ), - ); - }).toList(), - ), + ); + }).toList(), + ), + ], ], ), ); diff --git a/lib/pangea/activity_sessions/activity_status_message.dart b/lib/pangea/activity_sessions/activity_status_message.dart index 0250cb7b1..accaf8c35 100644 --- a/lib/pangea/activity_sessions/activity_status_message.dart +++ b/lib/pangea/activity_sessions/activity_status_message.dart @@ -20,7 +20,7 @@ class ActivityStatusMessage extends StatelessWidget { return const SizedBox.shrink(); } - final role = room.activityRoles?.role(room.client.userID!); + final role = room.ownRole; if (role != null && !role.isFinished) { return const SizedBox.shrink(); } diff --git a/lib/pangea/activity_sessions/activity_unfinished_status_message.dart b/lib/pangea/activity_sessions/activity_unfinished_status_message.dart index 27bbeb9ad..336f7db97 100644 --- a/lib/pangea/activity_sessions/activity_unfinished_status_message.dart +++ b/lib/pangea/activity_sessions/activity_unfinished_status_message.dart @@ -72,46 +72,47 @@ class ActivityUnfinishedStatusMessageState ), const SizedBox(height: 16.0), ], - ElevatedButton( - style: ElevatedButton.styleFrom( - padding: const EdgeInsets.symmetric( - horizontal: 12.0, - vertical: 8.0, + if (completed || remainingRoles > 0) + ElevatedButton( + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric( + horizontal: 12.0, + vertical: 8.0, + ), + foregroundColor: theme.colorScheme.onPrimaryContainer, + backgroundColor: theme.colorScheme.primaryContainer, ), - foregroundColor: theme.colorScheme.onPrimaryContainer, - backgroundColor: theme.colorScheme.primaryContainer, - ), - onPressed: completed - ? () { - showFutureLoadingDialog( - context: context, - future: widget.room.continueActivity, - ); - } - : _selectedRoleId != null - ? () { - showFutureLoadingDialog( - context: context, - future: () => widget.room.joinActivity( - availableRoles[_selectedRoleId!]!, - ), - ); - } - : 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, + onPressed: completed + ? () { + showFutureLoadingDialog( + context: context, + future: widget.room.continueActivity, + ); + } + : _selectedRoleId != null + ? () { + showFutureLoadingDialog( + context: context, + future: () => widget.room.joinActivity( + availableRoles[_selectedRoleId!]!, + ), + ); + } + : 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, + ), ), - ), - ], + ], + ), ), - ), ], ); }