161 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Dart
		
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Dart
		
	
	
	
| import 'dart:typed_data';
 | |
| 
 | |
| import 'package:flutter/material.dart';
 | |
| 
 | |
| import 'package:flutter_gen/gen_l10n/l10n.dart';
 | |
| import 'package:go_router/go_router.dart';
 | |
| import 'package:matrix/matrix.dart' as sdk;
 | |
| import 'package:matrix/matrix.dart';
 | |
| 
 | |
| import 'package:fluffychat/pages/new_group/new_group_view.dart';
 | |
| import 'package:fluffychat/utils/file_selector.dart';
 | |
| import 'package:fluffychat/widgets/matrix.dart';
 | |
| 
 | |
| class NewGroup extends StatefulWidget {
 | |
|   final CreateGroupType createGroupType;
 | |
|   const NewGroup({
 | |
|     this.createGroupType = CreateGroupType.group,
 | |
|     super.key,
 | |
|   });
 | |
| 
 | |
|   @override
 | |
|   NewGroupController createState() => NewGroupController();
 | |
| }
 | |
| 
 | |
| class NewGroupController extends State<NewGroup> {
 | |
|   TextEditingController nameController = TextEditingController();
 | |
| 
 | |
|   bool publicGroup = false;
 | |
|   bool groupCanBeFound = false;
 | |
|   bool enableEncryption = false;
 | |
| 
 | |
|   Uint8List? avatar;
 | |
| 
 | |
|   Uri? avatarUrl;
 | |
| 
 | |
|   Object? error;
 | |
| 
 | |
|   bool loading = false;
 | |
| 
 | |
|   CreateGroupType get createGroupType =>
 | |
|       _createGroupType ?? widget.createGroupType;
 | |
| 
 | |
|   CreateGroupType? _createGroupType;
 | |
| 
 | |
|   void setCreateGroupType(Set<CreateGroupType> b) =>
 | |
|       setState(() => _createGroupType = b.single);
 | |
| 
 | |
|   void setPublicGroup(bool b) =>
 | |
|       setState(() => publicGroup = groupCanBeFound = b);
 | |
| 
 | |
|   void setGroupCanBeFound(bool b) => setState(() => groupCanBeFound = b);
 | |
| 
 | |
|   void setEnableEncryption(bool b) => setState(() => enableEncryption = b);
 | |
| 
 | |
|   void selectPhoto() async {
 | |
|     final photo = await selectFiles(
 | |
|       context,
 | |
|       type: FileSelectorType.images,
 | |
|       allowMultiple: false,
 | |
|     );
 | |
|     final bytes = await photo.singleOrNull?.readAsBytes();
 | |
| 
 | |
|     setState(() {
 | |
|       avatarUrl = null;
 | |
|       avatar = bytes;
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   Future<void> _createGroup() async {
 | |
|     if (!mounted) return;
 | |
|     final roomId = await Matrix.of(context).client.createGroupChat(
 | |
|       visibility:
 | |
|           groupCanBeFound ? sdk.Visibility.public : sdk.Visibility.private,
 | |
|       enableEncryption: enableEncryption,
 | |
|       groupName: nameController.text.isNotEmpty ? nameController.text : null,
 | |
|       initialState: [
 | |
|         if (avatar != null)
 | |
|           sdk.StateEvent(
 | |
|             type: sdk.EventTypes.RoomAvatar,
 | |
|             content: {'url': avatarUrl.toString()},
 | |
|           ),
 | |
|         sdk.StateEvent(
 | |
|           type: sdk.EventTypes.RoomJoinRules,
 | |
|           content: {'join_rule': publicGroup ? 'public' : 'invite'}
 | |
|         )
 | |
|       ],
 | |
|     );
 | |
|     final room = Matrix.of(context).client.getRoomById(roomId);
 | |
|     // if (room != null) {
 | |
|     //   room.setJoinRules(publicGroup ? JoinRules.public : JoinRules.invite);
 | |
|     // }
 | |
|     if (!mounted) return;
 | |
|     context.go('/rooms/$roomId/invite');
 | |
|   }
 | |
| 
 | |
|   Future<void> _createSpace() async {
 | |
|     if (!mounted) return;
 | |
|     final spaceId = await Matrix.of(context).client.createRoom(
 | |
|           preset: publicGroup
 | |
|               ? sdk.CreateRoomPreset.publicChat
 | |
|               : sdk.CreateRoomPreset.privateChat,
 | |
|           creationContent: {'type': RoomCreationTypes.mSpace},
 | |
|           visibility: publicGroup ? sdk.Visibility.public : null,
 | |
|           roomAliasName: publicGroup
 | |
|               ? nameController.text.trim().toLowerCase().replaceAll(' ', '_')
 | |
|               : null,
 | |
|           name: nameController.text.trim(),
 | |
|           powerLevelContentOverride: {'events_default': 100},
 | |
|           initialState: [
 | |
|             if (avatar != null)
 | |
|               sdk.StateEvent(
 | |
|                 type: sdk.EventTypes.RoomAvatar,
 | |
|                 content: {'url': avatarUrl.toString()},
 | |
|               ),
 | |
|           ],
 | |
|         );
 | |
|     if (!mounted) return;
 | |
|     context.pop<String>(spaceId);
 | |
|   }
 | |
| 
 | |
|   void submitAction([_]) async {
 | |
|     final client = Matrix.of(context).client;
 | |
| 
 | |
|     try {
 | |
|       if (nameController.text.trim().isEmpty &&
 | |
|           createGroupType == CreateGroupType.space) {
 | |
|         setState(() => error = L10n.of(context).pleaseFillOut);
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       setState(() {
 | |
|         loading = true;
 | |
|         error = null;
 | |
|       });
 | |
| 
 | |
|       final avatar = this.avatar;
 | |
|       avatarUrl ??= avatar == null ? null : await client.uploadContent(avatar);
 | |
| 
 | |
|       if (!mounted) return;
 | |
| 
 | |
|       switch (createGroupType) {
 | |
|         case CreateGroupType.group:
 | |
|           await _createGroup();
 | |
|         case CreateGroupType.space:
 | |
|           await _createSpace();
 | |
|       }
 | |
|     } catch (e, s) {
 | |
|       sdk.Logs().d('Unable to create group', e, s);
 | |
|       setState(() {
 | |
|         error = e;
 | |
|         loading = false;
 | |
|       });
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) => NewGroupView(this);
 | |
| }
 | |
| 
 | |
| enum CreateGroupType { group, space }
 |