reply rendering

This commit is contained in:
Henry Hiles 2025-11-12 11:33:17 -05:00
commit 2a4525a78f
No known key found for this signature in database
6 changed files with 226 additions and 109 deletions

View file

@ -3,6 +3,7 @@ import "package:flutter_chat_core/flutter_chat_core.dart";
import "package:flutter_chat_core/flutter_chat_core.dart" as chat;
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:matrix/matrix.dart";
import "package:nexus/helpers/extension_helper.dart";
class RoomChatController extends AsyncNotifier<ChatController> {
RoomChatController(this.room);
@ -13,7 +14,7 @@ class RoomChatController extends AsyncNotifier<ChatController> {
final timeline = await room.getTimeline();
room.client.onTimelineEvent.stream.listen((event) async {
if (event.roomId != room.id) return;
final message = await toMessage(event);
final message = await event.toMessage();
if (message != null) {
await insertMessage(message);
}
@ -21,7 +22,7 @@ class RoomChatController extends AsyncNotifier<ChatController> {
return InMemoryChatController(
messages: (await Future.wait(
timeline.events.map(toMessage),
timeline.events.map((event) => event.toMessage()),
)).toList().reversed.nonNulls.toList(),
);
}
@ -42,78 +43,6 @@ class RoomChatController extends AsyncNotifier<ChatController> {
return controller.updateMessage(message, newMessage);
}
Future<Message?> toMessage(Event event) async {
final replyId = event.relationshipType == RelationshipTypes.reply
? event.relationshipEventId
: null;
final metadata = {
"eventType": event.type,
"displayName": event.senderFromMemoryOrFallback.displayName,
"txnId": event.transactionId,
};
return event.redacted
? Message.text(
metadata: metadata,
id: event.eventId,
authorId: event.senderId,
text: "~~This message has been redacted.~~",
deletedAt: event.redactedBecause?.originServerTs,
)
: switch (event.type) {
EventTypes.Message => switch (event.messageType) {
MessageTypes.Image => Message.image(
metadata: metadata,
id: event.eventId,
authorId: event.senderId,
source: (await event.getAttachmentUri()).toString(),
replyToMessageId: replyId,
deliveredAt: event.originServerTs,
),
MessageTypes.Audio => Message.audio(
metadata: metadata,
id: event.eventId,
authorId: event.senderId,
text: event.body,
replyToMessageId: replyId,
source: (await event.getAttachmentUri()).toString(),
deliveredAt: event.originServerTs,
duration: Duration(hours: 1),
),
MessageTypes.File => Message.file(
name: event.content["filename"].toString(),
metadata: metadata,
id: event.eventId,
authorId: event.senderId,
source: (await event.getAttachmentUri()).toString(),
replyToMessageId: replyId,
deliveredAt: event.originServerTs,
),
_ => Message.text(
metadata: metadata,
id: event.eventId,
authorId: event.senderId,
text: event.body,
replyToMessageId: replyId,
deliveredAt: event.originServerTs,
),
},
EventTypes.RoomMember => Message.system(
metadata: metadata,
id: event.eventId,
authorId: event.senderId,
text:
"${event.senderFromMemoryOrFallback.calcDisplayname()} joined the room.",
),
EventTypes.Redaction => null,
_ => Message.unsupported(
metadata: metadata,
id: event.eventId,
authorId: event.senderId,
replyToMessageId: replyId,
),
};
}
Future<void> send(String message) async {
await room.sendTextEvent(message);
}