chore: display activity role state events (#3732)
This commit is contained in:
parent
861da39362
commit
506e069997
4 changed files with 114 additions and 0 deletions
|
|
@ -11,6 +11,7 @@ import 'package:fluffychat/pages/chat/chat.dart';
|
|||
import 'package:fluffychat/pages/chat/events/pangea_message_reactions.dart';
|
||||
import 'package:fluffychat/pages/chat/events/room_creation_state_event.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_creation_state_event.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_roles_event.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_state_event.dart';
|
||||
import 'package:fluffychat/pangea/chat/extensions/custom_room_display_extension.dart';
|
||||
|
|
@ -140,6 +141,10 @@ class Message extends StatelessWidget {
|
|||
if (event.type == PangeaEventTypes.activityPlan) {
|
||||
return ActivityStateEvent(event: event);
|
||||
}
|
||||
|
||||
if (event.type == PangeaEventTypes.activityRole) {
|
||||
return ActivityRolesEvent(event: event);
|
||||
}
|
||||
// Pangea#
|
||||
|
||||
return StateMessage(event);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
|
||||
class ActivityRoleModel {
|
||||
final String id;
|
||||
final String userId;
|
||||
|
|
@ -17,6 +19,21 @@ class ActivityRoleModel {
|
|||
|
||||
bool get isArchived => archivedAt != null;
|
||||
|
||||
String? stateEventMessage(String displayName, L10n l10n) {
|
||||
if (isArchived) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isFinished) {
|
||||
return l10n.finishedTheActivity(displayName);
|
||||
}
|
||||
|
||||
return l10n.joinedTheActivity(
|
||||
displayName,
|
||||
role ?? l10n.participant,
|
||||
);
|
||||
}
|
||||
|
||||
factory ActivityRoleModel.fromJson(Map<String, dynamic> json) {
|
||||
return ActivityRoleModel(
|
||||
id: json['id'] as String,
|
||||
|
|
|
|||
90
lib/pangea/activity_sessions/activity_roles_event.dart
Normal file
90
lib/pangea/activity_sessions/activity_roles_event.dart
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_role_model.dart';
|
||||
|
||||
class ActivityRolesEvent extends StatelessWidget {
|
||||
final Event event;
|
||||
const ActivityRolesEvent({
|
||||
super.key,
|
||||
required this.event,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
Set<ActivityRoleModel> difference = {};
|
||||
try {
|
||||
final currentRoles = (event.content['roles'] as Map<String, dynamic>)
|
||||
.values
|
||||
.map((v) => ActivityRoleModel.fromJson(v))
|
||||
.toSet();
|
||||
|
||||
final previousRoles =
|
||||
(event.prevContent?['roles'] as Map<String, dynamic>?)
|
||||
?.values
|
||||
.map((v) => ActivityRoleModel.fromJson(v))
|
||||
.toSet() ??
|
||||
{};
|
||||
|
||||
difference = currentRoles.difference(previousRoles);
|
||||
} catch (e) {
|
||||
debugPrint("Failed to parse activity roles: $e");
|
||||
}
|
||||
|
||||
if (difference.isEmpty) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: difference.map((role) {
|
||||
final user = event.room.getParticipants().firstWhereOrNull(
|
||||
(u) => u.id == role.userId,
|
||||
);
|
||||
|
||||
final displayName =
|
||||
user?.calcDisplayname() ?? role.userId.localpart ?? role.userId;
|
||||
|
||||
final message = role.stateEventMessage(displayName, L10n.of(context));
|
||||
if (message == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Material(
|
||||
color: theme.colorScheme.surface.withAlpha(128),
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius / 3),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
child: Text(
|
||||
"${role.stateEventMessage(displayName, L10n.of(context))}",
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 12 * AppConfig.fontSizeFactor,
|
||||
decoration:
|
||||
event.redacted ? TextDecoration.lineThrough : null,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -73,6 +73,7 @@ extension IsStateExtension on Event {
|
|||
isEventTypeKnown ||
|
||||
[
|
||||
PangeaEventTypes.activityPlan,
|
||||
PangeaEventTypes.activityRole,
|
||||
].contains(type);
|
||||
|
||||
// we're filtering out some state events that we don't want to render
|
||||
|
|
@ -83,6 +84,7 @@ extension IsStateExtension on Event {
|
|||
EventTypes.RoomTombstone,
|
||||
EventTypes.CallInvite,
|
||||
PangeaEventTypes.activityPlan,
|
||||
PangeaEventTypes.activityRole,
|
||||
};
|
||||
// Pangea#
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue