diff --git a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart index 9e161f55..ae9f846a 100644 --- a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart +++ b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/main_module/helpers/spaces_recursive_helper.dart'; @@ -51,13 +53,22 @@ class _CommunityStructureCanvasState extends State duration: const Duration(milliseconds: 150), ); super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) { + _centerOnTree(); + } + }); } @override void didUpdateWidget(covariant CommunityStructureCanvas oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.community.uuid != widget.community.uuid) { - _animateToSpace(null); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) { + _centerOnTree(animate: true); + } + }); } else if (widget.selectedSpace?.uuid != oldWidget.selectedSpace?.uuid) { WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) { @@ -152,6 +163,60 @@ class _CommunityStructureCanvasState extends State _runAnimation(matrix); } + void _centerOnTree({bool animate = false}) { + if (_positions.isEmpty) { + if (animate) { + _runAnimation(Matrix4.identity()); + } else { + _transformationController.value = Matrix4.identity(); + } + return; + } + + var minX = double.infinity; + var maxX = double.negativeInfinity; + var minY = double.infinity; + var maxY = double.negativeInfinity; + + _positions.forEach((uuid, offset) { + final cardWidth = _cardWidths[uuid] ?? _minCardWidth; + minX = min(minX, offset.dx); + maxX = max(maxX, offset.dx + cardWidth); + minY = min(minY, offset.dy); + maxY = max(maxY, offset.dy + _cardHeight); + }); + + if (!minX.isFinite || !maxX.isFinite || !minY.isFinite || !maxY.isFinite) { + return; + } + + final treeWidth = maxX - minX; + final treeHeight = maxY - minY; + + final viewSize = context.size; + if (viewSize == null) return; + + final scaleX = viewSize.width / treeWidth; + final scaleY = viewSize.height / treeHeight; + final scale = min(scaleX, scaleY).clamp(0.5, 1.0) * 0.9; + + final treeCenterX = minX + treeWidth / 2; + final treeCenterY = minY + treeHeight / 2; + + final x = -treeCenterX * scale + viewSize.width / 2; + final y = -treeCenterY * scale + viewSize.height / 2; + + final matrix = Matrix4.identity() + ..translate(x, y) + ..scale(scale); + + if (animate) { + _runAnimation(matrix); + } else { + _transformationController.value = matrix; + } + } + void _onReorder(SpaceReorderDataModel data, int newIndex) { final newCommunity = widget.community.copyWith(); final children = data.parent?.children ?? newCommunity.spaces;