diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart index b5f54708..8e8cbe8f 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart @@ -633,29 +633,37 @@ class _CommunityStructureAreaState extends State { void _duplicateSpace(SpaceModel space) { final Map originalToDuplicate = {}; - const double horizontalGap = 150.0; + const double horizontalGap = 200.0; const double verticalGap = 100.0; - SpaceModel duplicateRecursive(SpaceModel original, Offset parentPosition) { - // Find a new position for the duplicated space + final Map nameCounters = {}; + + String _generateCopyName(String originalName) { + final baseName = originalName.replaceAll(RegExp(r'\(\d+\)$'), '').trim(); + nameCounters[baseName] = (nameCounters[baseName] ?? 0) + 1; + return "$baseName(${nameCounters[baseName]})"; + } + + SpaceModel duplicateRecursive(SpaceModel original, Offset parentPosition, + SpaceModel? duplicatedParent) { Offset newPosition = parentPosition + Offset(horizontalGap, 0); - // Avoid overlapping with existing spaces while (spaces.any((s) => (s.position - newPosition).distance < horizontalGap && s.status != SpaceStatus.deleted)) { newPosition += Offset(horizontalGap, 0); } - // Create the duplicated space + final duplicatedName = _generateCopyName(original.name); + final duplicated = SpaceModel( - name: "${original.name} (Copy)", + name: duplicatedName, icon: original.icon, position: newPosition, isPrivate: original.isPrivate, children: [], status: SpaceStatus.newSpace, - parent: original.parent, + parent: duplicatedParent, spaceModel: original.spaceModel, subspaces: original.subspaces, tags: original.tags, @@ -663,62 +671,55 @@ class _CommunityStructureAreaState extends State { originalToDuplicate[original] = duplicated; - // Copy the children of the original space to the duplicated space + setState(() { + spaces.add(duplicated); + _updateNodePosition(duplicated, duplicated.position); + + if (duplicatedParent != null) { + final newConnection = Connection( + startSpace: duplicatedParent, + endSpace: duplicated, + direction: "down", + ); + connections.add(newConnection); + duplicated.incomingConnection = newConnection; + duplicatedParent.addOutgoingConnection(newConnection); + } + + if (original.parent != null && duplicatedParent == null) { + final originalParent = original.parent!; + final duplicatedParent = + originalToDuplicate[originalParent] ?? originalParent; + + final parentConnection = Connection( + startSpace: duplicatedParent, + endSpace: duplicated, + direction: original.incomingConnection?.direction ?? "down", + ); + + connections.add(parentConnection); + duplicated.incomingConnection = parentConnection; + duplicatedParent.addOutgoingConnection(parentConnection); + } + }); + Offset childStartPosition = newPosition + Offset(0, verticalGap); for (final child in original.children) { - final duplicatedChild = duplicateRecursive(child, childStartPosition); + final duplicatedChild = + duplicateRecursive(child, childStartPosition, duplicated); duplicated.children.add(duplicatedChild); - duplicatedChild.parent = - duplicated; // Set the parent for the duplicated child childStartPosition += Offset(0, verticalGap); } return duplicated; } - // Duplicate the selected space and its children - final duplicatedSpace = duplicateRecursive(space, space.position); - - // Ensure the duplicated space has the same parent as the original - if (space.parent != null) { - final parentSpace = space.parent!; - final duplicatedParent = originalToDuplicate[parentSpace] ?? parentSpace; - duplicatedSpace.parent = duplicatedParent; - duplicatedParent.children.add(duplicatedSpace); + if (space.parent == null) { + duplicateRecursive(space, space.position, null); + } else { + final duplicatedParent = + originalToDuplicate[space.parent!] ?? space.parent!; + duplicateRecursive(space, space.position, duplicatedParent); } - - // Flatten the hierarchy of the duplicated spaces - List flattenHierarchy(SpaceModel root) { - final List result = []; - void traverse(SpaceModel node) { - result.add(node); - for (final child in node.children) { - traverse(child); - } - } - - traverse(root); - return result; - } - - final duplicatedSpacesList = flattenHierarchy(duplicatedSpace); - - setState(() { - spaces.addAll(duplicatedSpacesList); - - // Duplicate the connections - for (final connection in connections) { - if (originalToDuplicate.containsKey(connection.startSpace) && - originalToDuplicate.containsKey(connection.endSpace)) { - connections.add( - Connection( - startSpace: originalToDuplicate[connection.startSpace]!, - endSpace: originalToDuplicate[connection.endSpace]!, - direction: connection.direction, - ), - ); - } - } - }); } }