refactor: use membership summary from room_preview response to tell which users have left an activity session
This commit is contained in:
parent
104cb817d6
commit
968059f818
5 changed files with 89 additions and 21 deletions
|
|
@ -154,7 +154,7 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage>
|
|||
|
||||
final availableRoles = activity!.roles;
|
||||
final assignedRoles = activityRoom?.assignedRoles ??
|
||||
roomSummaries?[widget.roomId]?.activityRoles.roles ??
|
||||
roomSummaries?[widget.roomId]?.joinedUsersWithRoles ??
|
||||
{};
|
||||
final unassignedIds = availableRoles.keys
|
||||
.where((id) => !assignedRoles.containsKey(id))
|
||||
|
|
@ -401,6 +401,14 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage>
|
|||
}
|
||||
|
||||
Future<void> joinActivityByRoomId(String roomId) async {
|
||||
final room = Matrix.of(context).client.getRoomById(roomId);
|
||||
if (room != null && room.membership == Membership.join) {
|
||||
widget.parentId != null
|
||||
? context.go("/rooms/spaces/${widget.parentId}/$roomId")
|
||||
: context.go("/rooms/$roomId");
|
||||
return;
|
||||
}
|
||||
|
||||
final resp = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () async {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import 'package:fluffychat/config/themes.dart';
|
|||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/activity_feedback/activity_feedback_repo.dart';
|
||||
import 'package:fluffychat/pangea/activity_feedback/activity_feedback_request.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_sessions/activity_session_start/activity_feedback_request_dialog.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_session_start/activity_feedback_response_dialog.dart';
|
||||
|
|
@ -153,8 +154,7 @@ class ActivitySessionStartView extends StatelessWidget {
|
|||
assignedRoles: controller
|
||||
.roomSummaries?[
|
||||
controller.widget.roomId]
|
||||
?.activityRoles
|
||||
.roles ??
|
||||
?.joinedUsersWithRoles ??
|
||||
{},
|
||||
),
|
||||
if (controller.courseParent != null)
|
||||
|
|
@ -456,10 +456,23 @@ class _ActivityStatuses extends StatelessWidget {
|
|||
final roomId = e.key;
|
||||
final room =
|
||||
Matrix.of(context).client.getRoomById(roomId);
|
||||
|
||||
final activityPlan =
|
||||
room?.activityPlan ?? e.value.activityPlan;
|
||||
final activityRoles =
|
||||
room?.assignedRoles ?? e.value.activityRoles.roles;
|
||||
|
||||
// If activity is completed, show all roles, even for users who have left the
|
||||
// room (like the bot). Otherwise, show only joined users with roles
|
||||
Map<String, ActivityRoleModel> activityRoles =
|
||||
status == ActivitySummaryStatus.completed
|
||||
? e.value.activityRoles.roles
|
||||
: e.value.joinedUsersWithRoles;
|
||||
|
||||
// If the user is in the activity room and it's not completed, use the room's
|
||||
// state events to determine roles to update them in real-time
|
||||
if (room?.assignedRoles != null &&
|
||||
status != ActivitySummaryStatus.completed) {
|
||||
activityRoles = room!.assignedRoles!;
|
||||
}
|
||||
|
||||
return ListTile(
|
||||
title: OpenRolesIndicator(
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import 'package:matrix/matrix.dart';
|
|||
import 'package:matrix/matrix_api_lite/generated/api.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/activity_planner/activity_plan_model.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_role_model.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_roles_model.dart';
|
||||
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
|
||||
|
||||
|
|
@ -64,12 +65,31 @@ class RoomSummariesResponse {
|
|||
class RoomSummaryResponse {
|
||||
final ActivityPlanModel activityPlan;
|
||||
final ActivityRolesModel activityRoles;
|
||||
final Map<String, String> membershipSummary;
|
||||
|
||||
RoomSummaryResponse({
|
||||
required this.activityPlan,
|
||||
required this.activityRoles,
|
||||
required this.membershipSummary,
|
||||
});
|
||||
|
||||
Membership? getMembershipForUserId(String userId) {
|
||||
final membershipString = membershipSummary[userId];
|
||||
if (membershipString == null) return null;
|
||||
return Membership.values.firstWhere(
|
||||
(m) => m.name == membershipString,
|
||||
orElse: () => Membership.join,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, ActivityRoleModel> get joinedUsersWithRoles {
|
||||
return Map.fromEntries(
|
||||
activityRoles.roles.entries.where(
|
||||
(role) => getMembershipForUserId(role.value.userId) == Membership.join,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
factory RoomSummaryResponse.fromJson(Map<String, dynamic> json) {
|
||||
return RoomSummaryResponse(
|
||||
activityPlan: ActivityPlanModel.fromJson(
|
||||
|
|
@ -78,6 +98,9 @@ class RoomSummaryResponse {
|
|||
activityRoles: ActivityRolesModel.fromJson(
|
||||
json[PangeaEventTypes.activityRole]?["default"]?["content"] ?? {},
|
||||
),
|
||||
membershipSummary: Map<String, String>.from(
|
||||
json['membership_summary'] ?? {},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -85,6 +108,7 @@ class RoomSummaryResponse {
|
|||
return {
|
||||
PangeaEventTypes.activityPlan: activityPlan.toJson(),
|
||||
PangeaEventTypes.activityRole: activityRoles.toJson(),
|
||||
'membership_summary': membershipSummary,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ class CourseChatsController extends State<CourseChats>
|
|||
}
|
||||
|
||||
final activity = summary.activityPlan;
|
||||
final users = summary.activityRoles.roles.values.toList();
|
||||
final users = summary.joinedUsersWithRoles;
|
||||
|
||||
if (users.isEmpty || !validIDs.contains(activity.activityId)) {
|
||||
continue;
|
||||
|
|
@ -154,7 +154,7 @@ class CourseChatsController extends State<CourseChats>
|
|||
sessionsMap[activity]!.add(
|
||||
ExtendedSpaceRoomsChunk(
|
||||
chunk: chunk,
|
||||
assignedRoles: users,
|
||||
assignedRoles: users.values.toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,38 @@ mixin ActivitySummariesProvider<T extends StatefulWidget> on State<T> {
|
|||
}
|
||||
}
|
||||
|
||||
bool isActivityStarted(String roomId) {
|
||||
if (isActivityFinished(roomId)) return true;
|
||||
final roomSummary = roomSummaries?[roomId];
|
||||
if (roomSummary == null) return false;
|
||||
|
||||
final activityPlan = roomSummary.activityPlan;
|
||||
final assignedRoles = roomSummary.joinedUsersWithRoles;
|
||||
return activityPlan.roles.length - assignedRoles.length <= 0;
|
||||
}
|
||||
|
||||
bool isActivityFinished(String roomId) {
|
||||
final roomSummary = roomSummaries?[roomId];
|
||||
if (roomSummary == null) return false;
|
||||
|
||||
final activityRoles = roomSummary.activityRoles;
|
||||
final roles = activityRoles.roles.values.where(
|
||||
(r) => r.userId != BotName.byEnvironment,
|
||||
);
|
||||
|
||||
if (roles.isEmpty) return false;
|
||||
if (!roles.any((r) => r.isFinished)) return false;
|
||||
|
||||
return roles.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 membership = roomSummary.getMembershipForUserId(r.userId);
|
||||
return membership == null || membership != Membership.join;
|
||||
});
|
||||
}
|
||||
|
||||
Map<String, RoomSummaryResponse> activitySessions(String activityId) =>
|
||||
Map.fromEntries(
|
||||
roomSummaries?.entries
|
||||
|
|
@ -62,17 +94,13 @@ mixin ActivitySummariesProvider<T extends StatefulWidget> on State<T> {
|
|||
for (final entry in sessions.entries) {
|
||||
final session = entry.value;
|
||||
final roomId = entry.key;
|
||||
final roles = session.activityRoles.roles.values;
|
||||
|
||||
if (roles.isNotEmpty &&
|
||||
(roles.any((r) => r.isArchived) ||
|
||||
roles.every((r) => r.isFinished))) {
|
||||
if (isActivityFinished(roomId)) {
|
||||
statuses[ActivitySummaryStatus.completed]![roomId] = session;
|
||||
} else if (session.activityRoles.roles.length <
|
||||
session.activityPlan.req.numberOfParticipants) {
|
||||
statuses[ActivitySummaryStatus.notStarted]![roomId] = session;
|
||||
} else {
|
||||
} else if (isActivityStarted(roomId)) {
|
||||
statuses[ActivitySummaryStatus.inProgress]![roomId] = session;
|
||||
} else {
|
||||
statuses[ActivitySummaryStatus.notStarted]![roomId] = session;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,12 +119,7 @@ mixin ActivitySummariesProvider<T extends StatefulWidget> on State<T> {
|
|||
continue;
|
||||
}
|
||||
|
||||
final isOpen =
|
||||
!summary.activityRoles.roles.values.any((r) => r.isArchived) &&
|
||||
(summary.activityRoles.roles.length <
|
||||
summary.activityPlan.req.numberOfParticipants);
|
||||
|
||||
if (isOpen) {
|
||||
if (!isActivityStarted(roomId)) {
|
||||
sessions.add(roomId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue