1
0
Fork 0
forked from Nexus/nexus

Update reactions as they are modified

This commit is contained in:
Henry Hiles 2026-04-10 16:31:55 -04:00
commit e9b78a14d5
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
2 changed files with 60 additions and 6 deletions

View file

@ -79,7 +79,8 @@ class MessageController extends AsyncNotifier<Message?> {
); );
final reactions = reactionEvents final reactions = reactionEvents
?.fold<IMap<String, IList<String>>>(IMap(), (acc, event) { ?.where((event) => event.redactedBy == null)
.fold<IMap<String, IList<String>>>(IMap(), (acc, event) {
final key = event.content["m.relates_to"]?["key"]; final key = event.content["m.relates_to"]?["key"];
if (key == null) return acc; if (key == null) return acc;

View file

@ -9,6 +9,7 @@ import "package:nexus/controllers/message_controller.dart";
import "package:nexus/controllers/messages_controller.dart"; import "package:nexus/controllers/messages_controller.dart";
import "package:nexus/controllers/new_events_controller.dart"; import "package:nexus/controllers/new_events_controller.dart";
import "package:nexus/controllers/rooms_controller.dart"; import "package:nexus/controllers/rooms_controller.dart";
import "package:nexus/controllers/selected_room_controller.dart";
import "package:nexus/models/configs/messages_config.dart"; import "package:nexus/models/configs/messages_config.dart";
import "package:nexus/models/configs/message_config.dart"; import "package:nexus/models/configs/message_config.dart";
import "package:nexus/models/requests/get_room_state_request.dart"; import "package:nexus/models/requests/get_room_state_request.dart";
@ -77,15 +78,67 @@ class RoomChatController extends AsyncNotifier<InMemoryChatController> {
ref.onDispose( ref.onDispose(
ref.listen(NewEventsController.provider(roomId), (_, next) async { ref.listen(NewEventsController.provider(roomId), (_, next) async {
for (final event in next) { for (final event in next) {
// TODO: Handle new reactions if (event.type == "m.reaction") {
final message = controller.messages.firstWhereOrNull(
(message) =>
message.id == event.content["m.relates_to"]?["event_id"],
);
final key = event.content["m.relates_to"]?["key"];
if (message == null || key == null || !ref.mounted) return;
return await controller.updateMessage(
message,
message.copyWith(
reactions: IMap(message.reactions)
.update(
key,
(reactors) => [...reactors, event.authorId],
ifAbsent: () => [event.authorId],
)
.unlock,
),
);
}
if (event.type == "m.room.redaction") { if (event.type == "m.room.redaction") {
final controller = await future; final controller = await future;
final message = controller.messages.firstWhereOrNull( final redactsId = event.content["redacts"];
(message) => message.id == event.content["redacts"], final originalMessage = controller.messages.firstWhereOrNull(
(message) => message.id == redactsId,
); );
if (message == null || !ref.mounted) return; if (!ref.mounted) return;
await controller.removeMessage(message); if (originalMessage != null) {
return await controller.removeMessage(originalMessage);
}
final redacts = ref
.read(SelectedRoomController.provider)
?.events
.firstWhere((event) => event.eventId == redactsId);
if (redacts?.type == "m.reaction") {
final message = controller.messages.firstWhereOrNull(
(message) =>
message.id == redacts!.content["m.relates_to"]?["event_id"],
);
final key = redacts!.content["m.relates_to"]?["key"];
if (message == null || key == null || !ref.mounted) return;
return await controller.updateMessage(
message,
message.copyWith(
reactions: IMap(message.reactions)
.update(
key,
(reactors) =>
IList(reactors).remove(redacts.authorId).unlock,
)
.where((_, value) => value.isNotEmpty)
.unlock,
),
);
}
} else { } else {
final message = await ref.watch( final message = await ref.watch(
MessageController.provider( MessageController.provider(