166 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Dart
		
	
	
	
			
		
		
	
	
			166 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Dart
		
	
	
	
| import 'dart:async';
 | |
| 
 | |
| import 'package:flutter/material.dart';
 | |
| 
 | |
| import 'package:extera_next/generated/l10n/l10n.dart';
 | |
| import 'package:go_router/go_router.dart';
 | |
| import 'package:matrix/matrix.dart';
 | |
| 
 | |
| import 'package:extera_next/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
 | |
| import 'package:extera_next/widgets/future_loading_dialog.dart';
 | |
| import 'matrix.dart';
 | |
| 
 | |
| enum ChatPopupMenuActions { details, mute, unmute, leave, search }
 | |
| 
 | |
| class ChatSettingsPopupMenu extends StatefulWidget {
 | |
|   final Room room;
 | |
|   final bool displayChatDetails;
 | |
| 
 | |
|   const ChatSettingsPopupMenu(this.room, this.displayChatDetails, {super.key});
 | |
| 
 | |
|   @override
 | |
|   ChatSettingsPopupMenuState createState() => ChatSettingsPopupMenuState();
 | |
| }
 | |
| 
 | |
| class ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
 | |
|   StreamSubscription? notificationChangeSub;
 | |
| 
 | |
|   @override
 | |
|   void dispose() {
 | |
|     notificationChangeSub?.cancel();
 | |
|     super.dispose();
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     notificationChangeSub ??= Matrix.of(context)
 | |
|         .client
 | |
|         .onSync
 | |
|         .stream
 | |
|         .where(
 | |
|           (syncUpdate) =>
 | |
|               syncUpdate.accountData?.any(
 | |
|                 (accountData) => accountData.type == 'm.push_rules',
 | |
|               ) ??
 | |
|               false,
 | |
|         )
 | |
|         .listen(
 | |
|           (u) => setState(() {}),
 | |
|         );
 | |
|     return Stack(
 | |
|       alignment: Alignment.center,
 | |
|       children: [
 | |
|         const SizedBox.shrink(),
 | |
|         PopupMenuButton<ChatPopupMenuActions>(
 | |
|           onSelected: (choice) async {
 | |
|             switch (choice) {
 | |
|               case ChatPopupMenuActions.leave:
 | |
|                 final confirmed = await showOkCancelAlertDialog(
 | |
|                   context: context,
 | |
|                   title: L10n.of(context).areYouSure,
 | |
|                   message: L10n.of(context).archiveRoomDescription,
 | |
|                   okLabel: L10n.of(context).leave,
 | |
|                   cancelLabel: L10n.of(context).cancel,
 | |
|                   isDestructive: true,
 | |
|                 );
 | |
|                 if (confirmed == OkCancelResult.ok) {
 | |
|                   final success = await showFutureLoadingDialog(
 | |
|                     context: context,
 | |
|                     future: () => widget.room.leave(),
 | |
|                   );
 | |
|                   if (success.error == null) {
 | |
|                     context.go('/rooms');
 | |
|                   }
 | |
|                 }
 | |
|                 break;
 | |
|               case ChatPopupMenuActions.mute:
 | |
|                 await showFutureLoadingDialog(
 | |
|                   context: context,
 | |
|                   future: () =>
 | |
|                       widget.room.setPushRuleState(PushRuleState.mentionsOnly),
 | |
|                 );
 | |
|                 break;
 | |
|               case ChatPopupMenuActions.unmute:
 | |
|                 await showFutureLoadingDialog(
 | |
|                   context: context,
 | |
|                   future: () =>
 | |
|                       widget.room.setPushRuleState(PushRuleState.notify),
 | |
|                 );
 | |
|                 break;
 | |
|               case ChatPopupMenuActions.details:
 | |
|                 _showChatDetails();
 | |
|                 break;
 | |
|               case ChatPopupMenuActions.search:
 | |
|                 context.go('/rooms/${widget.room.id}/search');
 | |
|                 break;
 | |
|             }
 | |
|           },
 | |
|           itemBuilder: (BuildContext context) => [
 | |
|             if (widget.displayChatDetails)
 | |
|               PopupMenuItem<ChatPopupMenuActions>(
 | |
|                 value: ChatPopupMenuActions.details,
 | |
|                 child: Row(
 | |
|                   children: [
 | |
|                     const Icon(Icons.info_outline_rounded),
 | |
|                     const SizedBox(width: 12),
 | |
|                     Text(L10n.of(context).chatDetails),
 | |
|                   ],
 | |
|                 ),
 | |
|               ),
 | |
|             if (widget.room.pushRuleState == PushRuleState.notify)
 | |
|               PopupMenuItem<ChatPopupMenuActions>(
 | |
|                 value: ChatPopupMenuActions.mute,
 | |
|                 child: Row(
 | |
|                   children: [
 | |
|                     const Icon(Icons.notifications_off_outlined),
 | |
|                     const SizedBox(width: 12),
 | |
|                     Text(L10n.of(context).muteChat),
 | |
|                   ],
 | |
|                 ),
 | |
|               )
 | |
|             else
 | |
|               PopupMenuItem<ChatPopupMenuActions>(
 | |
|                 value: ChatPopupMenuActions.unmute,
 | |
|                 child: Row(
 | |
|                   children: [
 | |
|                     const Icon(Icons.notifications_on_outlined),
 | |
|                     const SizedBox(width: 12),
 | |
|                     Text(L10n.of(context).unmuteChat),
 | |
|                   ],
 | |
|                 ),
 | |
|               ),
 | |
|             PopupMenuItem<ChatPopupMenuActions>(
 | |
|               value: ChatPopupMenuActions.search,
 | |
|               child: Row(
 | |
|                 children: [
 | |
|                   const Icon(Icons.search_outlined),
 | |
|                   const SizedBox(width: 12),
 | |
|                   Text(L10n.of(context).search),
 | |
|                 ],
 | |
|               ),
 | |
|             ),
 | |
|             PopupMenuItem<ChatPopupMenuActions>(
 | |
|               value: ChatPopupMenuActions.leave,
 | |
|               child: Row(
 | |
|                 children: [
 | |
|                   const Icon(Icons.delete_outlined),
 | |
|                   const SizedBox(width: 12),
 | |
|                   Text(L10n.of(context).leave),
 | |
|                 ],
 | |
|               ),
 | |
|             ),
 | |
|           ],
 | |
|         ),
 | |
|       ],
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   void _showChatDetails() {
 | |
|     if (GoRouterState.of(context).uri.path.endsWith('/details')) {
 | |
|       context.go('/rooms/${widget.room.id}');
 | |
|     } else {
 | |
|       context.go('/rooms/${widget.room.id}/details');
 | |
|     }
 | |
|   }
 | |
| }
 |