chore: simplify activity summary display, add activity summary widget to chat event list
This commit is contained in:
parent
25e72f440d
commit
1e3529180b
8 changed files with 286 additions and 391 deletions
|
|
@ -5192,5 +5192,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"noDataFound": "No data found"
|
||||
"noDataFound": "No data found",
|
||||
"activityFinishedMessage": "All Finished!"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import 'package:fluffychat/pages/chat/event_info_dialog.dart';
|
|||
import 'package:fluffychat/pages/chat/events/audio_player.dart';
|
||||
import 'package:fluffychat/pages/chat/recording_dialog.dart';
|
||||
import 'package:fluffychat/pages/chat_details/chat_details.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_role_model.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/gain_points_animation.dart';
|
||||
|
|
@ -2180,6 +2181,12 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
closePrevOverlay: false,
|
||||
);
|
||||
}
|
||||
|
||||
ActivityRoleModel? highlightedRole;
|
||||
|
||||
void highlightRole(ActivityRoleModel role) {
|
||||
if (mounted) setState(() => highlightedRole = role);
|
||||
}
|
||||
// Pangea#
|
||||
|
||||
late final ValueNotifier<bool> _displayChatDetailsColumn;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import 'package:fluffychat/pages/chat/events/message.dart';
|
|||
import 'package:fluffychat/pages/chat/seen_by_row.dart';
|
||||
import 'package:fluffychat/pages/chat/typing_indicators.dart';
|
||||
import 'package:fluffychat/pangea/activity_planner/activity_plan_message.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_finished_status_message.dart';
|
||||
import 'package:fluffychat/pangea/events/extensions/pangea_event_extension.dart';
|
||||
import 'package:fluffychat/utils/account_config.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart';
|
||||
|
|
@ -91,7 +92,10 @@ class ChatEventList extends StatelessWidget {
|
|||
}
|
||||
|
||||
// Request history button or progress indicator:
|
||||
if (i == events.length + 1) {
|
||||
// #Pangea
|
||||
// if (i == events.length + 1) {
|
||||
if (i == events.length + 2) {
|
||||
// Pangea#
|
||||
if (timeline.isRequestingHistory) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(strokeWidth: 2),
|
||||
|
|
@ -118,7 +122,17 @@ class ChatEventList extends StatelessWidget {
|
|||
}
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
i--;
|
||||
|
||||
// #Pangea
|
||||
if (i == 1) {
|
||||
return ActivityFinishedStatusMessage(controller: controller);
|
||||
}
|
||||
// Pangea#
|
||||
|
||||
// #Pangea
|
||||
// i--;
|
||||
i = i - 2;
|
||||
// Pangea#
|
||||
|
||||
// The message at this index:
|
||||
final event = events[i];
|
||||
|
|
@ -193,7 +207,10 @@ class ChatEventList extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
},
|
||||
childCount: events.length + 2,
|
||||
// #Pangea
|
||||
// childCount: events.length + 2,
|
||||
childCount: events.length + 3,
|
||||
// Pangea#
|
||||
findChildIndexCallback: (key) =>
|
||||
controller.findChildIndexCallback(key, thisEventsKeyMap),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pages/chat/chat.dart';
|
||||
import 'package:fluffychat/pangea/activity_planner/activity_plan_model.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_participant_indicator.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_results_carousel.dart';
|
||||
|
|
@ -14,301 +13,217 @@ import 'package:fluffychat/pangea/activity_sessions/activity_role_model.dart';
|
|||
import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart';
|
||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:fluffychat/widgets/mxc_image.dart';
|
||||
|
||||
class ActivityFinishedStatusMessage extends StatefulWidget {
|
||||
final Room room;
|
||||
class ActivityFinishedStatusMessage extends StatelessWidget {
|
||||
final ChatController controller;
|
||||
|
||||
const ActivityFinishedStatusMessage({
|
||||
super.key,
|
||||
required this.room,
|
||||
required this.controller,
|
||||
});
|
||||
|
||||
@override
|
||||
ActivityFinishedStatusMessageState createState() =>
|
||||
ActivityFinishedStatusMessageState();
|
||||
}
|
||||
|
||||
class ActivityFinishedStatusMessageState
|
||||
extends State<ActivityFinishedStatusMessage> {
|
||||
ActivityRoleModel? _highlightedRole;
|
||||
bool _expanded = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_setDefaultHighlightedRole();
|
||||
|
||||
if (widget.room.activityIsFinished && widget.room.activitySummary == null) {
|
||||
widget.room.fetchSummaries();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(ActivityFinishedStatusMessage oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
_setDefaultHighlightedRole();
|
||||
}
|
||||
|
||||
Map<String, ActivityRole> get _roles => widget.room.activityPlan?.roles ?? {};
|
||||
|
||||
void _setExpanded(bool expanded) {
|
||||
if (mounted) setState(() => _expanded = expanded);
|
||||
}
|
||||
|
||||
int get _hightlightedRoleIndex {
|
||||
if (_highlightedRole == null) {
|
||||
return -1; // No highlighted role
|
||||
}
|
||||
return rolesWithSummaries.indexOf(_highlightedRole!);
|
||||
}
|
||||
|
||||
void _setDefaultHighlightedRole() {
|
||||
if (_hightlightedRoleIndex >= 0) return;
|
||||
|
||||
final roles = rolesWithSummaries;
|
||||
_highlightedRole = roles.firstWhereOrNull(
|
||||
(r) => r.userId == widget.room.client.userID,
|
||||
);
|
||||
|
||||
if (_highlightedRole == null && roles.isNotEmpty) {
|
||||
_highlightedRole = roles.first;
|
||||
}
|
||||
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
|
||||
void _highlightRole(ActivityRoleModel role) {
|
||||
if (mounted) setState(() => _highlightedRole = role);
|
||||
}
|
||||
|
||||
bool get _canMoveLeft =>
|
||||
_hightlightedRoleIndex > 0 && _highlightedRole != null;
|
||||
|
||||
bool get _canMoveRight =>
|
||||
_hightlightedRoleIndex < rolesWithSummaries.length - 1 &&
|
||||
_highlightedRole != null;
|
||||
|
||||
void _moveLeft() {
|
||||
if (_hightlightedRoleIndex > 0) {
|
||||
_highlightRole(rolesWithSummaries[_hightlightedRoleIndex - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
void _moveRight() {
|
||||
if (_hightlightedRoleIndex < rolesWithSummaries.length - 1) {
|
||||
_highlightRole(rolesWithSummaries[_hightlightedRoleIndex + 1]);
|
||||
}
|
||||
}
|
||||
Map<String, ActivityRole> get _roles =>
|
||||
controller.room.activityPlan?.roles ?? {};
|
||||
|
||||
Future<void> _archiveToAnalytics() async {
|
||||
await widget.room.archiveActivity();
|
||||
await controller.room.archiveActivity();
|
||||
await MatrixState.pangeaController.putAnalytics
|
||||
.sendActivityAnalytics(widget.room.id);
|
||||
.sendActivityAnalytics(controller.room.id);
|
||||
}
|
||||
|
||||
List<ActivityRoleModel> get rolesWithSummaries {
|
||||
if (widget.room.activitySummary?.summary == null) {
|
||||
List<ActivityRoleModel> get _rolesWithSummaries {
|
||||
if (controller.room.activitySummary?.summary == null) {
|
||||
return <ActivityRoleModel>[];
|
||||
}
|
||||
|
||||
final roles = widget.room.activityRoles;
|
||||
final roles = controller.room.activityRoles;
|
||||
return roles?.roles.values.where((role) {
|
||||
return widget.room.activitySummary!.summary!.participants.any(
|
||||
return controller.room.activitySummary!.summary!.participants.any(
|
||||
(p) => p.participantId == role.userId,
|
||||
);
|
||||
}).toList() ??
|
||||
[];
|
||||
}
|
||||
|
||||
ActivityRoleModel? get _highlightedRole {
|
||||
if (controller.highlightedRole != null) {
|
||||
return controller.highlightedRole;
|
||||
}
|
||||
|
||||
return _rolesWithSummaries.firstWhereOrNull(
|
||||
(r) => r.userId == controller.room.client.userID,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final summary = widget.room.activitySummary;
|
||||
final imageURL = widget.room.activityPlan!.imageURL;
|
||||
if (!controller.room.showActivityChatUI ||
|
||||
!controller.room.activityIsFinished) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
final summary = controller.room.activitySummary;
|
||||
|
||||
final theme = Theme.of(context);
|
||||
final isColumnMode = MediaQuery.of(context).size.width < 600;
|
||||
|
||||
final user = widget.room.getParticipants().firstWhereOrNull(
|
||||
final user = controller.room.getParticipants().firstWhereOrNull(
|
||||
(u) => u.id == _highlightedRole?.userId,
|
||||
);
|
||||
|
||||
final userSummary =
|
||||
widget.room.activitySummary?.summary?.participants.firstWhereOrNull(
|
||||
(p) => p.participantId == _highlightedRole!.userId,
|
||||
controller.room.activitySummary?.summary?.participants.firstWhereOrNull(
|
||||
(p) => p.participantId == _highlightedRole?.userId,
|
||||
);
|
||||
|
||||
return AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: _expanded
|
||||
? [
|
||||
if (summary?.summary != null) ...[
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.expand_more,
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
child: Center(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: FluffyThemes.columnWidth * 1.5,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (summary?.summary != null) ...[
|
||||
Text(
|
||||
L10n.of(context).activityFinishedMessage,
|
||||
style: const TextStyle(fontSize: 18.0),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Text(
|
||||
summary!.summary!.summary,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontSize: 14.0,
|
||||
),
|
||||
onPressed: () => _setExpanded(!_expanded),
|
||||
),
|
||||
const SizedBox(height: 8.0),
|
||||
if (imageURL != null)
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
child: imageURL.startsWith("mxc")
|
||||
? MxcImage(
|
||||
uri: Uri.parse(imageURL),
|
||||
width: 100.0,
|
||||
height: 100.0,
|
||||
cacheKey: widget.room.activityPlan!.bookmarkId,
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
: CachedNetworkImage(
|
||||
imageUrl: imageURL,
|
||||
fit: BoxFit.cover,
|
||||
width: 100.0,
|
||||
height: 100.0,
|
||||
placeholder: (
|
||||
context,
|
||||
url,
|
||||
) =>
|
||||
const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
errorWidget: (
|
||||
context,
|
||||
url,
|
||||
error,
|
||||
) =>
|
||||
const SizedBox(),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Text(
|
||||
summary!.summary!.summary,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: isColumnMode ? 16.0 : 12.0,
|
||||
),
|
||||
const SizedBox(height: 16.0),
|
||||
if (_highlightedRole != null && userSummary != null)
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.surfaceContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (_highlightedRole != null && userSummary != null)
|
||||
ActivityResultsCarousel(
|
||||
selectedRole: _highlightedRole!,
|
||||
moveLeft: _canMoveLeft ? _moveLeft : null,
|
||||
moveRight: _canMoveRight ? _moveRight : null,
|
||||
user: user,
|
||||
summary: userSummary,
|
||||
),
|
||||
const SizedBox(height: 8.0),
|
||||
Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
spacing: 12.0,
|
||||
runSpacing: 12.0,
|
||||
children: rolesWithSummaries.map(
|
||||
(role) {
|
||||
final user =
|
||||
widget.room.getParticipants().firstWhereOrNull(
|
||||
(u) => u.id == role.userId,
|
||||
child: Column(
|
||||
children: [
|
||||
ActivityResultsCarousel(
|
||||
selectedRole: _highlightedRole!,
|
||||
user: user,
|
||||
summary: userSummary,
|
||||
),
|
||||
Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
children: _rolesWithSummaries.map(
|
||||
(role) {
|
||||
final user = controller.room
|
||||
.getParticipants()
|
||||
.firstWhereOrNull(
|
||||
(u) => u.id == role.userId,
|
||||
);
|
||||
|
||||
return IntrinsicWidth(
|
||||
child: ActivityParticipantIndicator(
|
||||
availableRole: _roles[role.id]!,
|
||||
avatarUrl: _roles[role.id]?.avatarUrl ??
|
||||
user?.avatarUrl?.toString(),
|
||||
onTap: _highlightedRole == role
|
||||
? null
|
||||
: () => controller.highlightRole(role),
|
||||
assignedRole: role,
|
||||
selected: _highlightedRole == role,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
horizontal: 24.0,
|
||||
),
|
||||
borderRadius: BorderRadius.zero,
|
||||
),
|
||||
);
|
||||
|
||||
return ActivityParticipantIndicator(
|
||||
availableRole: _roles[role.id]!,
|
||||
avatarUrl: _roles[role.id]?.avatarUrl ??
|
||||
user?.avatarUrl?.toString(),
|
||||
onTap: _highlightedRole == role
|
||||
? null
|
||||
: () => _highlightRole(role),
|
||||
assignedRole: role,
|
||||
selected: _highlightedRole == role,
|
||||
);
|
||||
},
|
||||
).toList(),
|
||||
),
|
||||
const SizedBox(height: 20.0),
|
||||
] else if (summary?.isLoading ?? false)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
const CircularProgressIndicator.adaptive(),
|
||||
Text(L10n.of(context).loadingActivitySummary),
|
||||
],
|
||||
),
|
||||
)
|
||||
else if (summary?.hasError ?? false)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.school_outlined,
|
||||
size: 24.0,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Flexible(
|
||||
child: Text(
|
||||
L10n.of(context).activitySummaryError,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => widget.room.fetchSummaries(),
|
||||
child: Text(L10n.of(context).requestSummaries),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (!widget.room.isHiddenActivityRoom)
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12.0,
|
||||
vertical: 8.0,
|
||||
},
|
||||
).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
foregroundColor: theme.colorScheme.onPrimaryContainer,
|
||||
backgroundColor: theme.colorScheme.primaryContainer,
|
||||
),
|
||||
onPressed: () async {
|
||||
final resp = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: _archiveToAnalytics,
|
||||
);
|
||||
),
|
||||
const SizedBox(height: 20.0),
|
||||
] else if (summary?.isLoading ?? false)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
const CircularProgressIndicator.adaptive(),
|
||||
Text(L10n.of(context).loadingActivitySummary),
|
||||
],
|
||||
),
|
||||
)
|
||||
else if (summary?.hasError ?? false)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.school_outlined,
|
||||
size: 24.0,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Flexible(
|
||||
child: Text(
|
||||
L10n.of(context).activitySummaryError,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => controller.room.fetchSummaries(),
|
||||
child: Text(L10n.of(context).requestSummaries),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (!controller.room.isHiddenActivityRoom)
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12.0,
|
||||
vertical: 8.0,
|
||||
),
|
||||
foregroundColor: theme.colorScheme.onPrimaryContainer,
|
||||
backgroundColor: theme.colorScheme.primaryContainer,
|
||||
),
|
||||
onPressed: () async {
|
||||
final resp = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: _archiveToAnalytics,
|
||||
);
|
||||
|
||||
if (!resp.isError) {
|
||||
context.go(
|
||||
"/rooms/analytics?mode=activities",
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(L10n.of(context).archiveToAnalytics),
|
||||
],
|
||||
),
|
||||
if (!resp.isError) {
|
||||
context.go(
|
||||
"/rooms/analytics?mode=activities",
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(L10n.of(context).archiveToAnalytics),
|
||||
],
|
||||
),
|
||||
]
|
||||
: [
|
||||
if (summary != null)
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.expand_less,
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
onPressed: () => _setExpanded(!_expanded),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ class ActivityParticipantIndicator extends StatelessWidget {
|
|||
final bool selected;
|
||||
final double opacity;
|
||||
|
||||
final EdgeInsetsGeometry? padding;
|
||||
final BorderRadius? borderRadius;
|
||||
|
||||
const ActivityParticipantIndicator({
|
||||
super.key,
|
||||
required this.availableRole,
|
||||
|
|
@ -28,6 +31,8 @@ class ActivityParticipantIndicator extends StatelessWidget {
|
|||
this.selected = false,
|
||||
this.onTap,
|
||||
this.opacity = 1.0,
|
||||
this.padding,
|
||||
this.borderRadius,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -44,16 +49,15 @@ class ActivityParticipantIndicator extends StatelessWidget {
|
|||
return Opacity(
|
||||
opacity: opacity,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 4.0,
|
||||
horizontal: 8.0,
|
||||
),
|
||||
padding: padding ??
|
||||
const EdgeInsets.symmetric(
|
||||
vertical: 4.0,
|
||||
horizontal: 8.0,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
borderRadius: borderRadius ?? BorderRadius.circular(8.0),
|
||||
color: hovered || selected
|
||||
? theme.colorScheme.primaryContainer.withAlpha(
|
||||
selected ? 100 : 50,
|
||||
)
|
||||
? theme.colorScheme.surfaceContainerHighest
|
||||
: Colors.transparent,
|
||||
),
|
||||
child: Column(
|
||||
|
|
|
|||
|
|
@ -5,23 +5,16 @@ import 'package:matrix/matrix.dart';
|
|||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_role_model.dart';
|
||||
import 'package:fluffychat/pangea/activity_summary/activity_summary_response_model.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/pressable_button.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
|
||||
class ActivityResultsCarousel extends StatelessWidget {
|
||||
final ActivityRoleModel selectedRole;
|
||||
final ParticipantSummaryModel summary;
|
||||
|
||||
final VoidCallback? moveLeft;
|
||||
final VoidCallback? moveRight;
|
||||
|
||||
final User? user;
|
||||
|
||||
const ActivityResultsCarousel({
|
||||
super.key,
|
||||
required this.selectedRole,
|
||||
required this.moveLeft,
|
||||
required this.moveRight,
|
||||
required this.summary,
|
||||
this.user,
|
||||
});
|
||||
|
|
@ -31,111 +24,69 @@ class ActivityResultsCarousel extends StatelessWidget {
|
|||
final theme = Theme.of(context);
|
||||
final isColumnMode = FluffyThemes.isColumnMode(context);
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.arrow_back_ios_new),
|
||||
onPressed: moveLeft,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: PressableButton(
|
||||
onPressed: null,
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
color: theme.brightness == Brightness.dark
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.surfaceContainerHighest,
|
||||
colorFactor: theme.brightness == Brightness.dark ? 0.6 : 0.2,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.surfaceContainerHighest,
|
||||
),
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: isColumnMode ? 80.0 : 125.0,
|
||||
child: SingleChildScrollView(
|
||||
child: Text(
|
||||
summary.feedback,
|
||||
style: const TextStyle(fontSize: 12.0),
|
||||
),
|
||||
width: isColumnMode ? 225.0 : 175.0,
|
||||
child: Container(
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
Wrap(
|
||||
spacing: 8.0,
|
||||
runSpacing: 8.0,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
color: theme.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
child: Row(
|
||||
spacing: 4.0,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Avatar(
|
||||
size: isColumnMode ? 60.0 : 40.0,
|
||||
mxContent: user?.avatarUrl,
|
||||
name: user?.calcDisplayname() ??
|
||||
summary.participantId.localpart,
|
||||
userId: selectedRole.userId,
|
||||
const Icon(Icons.school, size: 12.0),
|
||||
Text(
|
||||
summary.cefrLevel,
|
||||
style: const TextStyle(
|
||||
fontSize: 12.0,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4.0),
|
||||
Text(
|
||||
selectedRole.role != null
|
||||
? "${selectedRole.role!} | ${selectedRole.userId.localpart}"
|
||||
: "${selectedRole.userId.localpart}",
|
||||
style: TextStyle(fontSize: isColumnMode ? 16.0 : 12.0),
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
Text(
|
||||
summary.feedback,
|
||||
style: TextStyle(fontSize: isColumnMode ? 12.0 : 8.0),
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
Wrap(
|
||||
spacing: 8.0,
|
||||
runSpacing: 8.0,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
spacing: 4.0,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.school, size: 12.0),
|
||||
Text(
|
||||
summary.cefrLevel,
|
||||
style: TextStyle(
|
||||
fontSize: isColumnMode ? 12.0 : 8.0,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
...summary.superlatives.map(
|
||||
(sup) => Container(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Text(
|
||||
sup,
|
||||
style: TextStyle(
|
||||
fontSize: isColumnMode ? 12.0 : 8.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
...summary.superlatives.map(
|
||||
(sup) => Container(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Text(
|
||||
sup,
|
||||
style: const TextStyle(
|
||||
fontSize: 12.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.arrow_forward_ios),
|
||||
onPressed: moveRight,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class ActivityStateEvent extends StatelessWidget {
|
|||
? 0.5
|
||||
: 1.0,
|
||||
avatarUrl:
|
||||
availableRole.avatarUrl ?? user?.avatarUrl.toString(),
|
||||
availableRole.avatarUrl ?? user?.avatarUrl?.toString(),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_finished_status_message.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_unfinished_status_message.dart';
|
||||
|
||||
|
|
@ -17,32 +16,33 @@ class ActivityStatusMessage extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!room.showActivityChatUI) {
|
||||
if (!room.showActivityChatUI || room.activityIsFinished) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
final role = room.activityRoles?.role(room.client.userID!);
|
||||
if (role != null && !role.isFinished) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Material(
|
||||
child: AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
child: room.isInactiveInActivity
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: FluffyThemes.isColumnMode(context) ? 32.0 : 16.0,
|
||||
left: 16.0,
|
||||
right: 16.0,
|
||||
),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: MediaQuery.of(context).size.height * 0.8,
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: room.activityIsFinished
|
||||
? ActivityFinishedStatusMessage(room: room)
|
||||
: ActivityUnfinishedStatusMessage(room: room),
|
||||
),
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: FluffyThemes.isColumnMode(context) ? 32.0 : 16.0,
|
||||
left: 16.0,
|
||||
right: 16.0,
|
||||
),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: MediaQuery.of(context).size.height * 0.8,
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: ActivityUnfinishedStatusMessage(room: room),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue