From 7bac9f8a85f9699b7f4cfd016844002c6b107b2e Mon Sep 17 00:00:00 2001 From: OfficialDakari Date: Tue, 14 Oct 2025 11:46:33 +0500 Subject: [PATCH] feat: end polls --- assets/l10n/intl_en.arb | 1 + assets/l10n/intl_ru.arb | 1 + lib/pages/chat/chat.dart | 19 +++++++++++++++++-- lib/pages/chat/chat_view.dart | 20 +++++++++++++++++++- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 26901a9..a0db7d0 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -6,6 +6,7 @@ "longPressToRecordVoiceMessage": "Long press to record voice message.", "pause": "Pause", "resume": "Resume", + "endPoll": "End poll", "anonymousPoll": "Anonymous", "publicPoll": "Public", "endedPoll": "Ended", diff --git a/assets/l10n/intl_ru.arb b/assets/l10n/intl_ru.arb index 5c710a0..052efcb 100644 --- a/assets/l10n/intl_ru.arb +++ b/assets/l10n/intl_ru.arb @@ -30,6 +30,7 @@ "pleaseEnterQuestion": "Введите вопрос", "atLeastTwoAnswersRequired": "Требуется хотя бы 2 ответа", "maxSelections": "Количество ответов", + "endPoll": "Завершить опрос", "createPoll": "Создать опрос", "alwaysUse24HourFormat": "нет", "@alwaysUse24HourFormat": { diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 77a5a68..84d63ff 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -551,8 +551,7 @@ class ChatController extends State void sendPollAction() async { await showAdaptiveDialog( context: context, - builder: (c) => SendPollDialog(room: room, outerContext: context) - ); + builder: (c) => SendPollDialog(room: room, outerContext: context)); replyEvent = null; } @@ -872,6 +871,22 @@ class ChatController extends State } } + void endPollAction() async { + final event = selectedEvents.first; + if (event == null) return; + final client = currentRoomBundle.firstWhere( + (cl) => selectedEvents.first.senderId == cl!.userID, + orElse: () => null, + ); + if (client == null) return; + if (event.senderId != client!.userID) return; + await room.sendEvent({ + 'org.matrix.msc1767.text': 'Ended poll', + 'm.relates_to': {'rel_type': 'm.reference', 'event_id': event.eventId}, + 'body': 'Ended poll' + }, type: 'org.matrix.msc3381.poll.end'); + } + void redactEventsAction() async { final reasonInput = selectedEvents.any((event) => event.status.isSent) ? await showTextInputDialog( diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 4567fc4..f518e02 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -27,7 +27,7 @@ import '../../utils/stream_extension.dart'; import 'chat_emoji_picker.dart'; import 'chat_input_row.dart'; -enum _EventContextAction { info, recover, translate, report } +enum _EventContextAction { info, recover, translate, report, endPoll } class ChatView extends StatelessWidget { final ChatController controller; @@ -92,6 +92,9 @@ class ChatView extends StatelessWidget { case _EventContextAction.translate: controller.translateEventAction(); break; + case _EventContextAction.endPoll: + controller.endPollAction(); + break; } }, itemBuilder: (context) => [ @@ -115,6 +118,21 @@ class ChatView extends StatelessWidget { Text(L10n.of(context).recoverMessage), ]), ), + if (controller.selectedEvents.single.type == 'org.matrix.msc3381.poll.start' && controller.selectedEvents.single.senderId == Matrix.of(context).client.userID) + + PopupMenuItem( + value: _EventContextAction.endPoll, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon( + Icons.check, + ), + const SizedBox(width: 12), + Text(L10n.of(context).endPoll), + ], + ), + ), if (controller.selectedEvents.single.status.isSent) PopupMenuItem( value: _EventContextAction.report,