diff --git a/README.md b/README.md index 203b263..c7c9226 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,6 @@ A simple and user-friendly Matrix client made with Flutter and the Matrix Dart S ## Known Bugs -- Sometimes we have errors on scrolling due to out of chunk edits. This will be easy to fix once https://forgejo.ellis.link/continuwuation/continuwuity/pulls/847 is complete and merged. I left a bounty on this, so hopefully it can get resolved quickly. - Sometimes the app refreshes, I believe due to some controllers invalidating. This needs investigation as to why it happens. - Sometimes links don't parse properly, this is apparent in the Maunium Ping Room. We might possibly need a regex change. diff --git a/lib/controllers/room_chat_controller.dart b/lib/controllers/room_chat_controller.dart index 49c3cfa..2583c01 100644 --- a/lib/controllers/room_chat_controller.dart +++ b/lib/controllers/room_chat_controller.dart @@ -30,18 +30,17 @@ class RoomChatController extends AsyncNotifier { ), ); } else { - final message = await event.toMessage(); + final message = await event.toMessage(includeEdits: true); + if (event.relationshipType == RelationshipTypes.edit) { + final controller = await future; + final oldMessage = controller.messages.firstWhereOrNull( + (element) => element.id == event.relationshipEventId, + ); + if (oldMessage == null || message == null) return; + return await updateMessage(oldMessage, message); + } if (message != null) { - if (event.relationshipType == RelationshipTypes.edit) { - final controller = await future; - final oldMessage = controller.messages.firstWhereOrNull( - (element) => element.id == event.relationshipEventId, - ); - if (oldMessage == null) return; - await updateMessage(oldMessage, message); - } else { - await insertMessage(message); - } + return await insertMessage(message); } } }).cancel, diff --git a/lib/helpers/extensions/event_to_message.dart b/lib/helpers/extensions/event_to_message.dart index a4c58d6..0455285 100644 --- a/lib/helpers/extensions/event_to_message.dart +++ b/lib/helpers/extensions/event_to_message.dart @@ -4,33 +4,39 @@ import "package:flutter_chat_core/flutter_chat_core.dart"; import "package:matrix/matrix.dart"; extension EventToMessage on Event { - Future toMessage({bool mustBeText = false}) async { + Future toMessage({ + bool mustBeText = false, + bool includeEdits = false, + }) async { final replyId = relationshipType == RelationshipTypes.reply ? relationshipEventId : null; - final sender = (await fetchSenderUser()) ?? senderFromMemoryOrFallback; - final newContent = content["m.new_content"] as Map?; + final newEvent = (unsigned?["m.relations"] as Map?)?["m.replace"]; + final event = newEvent == null ? this : Event.fromJson(newEvent, room); + + final newContent = event.content["m.new_content"] as Map?; final metadata = { "formatted": newContent?["formatted_body"] ?? newContent?["body"] ?? - content["formatted_body"] ?? - this.body, - "eventType": type, - "displayName": sender.displayName ?? sender.id, + event.content["formatted_body"] ?? + event.content["body"], + "eventType": event.type, + "displayName": + event.senderFromMemoryOrFallback.displayName ?? + event.senderFromMemoryOrFallback.id, "txnId": transactionId, }; - final editedAt = relationshipType == RelationshipTypes.edit - ? originServerTs + final editedAt = event.relationshipType == RelationshipTypes.edit + ? event.originServerTs : null; - final body = (newContent?["body"] ?? content["body"]).toString(); - final eventId = editedAt == null - ? this.eventId - : relationshipEventId ?? this.eventId; - if (redacted && !mustBeText) return null; + if ((redacted && !mustBeText) || + (!includeEdits && (relationshipType == RelationshipTypes.edit))) { + return null; + } // TODO: Use server-generated preview if enabled when https://github.com/famedly/matrix-dart-sdk/issues/2195 is fixed. @@ -47,7 +53,7 @@ extension EventToMessage on Event { metadata: metadata, id: eventId, authorId: senderId, - text: body, + text: redacted ? "This message has been deleted..." : event.body, replyToMessageId: replyId, deliveredAt: originServerTs, editedAt: editedAt, @@ -66,7 +72,7 @@ extension EventToMessage on Event { metadata: metadata, id: eventId, authorId: senderId, - text: text, + text: event.text, source: (await getAttachmentUri()).toString(), replyToMessageId: replyId, deliveredAt: originServerTs, @@ -75,18 +81,19 @@ extension EventToMessage on Event { metadata: metadata, id: eventId, authorId: senderId, - text: text, + text: event.text, replyToMessageId: replyId, - source: (await getAttachmentUri()).toString(), + source: (await event.getAttachmentUri()).toString(), deliveredAt: originServerTs, + // TODO: See if we can figure out duration duration: Duration(hours: 1), ), MessageTypes.File => Message.file( - name: content["filename"].toString(), + name: event.content["filename"].toString(), metadata: metadata, id: eventId, authorId: senderId, - source: (await getAttachmentUri()).toString(), + source: (await event.getAttachmentUri()).toString(), replyToMessageId: replyId, deliveredAt: originServerTs, ), @@ -97,7 +104,7 @@ extension EventToMessage on Event { id: eventId, authorId: senderId, text: - "${sender.displayName} ${switch (Membership.values.firstWhereOrNull((membership) => membership.name == content["membership"])) { + "${event.senderFromMemoryOrFallback.displayName} ${switch (Membership.values.firstWhereOrNull((membership) => membership.name == event.content["membership"])) { Membership.invite => "was invited to", Membership.join => "joined", Membership.leave => "left", diff --git a/lib/helpers/extensions/list_to_messages.dart b/lib/helpers/extensions/list_to_messages.dart index d7f89c4..c14618b 100644 --- a/lib/helpers/extensions/list_to_messages.dart +++ b/lib/helpers/extensions/list_to_messages.dart @@ -3,13 +3,7 @@ import "package:matrix/matrix.dart"; import "package:nexus/helpers/extensions/event_to_message.dart"; extension ListToMessages on List { - Future> toMessages(Room room) async { - final messages = await Future.wait( - map((event) => Event.fromMatrixEvent(event, room).toMessage()), - ); - - return { - for (var msg in messages.nonNulls.toList().reversed.toList()) msg.id: msg, - }.values.toList(); - } + Future> toMessages(Room room) async => (await Future.wait( + map((event) => Event.fromMatrixEvent(event, room).toMessage()), + )).nonNulls.toList().reversed.toList(); }