refactor: separate dropdown menu for activity sessions

This commit is contained in:
ggurdin 2025-11-05 14:06:19 -05:00
parent 38f07bc0f2
commit f0185441dd
No known key found for this signature in database
GPG key ID: A01CB41737CBB478
5 changed files with 203 additions and 91 deletions

View file

@ -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

View file

@ -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<ChatDetails> {
class ChatDetailsController extends State<ChatDetails>
with ActivitySummariesProvider, CoursePlanProvider {
with ActivitySummariesProvider, CoursePlanProvider, ChatDownloadProvider {
bool loadingActivities = true;
bool loadingCourseSummary = true;
@ -246,52 +245,6 @@ class ChatDetailsController extends State<ChatDetails>
}
// #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<void> setRoomCapacity() async {
if (roomId == null) return;
final Room? room = Matrix.of(context).client.getRoomById(roomId!);

View file

@ -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}",
),
),
);
}
}
}

View file

@ -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<ActivitySessionPopupMenu>
with ChatDownloadProvider {
@override
Widget build(BuildContext context) {
return PopupMenuButton<ActivityPopupMenuActions>(
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<ActivityPopupMenuActions>(
value: ActivityPopupMenuActions.invite,
child: Row(
children: [
const Icon(Icons.person_add_outlined),
const SizedBox(width: 12),
Text(L10n.of(context).invite),
],
),
),
PopupMenuItem<ActivityPopupMenuActions>(
value: ActivityPopupMenuActions.download,
child: Row(
children: [
const Icon(Icons.download_outlined),
const SizedBox(width: 12),
Text(L10n.of(context).download),
],
),
),
PopupMenuItem<ActivityPopupMenuActions>(
value: ActivityPopupMenuActions.leave,
child: Row(
children: [
const Icon(Icons.delete_outlined),
const SizedBox(width: 12),
Text(L10n.of(context).leave),
],
),
),
],
);
}
}

View file

@ -110,7 +110,7 @@ class ChatDetailsButtonRowState extends State<ChatDetailsButtonRow> {
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,