From 1cc2c87ae8bd30c5b8683ada1f8572d52ecca64b Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 19 May 2026 19:16:33 -0400 Subject: [PATCH 1/2] rename render_event to event_renderer --- lib/widgets/chat_page/composer/relation_preview.dart | 4 ++-- .../{render_event.dart => event_renderer.dart} | 10 ++++------ lib/widgets/chat_page/membership_renderer.dart | 0 lib/widgets/chat_page/room_chat.dart | 4 ++-- 4 files changed, 8 insertions(+), 10 deletions(-) rename lib/widgets/chat_page/{render_event.dart => event_renderer.dart} (98%) create mode 100644 lib/widgets/chat_page/membership_renderer.dart diff --git a/lib/widgets/chat_page/composer/relation_preview.dart b/lib/widgets/chat_page/composer/relation_preview.dart index 2df8a3d..2e59d5a 100644 --- a/lib/widgets/chat_page/composer/relation_preview.dart +++ b/lib/widgets/chat_page/composer/relation_preview.dart @@ -2,7 +2,7 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/relation_type.dart"; -import "package:nexus/widgets/chat_page/render_event.dart"; +import "package:nexus/widgets/chat_page/event_renderer.dart"; import "package:nexus/widgets/chat_page/lazy_loading/message_avatar.dart"; import "package:nexus/widgets/chat_page/lazy_loading/message_displayname.dart"; @@ -55,7 +55,7 @@ class RelationPreview extends ConsumerWidget { ), Expanded( child: IgnorePointer( - child: RenderEvent( + child: EventRenderer( relatedEvent!, textOnly: true, maxLines: 1, diff --git a/lib/widgets/chat_page/render_event.dart b/lib/widgets/chat_page/event_renderer.dart similarity index 98% rename from lib/widgets/chat_page/render_event.dart rename to lib/widgets/chat_page/event_renderer.dart index 747c3b7..b13a650 100644 --- a/lib/widgets/chat_page/render_event.dart +++ b/lib/widgets/chat_page/event_renderer.dart @@ -31,14 +31,14 @@ import "package:nexus/widgets/players/audio.dart"; import "package:timeago/timeago.dart"; import "package:flutter_linkify/flutter_linkify.dart"; -class RenderEvent extends ConsumerWidget { +class EventRenderer extends ConsumerWidget { final Event event; final bool textOnly; final bool isGrouped; final int? maxLines; final VoidCallback? onTapReply; final IList Function(Event event)? getEventOptions; - const RenderEvent( + const EventRenderer( this.event, { this.onTapReply, this.textOnly = false, @@ -240,10 +240,8 @@ class RenderEvent extends ConsumerWidget { :final info, ) => AudioPlayer(url, info), - // FileMessageContent( - // :final info, - // ) => - // VideoPlayer(url, info), + // FileMessageContent(:final info) => + // FileCard(url, info), ImageMessageContent(:final info) => ExpandableImage( url.toString(), child: ClipRRect( diff --git a/lib/widgets/chat_page/membership_renderer.dart b/lib/widgets/chat_page/membership_renderer.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/widgets/chat_page/room_chat.dart b/lib/widgets/chat_page/room_chat.dart index a9383f9..35490ac 100644 --- a/lib/widgets/chat_page/room_chat.dart +++ b/lib/widgets/chat_page/room_chat.dart @@ -18,7 +18,7 @@ import "package:nexus/models/relation_type.dart"; import "package:nexus/models/requests/report_request.dart"; import "package:nexus/widgets/chat_page/composer/chat_box.dart"; import "package:nexus/widgets/chat_page/emoji_picker_button.dart"; -import "package:nexus/widgets/chat_page/render_event.dart"; +import "package:nexus/widgets/chat_page/event_renderer.dart"; import "package:nexus/widgets/chat_page/member_list.dart"; import "package:nexus/widgets/chat_page/room_appbar.dart"; import "package:nexus/widgets/chat_page/wrappers/event_wrapper.dart"; @@ -327,7 +327,7 @@ class RoomChat extends HookConsumerWidget { itemCount: value.length, itemBuilder: (_, index) => EventWrapper( value[index], - RenderEvent( + EventRenderer( value[index], onTapReply: () => listController.value.animateToItem( From 35f5d4e8494c276458960342d4b59e16f3e189b6 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 19 May 2026 19:21:37 -0400 Subject: [PATCH 2/2] refactor membership renderer into its own widget --- .../chat_page/composer/relation_preview.dart | 2 +- .../chat_page/membership_renderer.dart | 0 lib/widgets/chat_page/room_chat.dart | 2 +- .../event.dart} | 45 +------------ lib/widgets/renderers/membership.dart | 64 +++++++++++++++++++ 5 files changed, 68 insertions(+), 45 deletions(-) delete mode 100644 lib/widgets/chat_page/membership_renderer.dart rename lib/widgets/{chat_page/event_renderer.dart => renderers/event.dart} (89%) create mode 100644 lib/widgets/renderers/membership.dart diff --git a/lib/widgets/chat_page/composer/relation_preview.dart b/lib/widgets/chat_page/composer/relation_preview.dart index 2e59d5a..fff95b2 100644 --- a/lib/widgets/chat_page/composer/relation_preview.dart +++ b/lib/widgets/chat_page/composer/relation_preview.dart @@ -2,7 +2,7 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/relation_type.dart"; -import "package:nexus/widgets/chat_page/event_renderer.dart"; +import "package:nexus/widgets/renderers/event.dart"; import "package:nexus/widgets/chat_page/lazy_loading/message_avatar.dart"; import "package:nexus/widgets/chat_page/lazy_loading/message_displayname.dart"; diff --git a/lib/widgets/chat_page/membership_renderer.dart b/lib/widgets/chat_page/membership_renderer.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/widgets/chat_page/room_chat.dart b/lib/widgets/chat_page/room_chat.dart index 35490ac..0876982 100644 --- a/lib/widgets/chat_page/room_chat.dart +++ b/lib/widgets/chat_page/room_chat.dart @@ -18,7 +18,7 @@ import "package:nexus/models/relation_type.dart"; import "package:nexus/models/requests/report_request.dart"; import "package:nexus/widgets/chat_page/composer/chat_box.dart"; import "package:nexus/widgets/chat_page/emoji_picker_button.dart"; -import "package:nexus/widgets/chat_page/event_renderer.dart"; +import "package:nexus/widgets/renderers/event.dart"; import "package:nexus/widgets/chat_page/member_list.dart"; import "package:nexus/widgets/chat_page/room_appbar.dart"; import "package:nexus/widgets/chat_page/wrappers/event_wrapper.dart"; diff --git a/lib/widgets/chat_page/event_renderer.dart b/lib/widgets/renderers/event.dart similarity index 89% rename from lib/widgets/chat_page/event_renderer.dart rename to lib/widgets/renderers/event.dart index b13a650..860e07f 100644 --- a/lib/widgets/chat_page/event_renderer.dart +++ b/lib/widgets/renderers/event.dart @@ -8,10 +8,8 @@ import "package:linkify/linkify.dart"; import "package:nexus/controllers/client_state_controller.dart"; import "package:nexus/controllers/cross_cache_controller.dart"; import "package:nexus/helpers/extensions/get_headers.dart"; -import "package:nexus/helpers/extensions/get_localpart.dart"; import "package:nexus/helpers/extensions/mxc_to_https.dart"; import "package:nexus/helpers/extensions/show_context_menu.dart"; -import "package:nexus/helpers/extensions/show_user_popover.dart"; import "package:nexus/helpers/launch_helper.dart"; import "package:nexus/models/content/avatar.dart"; import "package:nexus/models/content/content.dart"; @@ -19,7 +17,6 @@ import "package:nexus/models/content/encrypted.dart"; import "package:nexus/models/content/membership.dart"; import "package:nexus/models/content/message.dart"; import "package:nexus/models/event.dart"; -import "package:nexus/models/membership_status.dart"; import "package:nexus/widgets/chat_page/expandable_image.dart"; import "package:nexus/widgets/chat_page/html/html.dart"; import "package:nexus/widgets/chat_page/lazy_loading/message_avatar.dart"; @@ -28,6 +25,7 @@ import "package:nexus/widgets/link_preview.dart"; import "package:nexus/widgets/loading.dart"; import "package:nexus/widgets/players/video.dart"; import "package:nexus/widgets/players/audio.dart"; +import "package:nexus/widgets/renderers/membership.dart"; import "package:timeago/timeago.dart"; import "package:flutter_linkify/flutter_linkify.dart"; @@ -348,46 +346,7 @@ class EventRenderer extends ConsumerWidget { (event.previousContent as MembershipContent).status == content.status ? null - : Row( - spacing: 4, - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 4), - child: Icon(Icons.people), - ), - InkWell( - onTapUp: (details) => context.showUserPopover( - content, - event.stateKey!, - globalPosition: details.globalPosition, - ), - child: Text( - content.displayName ?? event.stateKey!.localpart, - style: TextStyle( - color: theme.colorScheme.primary, - fontWeight: FontWeight.bold, - ), - ), - ), - Text( - "${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${content.reason == null ? "" : "because ${content.reason}"}${event.sender == event.stateKey ? "" : " by "}", - ), - if (event.sender != event.stateKey) - MessageDisplayname( - event, - style: TextStyle( - color: theme.colorScheme.primary, - fontWeight: FontWeight.bold, - ), - ), - ], - ), + : MembershipRenderer(event), AvatarContent() => Row( spacing: 4, children: [ diff --git a/lib/widgets/renderers/membership.dart b/lib/widgets/renderers/membership.dart new file mode 100644 index 0000000..37c61c4 --- /dev/null +++ b/lib/widgets/renderers/membership.dart @@ -0,0 +1,64 @@ +import "package:flutter/material.dart"; +import "package:nexus/helpers/extensions/get_localpart.dart"; +import "package:nexus/helpers/extensions/show_user_popover.dart"; +import "package:nexus/models/content/membership.dart"; +import "package:nexus/models/event.dart"; +import "package:nexus/models/membership_status.dart"; +import "package:nexus/widgets/chat_page/lazy_loading/message_displayname.dart"; + +class MembershipRenderer extends StatelessWidget { + final Event event; + const MembershipRenderer(this.event, {super.key}); + + @override + Widget build(BuildContext context) { + assert( + event.content is MembershipContent, + "Make sure to only pass membership events to MembershipRenderer", + ); + + return switch (event.content) { + MembershipContent content => Row( + spacing: 4, + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 4), + child: Icon(Icons.people), + ), + InkWell( + onTapUp: (details) => context.showUserPopover( + content, + event.stateKey!, + globalPosition: details.globalPosition, + ), + child: Text( + content.displayName ?? event.stateKey!.localpart, + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold, + ), + ), + ), + Text( + "${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${content.reason == null ? "" : "because ${content.reason}"}${event.sender == event.stateKey ? "" : " by "}", + ), + if (event.sender != event.stateKey) + MessageDisplayname( + event, + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + _ => SizedBox.shrink(), + }; + } +}