fix: update room summary model (#5543)
This commit is contained in:
parent
995c8a6e71
commit
b66aa5f9db
6 changed files with 119 additions and 34 deletions
|
|
@ -191,7 +191,7 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage>
|
|||
|
||||
final availableRoles = activity!.roles;
|
||||
final assignedRoles = activityRoom?.assignedRoles ??
|
||||
roomSummaries?[widget.roomId]?.activityRoles.roles ??
|
||||
roomSummaries?[widget.roomId]?.activityRoles?.roles ??
|
||||
{};
|
||||
final unassignedIds = availableRoles.keys
|
||||
.where((id) => !assignedRoles.containsKey(id))
|
||||
|
|
|
|||
|
|
@ -518,7 +518,7 @@ class _ActivityStatuses extends StatelessWidget {
|
|||
// room (like the bot). Otherwise, show only joined users with roles
|
||||
Map<String, ActivityRoleModel> activityRoles =
|
||||
status == ActivitySummaryStatus.completed
|
||||
? e.value.activityRoles.roles
|
||||
? (e.value.activityRoles?.roles ?? {})
|
||||
: e.value.joinedUsersWithRoles;
|
||||
|
||||
// If the user is in the activity room and it's not completed, use the room's
|
||||
|
|
@ -530,7 +530,7 @@ class _ActivityStatuses extends StatelessWidget {
|
|||
|
||||
return ListTile(
|
||||
title: OpenRolesIndicator(
|
||||
roles: activityPlan.roles.values
|
||||
roles: (activityPlan?.roles.values ?? [])
|
||||
.sorted((a, b) => a.id.compareTo(b.id))
|
||||
.toList(),
|
||||
assignedRoles: activityRoles.values.toList(),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:http/http.dart' hide Client;
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:matrix/matrix_api_lite/generated/api.dart';
|
||||
|
|
@ -7,6 +8,8 @@ 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/activity_summary/activity_summary_model.dart';
|
||||
import 'package:fluffychat/pangea/course_plans/courses/course_plan_event.dart';
|
||||
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
|
||||
|
||||
extension RoomSummaryExtension on Api {
|
||||
|
|
@ -52,27 +55,40 @@ class RoomSummariesResponse {
|
|||
});
|
||||
return RoomSummariesResponse(summaries: summaries);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
summaries.forEach((key, value) {
|
||||
json[key] = value.toJson();
|
||||
});
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
class RoomSummaryResponse {
|
||||
final ActivityPlanModel activityPlan;
|
||||
final ActivityRolesModel activityRoles;
|
||||
final ActivityPlanModel? activityPlan;
|
||||
final ActivityRolesModel? activityRoles;
|
||||
final ActivitySummaryModel? activitySummary;
|
||||
final CoursePlanEvent? coursePlan;
|
||||
|
||||
final JoinRules? joinRule;
|
||||
final Map<String, int>? powerLevels;
|
||||
final Map<String, String> membershipSummary;
|
||||
final String? displayName;
|
||||
final String? avatarUrl;
|
||||
|
||||
RoomSummaryResponse({
|
||||
required this.activityPlan,
|
||||
required this.activityRoles,
|
||||
required this.membershipSummary,
|
||||
this.activityPlan,
|
||||
this.activityRoles,
|
||||
this.activitySummary,
|
||||
this.coursePlan,
|
||||
this.joinRule,
|
||||
this.powerLevels,
|
||||
this.displayName,
|
||||
this.avatarUrl,
|
||||
});
|
||||
|
||||
List<String> get adminUserIDs {
|
||||
if (powerLevels == null) return [];
|
||||
return powerLevels!.entries
|
||||
.where((entry) => entry.value >= 100)
|
||||
.map((entry) => entry.key)
|
||||
.toList();
|
||||
}
|
||||
|
||||
Membership? getMembershipForUserId(String userId) {
|
||||
final membershipString = membershipSummary[userId];
|
||||
if (membershipString == null) return null;
|
||||
|
|
@ -83,32 +99,93 @@ class RoomSummaryResponse {
|
|||
}
|
||||
|
||||
Map<String, ActivityRoleModel> get joinedUsersWithRoles {
|
||||
if (activityRoles == null) return {};
|
||||
return Map.fromEntries(
|
||||
activityRoles.roles.entries.where(
|
||||
activityRoles!.roles.entries.where(
|
||||
(role) => getMembershipForUserId(role.value.userId) == Membership.join,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
factory RoomSummaryResponse.fromJson(Map<String, dynamic> json) {
|
||||
final planEntry =
|
||||
json[PangeaEventTypes.activityPlan]?["default"]?["content"];
|
||||
ActivityPlanModel? plan;
|
||||
if (planEntry != null && planEntry is Map<String, dynamic>) {
|
||||
plan = ActivityPlanModel.fromJson(planEntry);
|
||||
}
|
||||
|
||||
final rolesEntry =
|
||||
json[PangeaEventTypes.activityRole]?["default"]?["content"];
|
||||
ActivityRolesModel? roles;
|
||||
if (rolesEntry != null && rolesEntry is Map<String, dynamic>) {
|
||||
roles = ActivityRolesModel.fromJson(rolesEntry);
|
||||
}
|
||||
|
||||
final summaryEntry =
|
||||
json[PangeaEventTypes.activitySummary]?["default"]?["content"];
|
||||
ActivitySummaryModel? summary;
|
||||
if (summaryEntry != null && summaryEntry is Map<String, dynamic>) {
|
||||
summary = ActivitySummaryModel.fromJson(summaryEntry);
|
||||
}
|
||||
|
||||
final coursePlanEntry =
|
||||
json[PangeaEventTypes.coursePlan]?["default"]?["content"];
|
||||
CoursePlanEvent? coursePlan;
|
||||
if (coursePlanEntry != null && coursePlanEntry is Map<String, dynamic>) {
|
||||
coursePlan = CoursePlanEvent.fromJson(coursePlanEntry);
|
||||
}
|
||||
|
||||
final powerLevelsEntry =
|
||||
json[EventTypes.RoomPowerLevels]?['default']?['content']?['users'];
|
||||
Map<String, int>? powerLevels;
|
||||
if (powerLevelsEntry != null) {
|
||||
powerLevels = Map<String, int>.from(powerLevelsEntry);
|
||||
}
|
||||
|
||||
final joinRulesString =
|
||||
json[EventTypes.RoomJoinRules]?['default']?['content']?['join_rule'];
|
||||
JoinRules? joinRule;
|
||||
if (joinRulesString != null && joinRulesString is String) {
|
||||
joinRule = JoinRules.values
|
||||
.singleWhereOrNull((element) => element.text == joinRulesString);
|
||||
}
|
||||
|
||||
final displayName =
|
||||
json[EventTypes.RoomName]?['default']?['content']?['name'] as String?;
|
||||
|
||||
String? avatarUrl =
|
||||
json[EventTypes.RoomAvatar]?['default']?['content']?['url'] as String?;
|
||||
if (avatarUrl != null && Uri.tryParse(avatarUrl) == null) {
|
||||
avatarUrl = null;
|
||||
}
|
||||
|
||||
return RoomSummaryResponse(
|
||||
activityPlan: ActivityPlanModel.fromJson(
|
||||
json[PangeaEventTypes.activityPlan]?["default"]?["content"] ?? {},
|
||||
),
|
||||
activityRoles: ActivityRolesModel.fromJson(
|
||||
json[PangeaEventTypes.activityRole]?["default"]?["content"] ?? {},
|
||||
),
|
||||
activityPlan: plan,
|
||||
activityRoles: roles,
|
||||
activitySummary: summary,
|
||||
coursePlan: coursePlan,
|
||||
powerLevels: powerLevels,
|
||||
joinRule: joinRule,
|
||||
membershipSummary: Map<String, String>.from(
|
||||
json['membership_summary'] ?? {},
|
||||
),
|
||||
displayName: displayName,
|
||||
avatarUrl: avatarUrl,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
PangeaEventTypes.activityPlan: activityPlan.toJson(),
|
||||
PangeaEventTypes.activityRole: activityRoles.toJson(),
|
||||
'membership_summary': membershipSummary,
|
||||
'activityPlan': activityPlan?.toJson(),
|
||||
'activityRoles': activityRoles?.toJson(),
|
||||
'activitySummary': activitySummary?.toJson(),
|
||||
'coursePlan': coursePlan?.toJson(),
|
||||
'joinRule': joinRule?.text,
|
||||
'powerLevels': powerLevels,
|
||||
'membershipSummary': membershipSummary,
|
||||
'displayName': displayName,
|
||||
'avatarUrl': avatarUrl,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,9 +133,13 @@ class CourseChatsController extends State<CourseChats>
|
|||
}
|
||||
|
||||
final activity = summary.activityPlan;
|
||||
final roles = summary.activityRoles;
|
||||
final users = summary.joinedUsersWithRoles;
|
||||
|
||||
if (users.isEmpty || !validIDs.contains(activity.activityId)) {
|
||||
if (activity == null ||
|
||||
roles == null ||
|
||||
users.isEmpty ||
|
||||
!validIDs.contains(activity.activityId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +152,7 @@ class CourseChatsController extends State<CourseChats>
|
|||
// It's possible for users to finish an activity and then for some of the
|
||||
// users to leave, but if the activity was archived by anyone, that means
|
||||
// it was full at some point.
|
||||
if (summary.activityRoles.roles.values.any((role) => role.isArchived)) {
|
||||
if (roles.roles.values.any((role) => role.isArchived)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ mixin ActivitySummariesProvider<T extends StatefulWidget> on State<T> {
|
|||
|
||||
final activityPlan = roomSummary.activityPlan;
|
||||
final assignedRoles = roomSummary.joinedUsersWithRoles;
|
||||
if (activityPlan == null) return false;
|
||||
return activityPlan.roles.length - assignedRoles.length <= 0;
|
||||
}
|
||||
|
||||
|
|
@ -56,6 +57,7 @@ mixin ActivitySummariesProvider<T extends StatefulWidget> on State<T> {
|
|||
if (roomSummary == null) return false;
|
||||
|
||||
final activityRoles = roomSummary.activityRoles;
|
||||
if (activityRoles == null) return false;
|
||||
final roles = activityRoles.roles.values.where(
|
||||
(r) => r.userId != BotName.byEnvironment,
|
||||
);
|
||||
|
|
@ -76,7 +78,7 @@ mixin ActivitySummariesProvider<T extends StatefulWidget> on State<T> {
|
|||
Map<String, RoomSummaryResponse> activitySessions(String activityId) =>
|
||||
Map.fromEntries(
|
||||
roomSummaries?.entries
|
||||
.where((v) => v.value.activityPlan.activityId == activityId) ??
|
||||
.where((v) => v.value.activityPlan?.activityId == activityId) ??
|
||||
[],
|
||||
);
|
||||
|
||||
|
|
@ -115,7 +117,7 @@ mixin ActivitySummariesProvider<T extends StatefulWidget> on State<T> {
|
|||
final summary = entry.value;
|
||||
final roomId = entry.key;
|
||||
|
||||
if (summary.activityPlan.activityId != activityId) {
|
||||
if (summary.activityPlan?.activityId != activityId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -132,11 +134,13 @@ mixin ActivitySummariesProvider<T extends StatefulWidget> on State<T> {
|
|||
if (roomSummaries == null || roomSummaries!.isEmpty) return {};
|
||||
return roomSummaries!.values
|
||||
.where(
|
||||
(entry) => entry.activityRoles.roles.values.any(
|
||||
(v) => v.userId == userID && v.isArchived,
|
||||
),
|
||||
(entry) =>
|
||||
entry.activityRoles != null &&
|
||||
entry.activityRoles!.roles.values.any(
|
||||
(v) => v.userId == userID && v.isArchived,
|
||||
),
|
||||
)
|
||||
.map((e) => e.activityPlan.activityId)
|
||||
.map((e) => e.activityPlan?.activityId)
|
||||
.whereType<String>()
|
||||
.toSet();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ description: Learn a language while texting your friends.
|
|||
# Pangea#
|
||||
publish_to: none
|
||||
# On version bump also increase the build number for F-Droid
|
||||
version: 4.1.16+5
|
||||
version: 4.1.16+6
|
||||
|
||||
environment:
|
||||
sdk: ">=3.0.0 <4.0.0"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue