ExteraNext/lib/pages/new_group/new_group.dart

161 lines
4.4 KiB
Dart

import 'dart:typed_data';
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' as sdk;
import 'package:matrix/matrix.dart';
import 'package:extera_next/pages/new_group/new_group_view.dart';
import 'package:extera_next/utils/file_selector.dart';
import 'package:extera_next/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 }