From cb22ed982201bafb0a3bc03f4c8bc35596834f11 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 17 May 2026 22:24:41 -0400 Subject: [PATCH] fix up bugs related to new architecture --- lib/controllers/client_controller.dart | 2 +- lib/controllers/members_controller.dart | 4 +++- lib/controllers/room_chat_controller.dart | 2 +- lib/helpers/extensions/get_localpart.dart | 2 +- lib/models/content/content.dart | 4 ++-- lib/models/content/create.dart | 4 ++-- lib/models/content/membership.dart | 2 +- lib/models/content/message.dart | 13 +++++++++++-- lib/models/event.dart | 7 +++++-- .../chat_page/composer/mention_overlay.dart | 16 +++++++++------- .../chat_page/lazy_loading/message_avatar.dart | 6 +++--- lib/widgets/chat_page/member_list.dart | 8 ++++++-- lib/widgets/chat_page/user_popover.dart | 5 +++-- 13 files changed, 48 insertions(+), 27 deletions(-) diff --git a/lib/controllers/client_controller.dart b/lib/controllers/client_controller.dart index 4539632..b09cd1c 100644 --- a/lib/controllers/client_controller.dart +++ b/lib/controllers/client_controller.dart @@ -80,7 +80,7 @@ class ClientController extends AsyncNotifier { case "send_complete": final event = Event.fromJson(decodedMuksEvent["event"]); - if (event.type == EventType.message) { + if (event.type == EventType.message.type) { // ref.watch(provider.notifier).addEvent(event); TODO } break; diff --git a/lib/controllers/members_controller.dart b/lib/controllers/members_controller.dart index 570a233..91da138 100644 --- a/lib/controllers/members_controller.dart +++ b/lib/controllers/members_controller.dart @@ -28,7 +28,9 @@ class MembersController extends AsyncNotifier> { ), ); - return state.where((state) => state.type == EventType.membership).toIList(); + return state + .where((state) => state.type == EventType.membership.type) + .toIList(); } static final provider = diff --git a/lib/controllers/room_chat_controller.dart b/lib/controllers/room_chat_controller.dart index f37716f..e4e4a72 100644 --- a/lib/controllers/room_chat_controller.dart +++ b/lib/controllers/room_chat_controller.dart @@ -57,7 +57,7 @@ class RoomChatController extends AsyncNotifier> { if (room == null) return const IList.empty(); // While there are under 30 messages, try up to load more messages until there's no more or we have 20 messages. - if (room.hasMore && room.events.length < 30) { + if (room.hasMore && room.timeline.length < 30) { loadOlder(); } diff --git a/lib/helpers/extensions/get_localpart.dart b/lib/helpers/extensions/get_localpart.dart index 445351f..fa3d285 100644 --- a/lib/helpers/extensions/get_localpart.dart +++ b/lib/helpers/extensions/get_localpart.dart @@ -1,3 +1,3 @@ extension GetLocalpart on String { - String get localpart => substring(1).split(":").first; + String get localpart => length > 1 ? substring(1).split(":").first : "?"; } diff --git a/lib/models/content/content.dart b/lib/models/content/content.dart index f388181..5277eeb 100644 --- a/lib/models/content/content.dart +++ b/lib/models/content/content.dart @@ -20,9 +20,9 @@ class Content { factory Content.fromJson(Map json) => Content(); Map toJson() => {}; - static Content fromEventJson(Map eventJson) => + static Content fromEventJson(Map eventJson, String type) => (EventType.values - .firstWhereOrNull((eventType) => eventType.type == eventJson["type"]) + .firstWhereOrNull((eventType) => eventType.type == type) ?.contentFromJson ?? Content.fromJson)(eventJson); } diff --git a/lib/models/content/create.dart b/lib/models/content/create.dart index 08d1c22..f20a713 100644 --- a/lib/models/content/create.dart +++ b/lib/models/content/create.dart @@ -19,7 +19,7 @@ abstract class CreateContent extends Content with _$CreateContent { @JsonKey(name: "m.federate") @Default(true) bool federated, @Default("1") String roomVersion, - required String type, + String? type, }) = _CreateContent; factory CreateContent.fromJson(Map json) => @@ -28,7 +28,7 @@ abstract class CreateContent extends Content with _$CreateContent { @freezed abstract class PreviousRoom with _$PreviousRoom { - const factory PreviousRoom({required int roomId}) = _PreviousRoom; + const factory PreviousRoom({required String roomId}) = _PreviousRoom; factory PreviousRoom.fromJson(Map json) => _$PreviousRoomFromJson(json); diff --git a/lib/models/content/membership.dart b/lib/models/content/membership.dart index c963ed7..aa5a36d 100644 --- a/lib/models/content/membership.dart +++ b/lib/models/content/membership.dart @@ -8,7 +8,7 @@ part "membership.g.dart"; abstract class MembershipContent extends Content with _$MembershipContent { MembershipContent._(); factory MembershipContent({ - @JsonKey(name: "displayname") required String displayName, + @JsonKey(name: "displayname") required String? displayName, @JsonKey(name: "membership") required MembershipStatus status, Uri? avatarUrl, String? reason, diff --git a/lib/models/content/message.dart b/lib/models/content/message.dart index 2408993..82b4604 100644 --- a/lib/models/content/message.dart +++ b/lib/models/content/message.dart @@ -9,13 +9,22 @@ part "message.g.dart"; @Freezed(unionKey: "msgtype", fallbackUnion: "default") abstract class MessageContent extends Content with _$MessageContent { MessageContent._(); - factory MessageContent({ - required String msgtype, + factory MessageContent({required String body}) = UnknownMessageContent; + + @FreezedUnionValue("m.text") + factory MessageContent.text({ required String body, String? format, String? formattedBody, }) = TextMessageContent; + @FreezedUnionValue("m.notice") + factory MessageContent.notice({ + required String body, + String? format, + String? formattedBody, + }) = NoticeMessageContent; + @FreezedUnionValue("m.image") factory MessageContent.image({ required String body, diff --git a/lib/models/event.dart b/lib/models/event.dart index 21fbedb..58bd388 100644 --- a/lib/models/event.dart +++ b/lib/models/event.dart @@ -36,10 +36,13 @@ abstract class Event with _$Event { @JsonKey(name: "last_edit_rowid") int? lastEditRowId, @UnreadTypeConverter() UnreadType? unreadType, @JsonKey(fromJson: pmpFromJson) Profile? pmp, - @JsonKey(fromJson: Content.fromEventJson) required Content content, + @JsonKey(fromJson: Content.fromJson) required Content content, }) = _Event; - factory Event.fromJson(Map json) => _$EventFromJson(json); + factory Event.fromJson(Map json) => + _$EventFromJson(json).copyWith( + content: Content.fromEventJson(json["content"], json["type"] as String), + ); } @freezed diff --git a/lib/widgets/chat_page/composer/mention_overlay.dart b/lib/widgets/chat_page/composer/mention_overlay.dart index b2a5492..b303ea1 100644 --- a/lib/widgets/chat_page/composer/mention_overlay.dart +++ b/lib/widgets/chat_page/composer/mention_overlay.dart @@ -4,6 +4,7 @@ import "package:nexus/controllers/members_by_type_controller.dart"; import "package:nexus/controllers/rooms_controller.dart"; import "package:nexus/controllers/via_controller.dart"; import "package:nexus/helpers/extensions/better_when.dart"; +import "package:nexus/helpers/extensions/get_localpart.dart"; import "package:nexus/models/content/membership.dart"; import "package:nexus/models/membership_status.dart"; import "package:nexus/widgets/avatar_or_hash.dart"; @@ -55,7 +56,7 @@ class MentionOverlay extends ConsumerWidget { :final displayName, ) => displayName - .toLowerCase() + ?.toLowerCase() .contains( query.toLowerCase(), ) == @@ -72,16 +73,17 @@ class MentionOverlay extends ConsumerWidget { ListTile( leading: AvatarOrHash( avatarUrl, - displayName, + displayName ?? + member.stateKey!.localpart, + ), + title: Text( + displayName ?? + member.stateKey!.localpart, ), - title: Text(displayName), subtitle: Text(member.stateKey!), onTap: () => addTag( id: "[@$displayName](matrix:u/${member.stateKey!.substring(1)})", - name: member.stateKey! - .substring(1) - .split(":") - .first, + name: member.stateKey!.localpart, ), ), _ => SizedBox.shrink(), diff --git a/lib/widgets/chat_page/lazy_loading/message_avatar.dart b/lib/widgets/chat_page/lazy_loading/message_avatar.dart index da6ecec..529edaa 100644 --- a/lib/widgets/chat_page/lazy_loading/message_avatar.dart +++ b/lib/widgets/chat_page/lazy_loading/message_avatar.dart @@ -2,8 +2,8 @@ import "package:flutter/material.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/author_controller.dart"; import "package:nexus/helpers/extensions/better_when.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/widgets/avatar_or_hash.dart"; @@ -26,11 +26,11 @@ class MessageAvatar extends ConsumerWidget { }, child: AvatarOrHash( membership.avatarUrl, - membership.displayName, + membership.displayName ?? event.sender.localpart, height: height, ), ), loading: () => - AvatarOrHash(null, event.sender.substring(1), height: height), + AvatarOrHash(null, event.sender.localpart, height: height), ); } diff --git a/lib/widgets/chat_page/member_list.dart b/lib/widgets/chat_page/member_list.dart index 3af1f0a..a59146c 100644 --- a/lib/widgets/chat_page/member_list.dart +++ b/lib/widgets/chat_page/member_list.dart @@ -3,6 +3,7 @@ import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/members_by_type_controller.dart"; import "package:nexus/helpers/extensions/better_when.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/membership_status.dart"; @@ -75,9 +76,12 @@ class MemberList extends HookConsumerWidget { globalPosition: details.globalPosition, ), child: ListTile( - leading: AvatarOrHash(avatarUrl, displayName), + leading: AvatarOrHash( + avatarUrl, + displayName ?? member.sender.localpart, + ), title: Text( - displayName, + displayName ?? member.stateKey!.localpart, overflow: TextOverflow.ellipsis, ), subtitle: Text( diff --git a/lib/widgets/chat_page/user_popover.dart b/lib/widgets/chat_page/user_popover.dart index 5ff4110..5d438ff 100644 --- a/lib/widgets/chat_page/user_popover.dart +++ b/lib/widgets/chat_page/user_popover.dart @@ -8,6 +8,7 @@ import "package:nexus/controllers/power_level_controller.dart"; import "package:nexus/controllers/profile_controller.dart"; import "package:nexus/controllers/selected_room_controller.dart"; import "package:nexus/helpers/extensions/better_when.dart"; +import "package:nexus/helpers/extensions/get_localpart.dart"; import "package:nexus/models/configs/power_level_config.dart"; import "package:nexus/models/content/membership.dart"; import "package:nexus/models/membership_status.dart"; @@ -93,7 +94,7 @@ class UserPopover extends ConsumerWidget { member.avatarUrl?.toString(), child: AvatarOrHash( member.avatarUrl, - member.displayName, + member.displayName ?? userId.localpart, height: 80, ), ), @@ -101,7 +102,7 @@ class UserPopover extends ConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ SelectableText( - member.displayName, + member.displayName ?? userId.localpart, style: textTheme.headlineSmall, ), SelectableText(userId, style: textTheme.titleSmall),