Add GenericEventRenderer

This commit is contained in:
Henry Hiles 2026-05-21 14:07:21 -04:00
commit e4f091cb0f
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
3 changed files with 60 additions and 53 deletions

View file

@ -29,6 +29,7 @@ import "package:nexus/widgets/loading.dart";
import "package:nexus/widgets/players/video.dart"; import "package:nexus/widgets/players/video.dart";
import "package:nexus/widgets/players/audio.dart"; import "package:nexus/widgets/players/audio.dart";
import "package:nexus/widgets/renderers/membership.dart"; import "package:nexus/widgets/renderers/membership.dart";
import "package:nexus/widgets/renderers/generic_event.dart";
import "package:nexus/widgets/file_card.dart"; import "package:nexus/widgets/file_card.dart";
import "package:timeago/timeago.dart"; import "package:timeago/timeago.dart";
import "package:flutter_linkify/flutter_linkify.dart"; import "package:flutter_linkify/flutter_linkify.dart";
@ -396,17 +397,14 @@ class EventRenderer extends ConsumerWidget {
content.status content.status
? null ? null
: MembershipRenderer(event), : MembershipRenderer(event),
AvatarContent() => Row( AvatarContent() => GenericEventRenderer(Icons.numbers, [
spacing: 4, Padding(
children: [ padding: EdgeInsets.symmetric(horizontal: 4),
Padding( child: Icon(Icons.numbers),
padding: EdgeInsets.symmetric(horizontal: 4), ),
child: Icon(Icons.numbers), Flexible(child: MessageDisplayname(event)),
), Expanded(child: Text("changed the room avatar")),
Flexible(child: MessageDisplayname(event)), ]),
Expanded(child: Text("changed the room avatar")),
],
),
_ => null, _ => null,
}; };

View file

@ -0,0 +1,22 @@
import "package:flutter/material.dart";
class GenericEventRenderer extends StatelessWidget {
final IconData icon;
final List<Widget> children;
const GenericEventRenderer(this.icon, this.children, {super.key});
@override
Widget build(BuildContext context) => Padding(
padding: EdgeInsets.only(bottom: 8),
child: Row(
spacing: 8,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 4),
child: Icon(Icons.people),
),
Expanded(child: Wrap(spacing: 4, children: children)),
],
),
);
}

View file

@ -6,6 +6,7 @@ import "package:nexus/models/content/membership.dart";
import "package:nexus/models/event.dart"; import "package:nexus/models/event.dart";
import "package:nexus/models/membership_status.dart"; import "package:nexus/models/membership_status.dart";
import "package:nexus/widgets/lazy_loading/message_displayname.dart"; import "package:nexus/widgets/lazy_loading/message_displayname.dart";
import "package:nexus/widgets/renderers/generic_event.dart";
class MembershipRenderer extends StatelessWidget { class MembershipRenderer extends StatelessWidget {
final Event event; final Event event;
@ -19,51 +20,37 @@ class MembershipRenderer extends StatelessWidget {
); );
return switch (event.content) { return switch (event.content) {
MembershipContent content => Row( MembershipContent content => GenericEventRenderer(Icons.people, [
spacing: 8, InkWell(
children: [ onTapUp: (details) => context.showUserPopover(
Padding( content,
padding: EdgeInsets.symmetric(horizontal: 4), event.stateKey!,
child: Icon(Icons.people), globalPosition: details.globalPosition,
), ),
Expanded( child: Text(
child: Wrap( overflow: TextOverflow.ellipsis,
spacing: 4, content.displayName ?? event.stateKey!.localpart,
children: [ maxLines: 1,
InkWell( style: TextStyle(
onTapUp: (details) => context.showUserPopover( color: event.sender.colorHash,
content, fontWeight: FontWeight.bold,
event.stateKey!,
globalPosition: details.globalPosition,
),
child: Text(
overflow: TextOverflow.ellipsis,
content.displayName ?? event.stateKey!.localpart,
maxLines: 1,
style: TextStyle(
color: event.sender.colorHash,
fontWeight: FontWeight.bold,
),
),
),
Text(
overflow: TextOverflow.ellipsis,
maxLines: 1,
"${switch (content.status) {
MembershipStatus.invite => "was invited to",
MembershipStatus.join => "joined",
MembershipStatus.leave => event.sender == event.stateKey ? "left" : (event.unsigned["prev_content"]?["membership"] == "ban" ? "was unbanned from" : "was kicked from"),
MembershipStatus.ban => "was banned from",
MembershipStatus.knock => "asked to join",
}} the room${event.sender == event.stateKey ? "" : " by "}",
),
if (event.sender != event.stateKey) MessageDisplayname(event),
if (content.reason != null) Text("for \"${content.reason}\""),
],
), ),
), ),
], ),
), Text(
overflow: TextOverflow.ellipsis,
maxLines: 1,
"${switch (content.status) {
MembershipStatus.invite => "was invited to",
MembershipStatus.join => "joined",
MembershipStatus.leave => event.sender == event.stateKey ? "left" : (event.unsigned["prev_content"]?["membership"] == "ban" ? "was unbanned from" : "was kicked from"),
MembershipStatus.ban => "was banned from",
MembershipStatus.knock => "asked to join",
}} the room${event.sender == event.stateKey ? "" : " by "}",
),
if (event.sender != event.stateKey) MessageDisplayname(event),
if (content.reason != null) Text("for \"${content.reason}\""),
]),
_ => SizedBox.shrink(), _ => SizedBox.shrink(),
}; };
} }