From 4954fb8c09f593c08c167b4360124d0b2500d1f0 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 12 Apr 2026 14:56:08 -0400 Subject: [PATCH] allow redacting/removing reactions --- lib/controllers/room_chat_controller.dart | 34 +++++++++++++++++++ .../chat_page/wrappers/reaction_row.dart | 15 ++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/lib/controllers/room_chat_controller.dart b/lib/controllers/room_chat_controller.dart index aac51b2c..94a7ccb9 100644 --- a/lib/controllers/room_chat_controller.dart +++ b/lib/controllers/room_chat_controller.dart @@ -12,6 +12,7 @@ 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/message_config.dart"; +import "package:nexus/models/requests/get_related_events_request.dart"; import "package:nexus/models/requests/get_room_state_request.dart"; import "package:nexus/models/requests/paginate_request.dart"; import "package:nexus/models/requests/redact_event_request.dart"; @@ -329,6 +330,39 @@ class RoomChatController extends AsyncNotifier { return await controller.scrollToMessage(message.id); } + Future removeReaction( + String reaction, + Message message, + String userId, + ) async { + final client = ref.watch(ClientController.provider.notifier); + final allReactionEvents = await client.getRelatedEvents( + GetRelatedEventsRequest( + roomId: roomId, + eventId: message.id, + relationType: "m.annotation", + ), + ); + + final reactionEvents = allReactionEvents + ?.where((event) => event.redactedBy == null) + .toIList(); + + final reactionEvent = reactionEvents?.firstWhereOrNull( + (event) => + event.authorId == userId && + event.content["m.relates_to"]?["key"] == reaction, + ); + + if (reactionEvent != null) { + await ref + .watch(ClientController.provider.notifier) + .redactEvent( + RedactEventRequest(eventId: reactionEvent.eventId, roomId: roomId), + ); + } + } + Future sendReaction(String reaction, Message message) async { final client = ref.watch(ClientController.provider.notifier); diff --git a/lib/widgets/chat_page/wrappers/reaction_row.dart b/lib/widgets/chat_page/wrappers/reaction_row.dart index 1924cd2d..62f58ee3 100644 --- a/lib/widgets/chat_page/wrappers/reaction_row.dart +++ b/lib/widgets/chat_page/wrappers/reaction_row.dart @@ -9,6 +9,7 @@ import "package:nexus/controllers/room_chat_controller.dart"; import "package:nexus/controllers/selected_room_controller.dart"; import "package:nexus/helpers/extensions/get_headers.dart"; import "package:nexus/helpers/extensions/mxc_to_https.dart"; +import "package:nexus/main.dart"; class ReactionRow extends ConsumerWidget { final Message message; @@ -56,16 +57,24 @@ class ReactionRow extends ConsumerWidget { (value) => value?.metadata?.id, ), ); - if (roomId == null) return; + if (roomId == null || clientState.userId == null) return; final controller = ref.watch( RoomChatController.provider(roomId).notifier, ); if (selected) { - // TODO: remove + await controller + .removeReaction( + reaction, + message, + clientState.userId!, + ) + .onError(showError); } else { - await controller.sendReaction(reaction, message); + await controller + .sendReaction(reaction, message) + .onError(showError); } }, ),