diff --git a/lib/pangea/activity_sessions/activity_participant_indicator.dart b/lib/pangea/activity_sessions/activity_participant_indicator.dart index 2b88eab67..58ba597aa 100644 --- a/lib/pangea/activity_sessions/activity_participant_indicator.dart +++ b/lib/pangea/activity_sessions/activity_participant_indicator.dart @@ -97,9 +97,10 @@ class ActivityParticipantIndicator extends StatelessWidget { ? theme.colorScheme.surfaceContainerHighest : theme.colorScheme.surface.withAlpha(130), ), - constraints: const BoxConstraints(maxWidth: 200.0), + height: 125.0, + constraints: const BoxConstraints(maxWidth: 100.0), child: Column( - mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ shimmer && !selected ? Shimmer.fromColors( diff --git a/lib/pangea/activity_sessions/activity_user_summaries_widget.dart b/lib/pangea/activity_sessions/activity_user_summaries_widget.dart index 797fbf444..fd4c9340b 100644 --- a/lib/pangea/activity_sessions/activity_user_summaries_widget.dart +++ b/lib/pangea/activity_sessions/activity_user_summaries_widget.dart @@ -9,6 +9,7 @@ import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pages/chat/chat.dart'; import 'package:fluffychat/pangea/activity_sessions/activity_participant_indicator.dart'; +import 'package:fluffychat/pangea/activity_sessions/activity_role_model.dart'; import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart'; import 'package:fluffychat/pangea/activity_summary/activity_summary_response_model.dart'; import 'package:fluffychat/widgets/avatar.dart'; @@ -87,6 +88,38 @@ class ButtonControlledCarouselView extends StatelessWidget { required this.controller, }); + void _scrollToUser( + ActivityRoleModel role, + int index, + double cardWidth, + ) { + controller.activityController.highlightRole(role); + + final scrollController = controller.activityController.carouselController; + + if (!scrollController.hasClients) return; + + const spacing = 5.0; + final itemExtent = cardWidth + spacing; + + final viewportWidth = scrollController.position.viewportDimension; + + final itemCenter = (index * itemExtent) + (cardWidth / 2); + + final targetOffset = itemCenter - (viewportWidth / 2); + + final clampedOffset = targetOffset.clamp( + scrollController.position.minScrollExtent, + scrollController.position.maxScrollExtent, + ); + + scrollController.animateTo( + clampedOffset, + duration: const Duration(milliseconds: 300), + curve: Curves.easeOutCubic, + ); + } + @override Widget build(BuildContext context) { final room = controller.room; @@ -101,6 +134,11 @@ class ButtonControlledCarouselView extends StatelessWidget { ), ) .toList(); + if (userSummaries.isNotEmpty) { + userSummaries.add(userSummaries.first); + userSummaries.add(userSummaries.first); + userSummaries.add(userSummaries.first); + } final isColumnMode = FluffyThemes.isColumnMode(context); @@ -114,12 +152,14 @@ class ButtonControlledCarouselView extends StatelessWidget { children: [ SizedBox( height: 270.0, - child: ListView( + child: ListView.builder( key: PageStorageKey('summaries-carousel-${room.id}'), shrinkWrap: true, controller: controller.activityController.carouselController, scrollDirection: Axis.horizontal, - children: userSummaries.mapIndexed((i, p) { + itemCount: userSummaries.length, + itemBuilder: (context, i) { + final p = userSummaries[i]; final user = room.getParticipants().firstWhereOrNull( (u) => u.id == p.participantId, ); @@ -185,7 +225,6 @@ class ButtonControlledCarouselView extends StatelessWidget { alignment: WrapAlignment.center, spacing: 12, runSpacing: 8, - //crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( p.cefrLevel, @@ -232,62 +271,40 @@ class ButtonControlledCarouselView extends StatelessWidget { ], ), ); - }).toList(), + }, ), ), const SizedBox(height: 12), - ValueListenableBuilder( - valueListenable: controller.activityController.highlightedRole, - builder: (context, highlightedRole, __) { - return Row( - mainAxisSize: MainAxisSize.min, - children: userSummaries.mapIndexed((i, p) { - final user = room.getParticipants().firstWhereOrNull( - (u) => u.id == p.participantId, - ); - final userRole = assignedRoles.values.firstWhere( - (role) => role.userId == p.participantId, - ); - final userRoleInfo = availableRoles[userRole.id]!; - return ActivityParticipantIndicator( - name: userRoleInfo.name, - userId: p.participantId, - user: user, - borderRadius: BorderRadius.circular(4), - selected: highlightedRole?.id == userRole.id, - onTap: () { - controller.activityController.highlightRole(userRole); - - final scrollController = - controller.activityController.carouselController; - - if (!scrollController.hasClients) return; - - const spacing = 5.0; - final itemExtent = cardWidth + spacing; - - final viewportWidth = - scrollController.position.viewportDimension; - - final itemCenter = (i * itemExtent) + (cardWidth / 2); - - final targetOffset = itemCenter - (viewportWidth / 2); - - final clampedOffset = targetOffset.clamp( - scrollController.position.minScrollExtent, - scrollController.position.maxScrollExtent, - ); - - scrollController.animateTo( - clampedOffset, - duration: const Duration(milliseconds: 300), - curve: Curves.easeOutCubic, - ); - }, - ); - }).toList(), - ); - }, + SizedBox( + height: 125.0, + child: ValueListenableBuilder( + valueListenable: controller.activityController.highlightedRole, + builder: (context, highlightedRole, __) { + return ListView.builder( + shrinkWrap: true, + scrollDirection: Axis.horizontal, + itemCount: userSummaries.length, + itemBuilder: (context, index) { + final p = userSummaries[index]; + final user = room.getParticipants().firstWhereOrNull( + (u) => u.id == p.participantId, + ); + final userRole = assignedRoles.values.firstWhere( + (role) => role.userId == p.participantId, + ); + final userRoleInfo = availableRoles[userRole.id]!; + return ActivityParticipantIndicator( + name: userRoleInfo.name, + userId: p.participantId, + user: user, + borderRadius: BorderRadius.circular(4), + selected: highlightedRole?.id == userRole.id, + onTap: () => _scrollToUser(userRole, index, cardWidth), + ); + }, + ); + }, + ), ), ], );