prevent users from nesting spaces (#1173)

This commit is contained in:
ggurdin 2024-12-06 13:40:06 -05:00 committed by GitHub
parent 4193ba1a4d
commit 0e91d93148
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 101 additions and 94 deletions

View file

@ -4522,5 +4522,7 @@
"chatCanBeFoundViaSearch": "Chat can be found via search",
"requireCodeToJoin": "Require code to join",
"canFindInSearch": "Can find in search",
"addSubspaceWarning": "Once you add this, it will not appear in public search results, and it will be visible to all members of the parent space."
"addSubspaceWarning": "Once you add this, it will not appear in public search results, and it will be visible to all members of the parent space.",
"nestedSpaceError": "Spaces should not be added as children of other spaces",
"addChatToSpace": "Add chat"
}

View file

@ -815,7 +815,12 @@ class ChatListController extends State<ChatList>
],
),
),
if (spacesWithPowerLevels.isNotEmpty)
if (spacesWithPowerLevels.isNotEmpty
// #Pangea
&&
!room.isSpace
// Pangea#
)
PopupMenuItem(
value: ChatContextAction.addToSpace,
child: Row(
@ -937,7 +942,17 @@ class ChatListController extends State<ChatList>
context: context,
// #Pangea
// future: () => space.setSpaceChild(room.id),
future: () => space.pangeaSetSpaceChild(room.id),
future: () async {
try {
await space.pangeaSetSpaceChild(room.id);
} catch (err) {
if (err is NestedSpaceError) {
throw L10n.of(context)!.nestedSpaceError;
} else {
rethrow;
}
}
},
// Pangea#
);
// #Pangea

View file

@ -22,7 +22,12 @@ import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart' as sdk;
import 'package:matrix/matrix.dart';
enum AddRoomType { chat, subspace }
enum AddRoomType {
chat,
// #Pangea
// subspace,
// Pangea#
}
class SpaceView extends StatefulWidget {
final String spaceId;
@ -310,35 +315,29 @@ class _SpaceViewState extends State<SpaceView> {
}
void _addChatOrSubspace() async {
final roomType = await showConfirmationDialog(
context: context,
title: L10n.of(context)!.addChatOrSubSpace,
actions: [
AlertDialogAction(
key: AddRoomType.subspace,
// #Pangea
// label: L10n.of(context)!.createNewSpace,
label: L10n.of(context)!.newSpace,
// Pangea#
),
AlertDialogAction(
key: AddRoomType.chat,
// #Pangea
// label: L10n.of(context)!.createGroup,
label: L10n.of(context)!.newChat,
// Pangea#
),
],
);
if (roomType == null) return;
// #Pangea
// final roomType = await showConfirmationDialog(
// context: context,
// title: L10n.of(context)!.addChatOrSubSpace,
// actions: [
// AlertDialogAction(
// key: AddRoomType.subspace,
// label: L10n.of(context)!.createNewSpace,
// ),
// AlertDialogAction(
// key: AddRoomType.chat,
// label: L10n.of(context)!.createGroup,
// ),
// ],
// );
// if (roomType == null) return;
// Pangea#
// #Pangea
final RoomResponse? response = await showDialog<RoomResponse?>(
context: context,
builder: (context) {
return AddRoomDialog(
roomType: roomType,
);
return const AddRoomDialog();
},
);
if (response == null) return;
@ -385,63 +384,50 @@ class _SpaceViewState extends State<SpaceView> {
final activeSpace = client.getRoomById(widget.spaceId)!;
await activeSpace.postLoad();
if (roomType == AddRoomType.subspace) {
// #Pangea
// if (roomType == AddRoomType.subspace) {
// roomId = await client.createSpace(
// name: names.first,
// topic: names.last.isEmpty ? null : names.last,
// visibility: activeSpace.joinRules == JoinRules.public
// ? sdk.Visibility.public
// : sdk.Visibility.private,
// );
// } else {
// Pangea#
roomId = await client.createGroupChat(
// #Pangea
// roomId = await client.createSpace(
// name: names.first,
// topic: names.last.isEmpty ? null : names.last,
// visibility: activeSpace.joinRules == JoinRules.public
// ? sdk.Visibility.public
// : sdk.Visibility.private,
// );
roomId = await client.createRoom(
preset: response.joinRules == sdk.JoinRules.public
? sdk.CreateRoomPreset.publicChat
: sdk.CreateRoomPreset.privateChat,
creationContent: {'type': RoomCreationTypes.mSpace},
visibility: response.joinRules == sdk.JoinRules.public
? response.visibility
: null,
name: response.roomName,
topic: response.roomDescription,
powerLevelContentOverride: {'events_default': 100},
);
// groupName: names.first,
// preset: activeSpace.joinRules == JoinRules.public
// ? CreateRoomPreset.publicChat
// : CreateRoomPreset.privateChat,
// visibility: activeSpace.joinRules == JoinRules.public
// ? sdk.Visibility.public
// : sdk.Visibility.private,
// initialState: names.length > 1 && names.last.isNotEmpty
// ? [
// StateEvent(
// type: EventTypes.RoomTopic,
// content: {'topic': names.last},
// ),
// ]
// : null,
groupName: response.roomName,
preset: response.joinRules == sdk.JoinRules.public
? CreateRoomPreset.publicChat
: CreateRoomPreset.privateChat,
visibility: response.visibility,
initialState: response.roomDescription.isNotEmpty
? [
StateEvent(
type: EventTypes.RoomTopic,
content: {'topic': response.roomDescription},
),
]
: null,
enableEncryption: false,
// Pangea#
} else {
roomId = await client.createGroupChat(
// #Pangea
// groupName: names.first,
// preset: activeSpace.joinRules == JoinRules.public
// ? CreateRoomPreset.publicChat
// : CreateRoomPreset.privateChat,
// visibility: activeSpace.joinRules == JoinRules.public
// ? sdk.Visibility.public
// : sdk.Visibility.private,
// initialState: names.length > 1 && names.last.isNotEmpty
// ? [
// StateEvent(
// type: EventTypes.RoomTopic,
// content: {'topic': names.last},
// ),
// ]
// : null,
groupName: response.roomName,
preset: response.joinRules == sdk.JoinRules.public
? CreateRoomPreset.publicChat
: CreateRoomPreset.privateChat,
visibility: response.visibility,
initialState: response.roomDescription.isNotEmpty
? [
StateEvent(
type: EventTypes.RoomTopic,
content: {'topic': response.roomDescription},
),
]
: null,
enableEncryption: false,
// Pangea#
);
}
);
await activeSpace.setSpaceChild(roomId);
},
);
@ -757,7 +743,10 @@ class _SpaceViewState extends State<SpaceView> {
child: Icon(Icons.add_outlined),
),
title: Text(
L10n.of(context)!.addChatOrSubSpace,
// #Pangea
// L10n.of(context)!.addChatOrSubSpace,
L10n.of(context)!.addChatToSpace,
// Pangea#
style: const TextStyle(fontSize: 14),
),
),

View file

@ -117,6 +117,10 @@ extension ChildrenAndParentsRoomExtension on Room {
}) async {
final Room? child = client.getRoomById(roomId);
if (child == null) return;
if (child.isSpace) {
throw NestedSpaceError();
}
final List<Room> spaceParents = child.pangeaSpaceParents;
for (final Room parent in spaceParents) {
try {
@ -151,3 +155,8 @@ extension ChildrenAndParentsRoomExtension on Room {
return suggestionStatus;
}
}
class NestedSpaceError extends Error {
@override
String toString() => 'Cannot add a space to another space';
}

View file

@ -1,14 +1,10 @@
import 'package:fluffychat/pages/chat_list/space_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart' as matrix;
import 'package:matrix/matrix.dart';
class AddRoomDialog extends StatefulWidget {
final AddRoomType? roomType;
const AddRoomDialog({
required this.roomType,
super.key,
});
@ -47,17 +43,13 @@ class AddRoomDialogState extends State<AddRoomDialog> {
children: [
Text(
style: Theme.of(context).textTheme.headlineSmall,
widget.roomType == AddRoomType.subspace
? L10n.of(context)!.createNewSpace
: L10n.of(context)!.createChat,
L10n.of(context)!.createChat,
),
const SizedBox(height: 20),
TextFormField(
controller: _roomNameController,
decoration: InputDecoration(
hintText: widget.roomType == AddRoomType.subspace
? L10n.of(context)!.spaceName
: L10n.of(context)!.chatName,
hintText: L10n.of(context)!.chatName,
),
minLines: 1,
maxLines: 1,