chore: add activity summaries loading indicator (#3633)

pull/2245/head
ggurdin 3 months ago committed by GitHub
parent 31c6228ca4
commit c283f157da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -5134,5 +5134,8 @@
},
"endActivityTitle": "I'm Done",
"endActivityDesc": "Did you complete the objectives?\nThis is your confirmation that you're stepping back from texting. But dont worry, the fun continues in the chat! Feel free to hang out and enjoy the show until everyone clicks 'Done'.",
"archiveToAnalytics": "Add to my Completed Activities"
"archiveToAnalytics": "Add to my Completed Activities",
"activitySummaryError": "Activity summaries unavailable",
"requestSummaries": "Request summaries",
"loadingActivitySummary": "Loading activity summary..."
}

@ -110,10 +110,13 @@ class ActivityFinishedStatusMessageState
}
List<ActivityRoleModel> get rolesWithSummaries {
if (widget.room.activitySummary == null) return <ActivityRoleModel>[];
if (widget.room.activitySummary?.summary == null) {
return <ActivityRoleModel>[];
}
final roles = widget.room.activityRoles;
return roles.where((role) {
return widget.room.activitySummary!.participants.any(
return widget.room.activitySummary!.summary!.participants.any(
(p) => p.participantId == role.userId,
);
}).toList();
@ -132,7 +135,7 @@ class ActivityFinishedStatusMessageState
);
final userSummary =
widget.room.activitySummary?.participants.firstWhereOrNull(
widget.room.activitySummary?.summary?.participants.firstWhereOrNull(
(p) => p.participantId == _highlightedRole!.userId,
);
@ -143,7 +146,7 @@ class ActivityFinishedStatusMessageState
crossAxisAlignment: CrossAxisAlignment.center,
children: _expanded
? [
if (summary != null) ...[
if (summary?.summary != null) ...[
IconButton(
icon: Icon(
Icons.expand_more,
@ -186,7 +189,7 @@ class ActivityFinishedStatusMessageState
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Text(
summary.summary,
summary!.summary!.summary,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: isColumnMode ? 16.0 : 12.0,
@ -219,7 +222,46 @@ class ActivityFinishedStatusMessageState
.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(

@ -6,9 +6,9 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/pangea/activity_planner/activity_plan_model.dart';
import 'package:fluffychat/pangea/activity_planner/activity_role_model.dart';
import 'package:fluffychat/pangea/activity_planner/bookmarked_activities_repo.dart';
import 'package:fluffychat/pangea/activity_summary/activity_summary_model.dart';
import 'package:fluffychat/pangea/activity_summary/activity_summary_repo.dart';
import 'package:fluffychat/pangea/activity_summary/activity_summary_request_model.dart';
import 'package:fluffychat/pangea/activity_summary/activity_summary_response_model.dart';
import 'package:fluffychat/pangea/chat_settings/utils/download_chat.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
@ -77,7 +77,7 @@ extension ActivityRoomExtension on Room {
}
Future<void> setActivitySummary(
ActivitySummaryResponseModel summary,
ActivitySummaryModel summary,
) async {
await client.setRoomStateWithKey(
id,
@ -88,7 +88,14 @@ extension ActivityRoomExtension on Room {
}
Future<void> fetchSummaries() async {
if (activitySummary != null) return;
if (activitySummary?.summary != null) return;
await setActivitySummary(
ActivitySummaryModel(
requestedAt: DateTime.now(),
summary: activitySummary?.summary,
),
);
final events = await getAllEvents(this);
final List<ActivitySummaryResultsMessage> messages = [];
@ -119,15 +126,37 @@ extension ActivityRoomExtension on Room {
messages.add(activityMessage);
}
final resp = await ActivitySummaryRepo.get(
ActivitySummaryRequestModel(
activity: activityPlan!,
activityResults: messages,
contentFeedback: [],
),
);
try {
final resp = await ActivitySummaryRepo.get(
ActivitySummaryRequestModel(
activity: activityPlan!,
activityResults: messages,
contentFeedback: [],
),
);
await setActivitySummary(resp);
await setActivitySummary(
ActivitySummaryModel(summary: resp),
);
} catch (e, s) {
ErrorHandler.logError(
e: e,
s: s,
data: {
"roomID": id,
"activityPlan": activityPlan?.toJson(),
"activityResults": messages.map((m) => m.toJson()).toList(),
},
);
if (activitySummary?.summary == null) {
await setActivitySummary(
ActivitySummaryModel(
errorAt: DateTime.now(),
),
);
}
}
}
Future<void> archiveActivity() async {
@ -182,12 +211,12 @@ extension ActivityRoomExtension on Room {
}
}
ActivitySummaryResponseModel? get activitySummary {
ActivitySummaryModel? get activitySummary {
final stateEvent = getState(PangeaEventTypes.activitySummary);
if (stateEvent == null) return null;
try {
return ActivitySummaryResponseModel.fromJson(stateEvent.content);
return ActivitySummaryModel.fromJson(stateEvent.content);
} catch (e, s) {
ErrorHandler.logError(
e: e,

@ -7,7 +7,7 @@ import 'package:fluffychat/pangea/activity_planner/activity_finished_status_mess
import 'package:fluffychat/pangea/activity_planner/activity_room_extension.dart';
import 'package:fluffychat/pangea/activity_planner/activity_unfinished_status_message.dart';
class ActivityStatusMessage extends StatefulWidget {
class ActivityStatusMessage extends StatelessWidget {
final Room room;
const ActivityStatusMessage({
@ -15,32 +15,16 @@ class ActivityStatusMessage extends StatefulWidget {
required this.room,
});
@override
ActivityStatusMessageState createState() => ActivityStatusMessageState();
}
class ActivityStatusMessageState extends State<ActivityStatusMessage> {
@override
void initState() {
super.initState();
if (widget.room.activityIsFinished && widget.room.activitySummary == null) {
widget.room.fetchSummaries().then((_) {
if (mounted) setState(() {});
});
}
}
@override
Widget build(BuildContext context) {
if (!widget.room.showActivityChatUI) {
if (!room.showActivityChatUI) {
return const SizedBox.shrink();
}
return Material(
child: AnimatedSize(
duration: FluffyThemes.animationDuration,
child: widget.room.isInactiveInActivity
child: room.isInactiveInActivity
? Padding(
padding: EdgeInsets.only(
bottom: FluffyThemes.isColumnMode(context) ? 32.0 : 16.0,
@ -52,9 +36,9 @@ class ActivityStatusMessageState extends State<ActivityStatusMessage> {
maxHeight: MediaQuery.of(context).size.height * 0.8,
),
child: SingleChildScrollView(
child: widget.room.activityIsFinished
? ActivityFinishedStatusMessage(room: widget.room)
: ActivityUnfinishedStatusMessage(room: widget.room),
child: room.activityIsFinished
? ActivityFinishedStatusMessage(room: room)
: ActivityUnfinishedStatusMessage(room: room),
),
),
)

@ -0,0 +1,45 @@
import 'package:fluffychat/pangea/activity_summary/activity_summary_response_model.dart';
class ActivitySummaryModel {
final ActivitySummaryResponseModel? summary;
final DateTime? requestedAt;
final DateTime? errorAt;
ActivitySummaryModel({
this.summary,
this.requestedAt,
this.errorAt,
});
Map<String, dynamic> toJson() {
return {
"summary": summary?.toJson(),
"requested_at": requestedAt?.toIso8601String(),
"error_at": errorAt?.toIso8601String(),
};
}
factory ActivitySummaryModel.fromJson(Map<String, dynamic> json) {
return ActivitySummaryModel(
summary: json['summary'] != null
? ActivitySummaryResponseModel.fromJson(json['summary'])
: null,
requestedAt: json['requested_at'] != null
? DateTime.parse(json['requested_at'])
: null,
errorAt:
json['error_at'] != null ? DateTime.parse(json['error_at']) : null,
);
}
bool get _hasTimeout =>
summary == null &&
requestedAt != null &&
requestedAt!.isBefore(
DateTime.now().subtract(const Duration(seconds: 30)),
);
bool get hasError => errorAt != null || _hasTimeout;
bool get isLoading => summary == null && requestedAt != null && !hasError;
}
Loading…
Cancel
Save