From f0185441dd16d770c2f5bac39eb8efea75ae2e04 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Wed, 5 Nov 2025 14:06:19 -0500 Subject: [PATCH] refactor: separate dropdown menu for activity sessions --- lib/pages/chat/chat_view.dart | 88 +++++++++-------- lib/pages/chat_details/chat_details.dart | 51 +--------- .../chat_details/chat_download_provider.dart | 56 +++++++++++ .../activity_session_popup_menu.dart | 97 +++++++++++++++++++ .../pages/chat_details_button_row.dart | 2 +- 5 files changed, 203 insertions(+), 91 deletions(-) create mode 100644 lib/pages/chat_details/chat_download_provider.dart create mode 100644 lib/pangea/activity_sessions/activity_session_chat/activity_session_popup_menu.dart diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index d18b8455e..0e60f595f 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -16,6 +16,7 @@ import 'package:fluffychat/pages/chat/pinned_events.dart'; import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart'; import 'package:fluffychat/pangea/activity_sessions/activity_session_chat/activity_finished_status_message.dart'; import 'package:fluffychat/pangea/activity_sessions/activity_session_chat/activity_menu_button.dart'; +import 'package:fluffychat/pangea/activity_sessions/activity_session_chat/activity_session_popup_menu.dart'; import 'package:fluffychat/pangea/activity_sessions/activity_session_chat/activity_stats_menu.dart'; import 'package:fluffychat/pangea/activity_sessions/activity_session_chat/load_activity_summary_widget.dart'; import 'package:fluffychat/pangea/analytics_misc/level_up/star_rain_widget.dart'; @@ -123,48 +124,53 @@ class ChatView extends StatelessWidget { // ], // ), // ]; - // } else - // if (!controller.room.isArchived) { - // return [ - // if (AppConfig.experimentalVoip && - // Matrix.of(context).voipPlugin != null && - // controller.room.isDirectChat) - // IconButton( - // onPressed: controller.onPhoneButtonTap, - // icon: const Icon(Icons.call_outlined), - // tooltip: L10n.of(context).placeCall, - // ), - // EncryptionButton(controller.room), - // ChatSettingsPopupMenu(controller.room, true), - // ]; - if (!(controller.room.isArchived || controller.room.hasArchivedActivity)) { - return [ - if (controller.room.activityPlan == null || - !controller.room.showActivityChatUI) - IconButton( - icon: const Icon(Icons.search_outlined), - tooltip: L10n.of(context).search, - onPressed: () { - context.go('/rooms/${controller.room.id}/search'); - }, - ), - if (controller.room.showActivityChatUI) - ActivityMenuButton(controller: controller), - IconButton( - icon: const Icon(Icons.settings_outlined), - tooltip: L10n.of(context).chatDetails, - onPressed: () { - if (GoRouterState.of(context).uri.path.endsWith('/details')) { - context.go('/rooms/${controller.room.id}'); - } else { - context.go('/rooms/${controller.room.id}/details'); - } - }, - ), - ]; - // Pangea# + // } else if (!controller.room.isArchived) { + // return [ + // if (AppConfig.experimentalVoip && + // Matrix.of(context).voipPlugin != null && + // controller.room.isDirectChat) + // IconButton( + // onPressed: controller.onPhoneButtonTap, + // icon: const Icon(Icons.call_outlined), + // tooltip: L10n.of(context).placeCall, + // ), + // EncryptionButton(controller.room), + // ChatSettingsPopupMenu(controller.room, true), + // ]; + // } + // return []; + if (controller.room.isArchived || controller.room.hasArchivedActivity) { + return []; } - return []; + + if (controller.room.showActivityChatUI) { + return [ + ActivityMenuButton(controller: controller), + ActivitySessionPopupMenu(controller.room), + ]; + } + + return [ + IconButton( + icon: const Icon(Icons.search_outlined), + tooltip: L10n.of(context).search, + onPressed: () { + context.go('/rooms/${controller.room.id}/search'); + }, + ), + IconButton( + icon: const Icon(Icons.settings_outlined), + tooltip: L10n.of(context).chatDetails, + onPressed: () { + if (GoRouterState.of(context).uri.path.endsWith('/details')) { + context.go('/rooms/${controller.room.id}'); + } else { + context.go('/rooms/${controller.room.id}/details'); + } + }, + ), + ]; + // Pangea# } @override diff --git a/lib/pages/chat_details/chat_details.dart b/lib/pages/chat_details/chat_details.dart index 4263aab5c..c81a23624 100644 --- a/lib/pages/chat_details/chat_details.dart +++ b/lib/pages/chat_details/chat_details.dart @@ -9,6 +9,7 @@ import 'package:matrix/matrix.dart' as sdk; import 'package:matrix/matrix.dart'; import 'package:fluffychat/l10n/l10n.dart'; +import 'package:fluffychat/pages/chat_details/chat_download_provider.dart'; import 'package:fluffychat/pages/settings/settings.dart'; import 'package:fluffychat/pangea/chat/constants/default_power_level.dart'; import 'package:fluffychat/pangea/chat_settings/pages/pangea_room_details.dart'; @@ -16,8 +17,6 @@ import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/course_plans/course_activities/activity_summaries_provider.dart'; import 'package:fluffychat/pangea/course_plans/courses/course_plan_builder.dart'; import 'package:fluffychat/pangea/course_plans/courses/course_plan_room_extension.dart'; -import 'package:fluffychat/pangea/download/download_room_extension.dart'; -import 'package:fluffychat/pangea/download/download_type_enum.dart'; import 'package:fluffychat/pangea/extensions/join_rule_extension.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/utils/file_selector.dart'; @@ -53,7 +52,7 @@ class ChatDetails extends StatefulWidget { // #Pangea // class ChatDetailsController extends State { class ChatDetailsController extends State - with ActivitySummariesProvider, CoursePlanProvider { + with ActivitySummariesProvider, CoursePlanProvider, ChatDownloadProvider { bool loadingActivities = true; bool loadingCourseSummary = true; @@ -246,52 +245,6 @@ class ChatDetailsController extends State } // #Pangea - void downloadChatAction() async { - if (roomId == null) return; - final Room? room = Matrix.of(context).client.getRoomById(roomId!); - if (room == null) return; - - final type = await showModalActionPopup( - context: context, - title: L10n.of(context).downloadGroupText, - actions: [ - AdaptiveModalAction( - value: DownloadType.csv, - label: L10n.of(context).downloadCSVFile, - ), - AdaptiveModalAction( - value: DownloadType.txt, - label: L10n.of(context).downloadTxtFile, - ), - AdaptiveModalAction( - value: DownloadType.xlsx, - label: L10n.of(context).downloadXLSXFile, - ), - ], - ); - if (type == null) return; - - try { - await room.download(type, context); - } on EmptyChatException { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - L10n.of(context).emptyChatDownloadWarning, - ), - ), - ); - } catch (e) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - "${L10n.of(context).oopsSomethingWentWrong} ${L10n.of(context).errorPleaseRefresh}", - ), - ), - ); - } - } - Future setRoomCapacity() async { if (roomId == null) return; final Room? room = Matrix.of(context).client.getRoomById(roomId!); diff --git a/lib/pages/chat_details/chat_download_provider.dart b/lib/pages/chat_details/chat_download_provider.dart new file mode 100644 index 000000000..ce1d9be0a --- /dev/null +++ b/lib/pages/chat_details/chat_download_provider.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/l10n/l10n.dart'; +import 'package:fluffychat/pangea/download/download_room_extension.dart'; +import 'package:fluffychat/pangea/download/download_type_enum.dart'; +import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +mixin ChatDownloadProvider { + void downloadChatAction(String roomId, BuildContext context) async { + final Room? room = Matrix.of(context).client.getRoomById(roomId); + if (room == null) return; + + final type = await showModalActionPopup( + context: context, + title: L10n.of(context).downloadGroupText, + actions: [ + AdaptiveModalAction( + value: DownloadType.csv, + label: L10n.of(context).downloadCSVFile, + ), + AdaptiveModalAction( + value: DownloadType.txt, + label: L10n.of(context).downloadTxtFile, + ), + AdaptiveModalAction( + value: DownloadType.xlsx, + label: L10n.of(context).downloadXLSXFile, + ), + ], + ); + if (type == null) return; + + try { + await room.download(type, context); + } on EmptyChatException { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + L10n.of(context).emptyChatDownloadWarning, + ), + ), + ); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + "${L10n.of(context).oopsSomethingWentWrong} ${L10n.of(context).errorPleaseRefresh}", + ), + ), + ); + } + } +} diff --git a/lib/pangea/activity_sessions/activity_session_chat/activity_session_popup_menu.dart b/lib/pangea/activity_sessions/activity_session_chat/activity_session_popup_menu.dart new file mode 100644 index 000000000..22c791e7f --- /dev/null +++ b/lib/pangea/activity_sessions/activity_session_chat/activity_session_popup_menu.dart @@ -0,0 +1,97 @@ +import 'package:flutter/material.dart'; + +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/l10n/l10n.dart'; +import 'package:fluffychat/pages/chat_details/chat_download_provider.dart'; +import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart'; +import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart'; +import 'package:fluffychat/widgets/future_loading_dialog.dart'; + +enum ActivityPopupMenuActions { invite, leave, download } + +class ActivitySessionPopupMenu extends StatefulWidget { + final Room room; + + const ActivitySessionPopupMenu(this.room, {super.key}); + + @override + ActivitySessionPopupMenuState createState() => + ActivitySessionPopupMenuState(); +} + +class ActivitySessionPopupMenuState extends State + with ChatDownloadProvider { + @override + Widget build(BuildContext context) { + return PopupMenuButton( + useRootNavigator: true, + onSelected: (choice) async { + switch (choice) { + case ActivityPopupMenuActions.leave: + final router = GoRouter.of(context); + final confirmed = await showOkCancelAlertDialog( + context: context, + title: L10n.of(context).areYouSure, + message: L10n.of(context).leaveRoomDescription, + okLabel: L10n.of(context).leave, + cancelLabel: L10n.of(context).cancel, + isDestructive: true, + ); + if (confirmed != OkCancelResult.ok) return; + final result = await showFutureLoadingDialog( + context: context, + future: () => widget.room.leave(), + ); + if (result.error == null) { + router.go('/rooms'); + } + break; + case ActivityPopupMenuActions.invite: + context.go( + widget.room.courseParent != null + ? '/rooms/spaces/${widget.room.courseParent!.id}/${widget.room.id}/invite' + : '/rooms/${widget.room.id}/invite', + ); + break; + case ActivityPopupMenuActions.download: + downloadChatAction(widget.room.id, context); + break; + } + }, + itemBuilder: (BuildContext context) => [ + PopupMenuItem( + value: ActivityPopupMenuActions.invite, + child: Row( + children: [ + const Icon(Icons.person_add_outlined), + const SizedBox(width: 12), + Text(L10n.of(context).invite), + ], + ), + ), + PopupMenuItem( + value: ActivityPopupMenuActions.download, + child: Row( + children: [ + const Icon(Icons.download_outlined), + const SizedBox(width: 12), + Text(L10n.of(context).download), + ], + ), + ), + PopupMenuItem( + value: ActivityPopupMenuActions.leave, + child: Row( + children: [ + const Icon(Icons.delete_outlined), + const SizedBox(width: 12), + Text(L10n.of(context).leave), + ], + ), + ), + ], + ); + } +} diff --git a/lib/pangea/chat_settings/pages/chat_details_button_row.dart b/lib/pangea/chat_settings/pages/chat_details_button_row.dart index b6f16aa3b..1b25cf01f 100644 --- a/lib/pangea/chat_settings/pages/chat_details_button_row.dart +++ b/lib/pangea/chat_settings/pages/chat_details_button_row.dart @@ -110,7 +110,7 @@ class ChatDetailsButtonRowState extends State { ButtonDetails( title: l10n.download, icon: const Icon(Icons.download_outlined, size: 30.0), - onPressed: widget.controller.downloadChatAction, + onPressed: () => widget.controller.downloadChatAction(room.id, context), visible: kIsWeb, enabled: room.ownPowerLevel >= 50, showInMainView: false,