From 5060d2a66d8871ec87f4349729f078fee4269c41 Mon Sep 17 00:00:00 2001 From: Abdullah Alassaf Date: Tue, 21 Jan 2025 15:28:59 +0300 Subject: [PATCH] Updated side tree branch --- lib/common/widgets/custom_expansion_tile.dart | 8 +- lib/pages/space_tree/view/community_tile.dart | 35 +++++ .../space_tree/view/custom_expansion.dart | 127 ++++++++++++++++++ lib/pages/space_tree/view/space_tile.dart | 52 +++++++ .../space_tree/view/space_tree_view.dart | 8 +- 5 files changed, 221 insertions(+), 9 deletions(-) create mode 100644 lib/pages/space_tree/view/community_tile.dart create mode 100644 lib/pages/space_tree/view/custom_expansion.dart create mode 100644 lib/pages/space_tree/view/space_tile.dart diff --git a/lib/common/widgets/custom_expansion_tile.dart b/lib/common/widgets/custom_expansion_tile.dart index b6b33479..8df9b663 100644 --- a/lib/common/widgets/custom_expansion_tile.dart +++ b/lib/common/widgets/custom_expansion_tile.dart @@ -58,18 +58,16 @@ class CustomExpansionTileState extends State { children: [ // Checkbox with independent state management Checkbox( - value: widget.isSelected, + value: false, onChanged: (bool? value) { - if (widget.onItemSelected != null) { - widget.onItemSelected!(); - } + setState(() {}); }, side: WidgetStateBorderSide.resolveWith((states) { return const BorderSide(color: ColorsManager.grayBorder); }), fillColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { - return ColorsManager.blue1; + return ColorsManager.grayBorder; } else { return ColorsManager.checkBoxFillColor; } diff --git a/lib/pages/space_tree/view/community_tile.dart b/lib/pages/space_tree/view/community_tile.dart new file mode 100644 index 00000000..938aa682 --- /dev/null +++ b/lib/pages/space_tree/view/community_tile.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_web/pages/space_tree/view/custom_expansion.dart'; + +class CommunityTileSpaceTree extends StatelessWidget { + final String title; + final List? children; + final bool isExpanded; + final bool isSelected; + final Function(String, bool) onExpansionChanged; + final Function() onItemSelected; + + const CommunityTileSpaceTree({ + super.key, + required this.title, + required this.isExpanded, + required this.onExpansionChanged, + required this.onItemSelected, + required this.isSelected, + this.children, + }); + + @override + Widget build(BuildContext context) { + return CustomExpansionTileSpaceTree( + title: title, + initiallyExpanded: isExpanded, + isSelected: isSelected, + onExpansionChanged: (bool expanded) { + onExpansionChanged(title, expanded); + }, + onItemSelected: onItemSelected, + children: children ?? [], + ); + } +} diff --git a/lib/pages/space_tree/view/custom_expansion.dart b/lib/pages/space_tree/view/custom_expansion.dart new file mode 100644 index 00000000..7314417b --- /dev/null +++ b/lib/pages/space_tree/view/custom_expansion.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; + +class CustomExpansionTileSpaceTree extends StatefulWidget { + final String title; + final List? children; + final bool initiallyExpanded; + final bool isSelected; // Add this to track selection + final bool? isExpanded; // External control over expansion + final ValueChanged? onExpansionChanged; // Notify when expansion changes + final VoidCallback? onItemSelected; // Callback for selecting the item + + CustomExpansionTileSpaceTree({ + required this.title, + this.children, + this.initiallyExpanded = false, + this.isExpanded, // Allow external control over expansion + this.onExpansionChanged, // Notify when expansion changes + this.onItemSelected, // Trigger item selection when name is tapped + required this.isSelected, // Add this to initialize selection state + }); + + @override + CustomExpansionTileState createState() => CustomExpansionTileState(); +} + +class CustomExpansionTileState extends State { + bool _isExpanded = false; // Local expansion state + + @override + void initState() { + super.initState(); + _isExpanded = widget.initiallyExpanded; + } + + @override + void didUpdateWidget(CustomExpansionTileSpaceTree oldWidget) { + super.didUpdateWidget(oldWidget); + // Sync local state with external control of expansion state + if (widget.isExpanded != null && widget.isExpanded != _isExpanded) { + setState(() { + _isExpanded = widget.isExpanded!; + }); + } + } + + // Utility function to capitalize the first letter of the title + String _capitalizeFirstLetter(String text) { + if (text.isEmpty) return text; + return text[0].toUpperCase() + text.substring(1); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Row( + children: [ + // Checkbox with independent state management + Checkbox( + value: widget.isSelected, + onChanged: (bool? value) { + if (widget.onItemSelected != null) { + widget.onItemSelected!(); + } + }, + side: WidgetStateBorderSide.resolveWith((states) { + return const BorderSide(color: ColorsManager.grayBorder); + }), + fillColor: WidgetStateProperty.resolveWith((states) { + if (states.contains(WidgetState.selected)) { + return ColorsManager.blue1; + } else { + return ColorsManager.checkBoxFillColor; + } + }), + checkColor: ColorsManager.whiteColors, + ), + // Expand/collapse icon, now wrapped in a GestureDetector for specific onTap + if (widget.children != null && widget.children!.isNotEmpty) + GestureDetector( + onTap: () { + setState(() { + _isExpanded = !_isExpanded; + widget.onExpansionChanged?.call(_isExpanded); + }); + }, + child: Icon( + _isExpanded ? Icons.keyboard_arrow_down : Icons.keyboard_arrow_right, + color: ColorsManager.lightGrayColor, + size: 16.0, // Adjusted size for better alignment + ), + ), + // The title text, wrapped in GestureDetector to handle selection + Expanded( + child: GestureDetector( + onTap: () { + if (widget.onItemSelected != null) { + widget.onItemSelected!(); + } + }, + child: Text( + _capitalizeFirstLetter(widget.title), + style: TextStyle( + color: widget.isSelected + ? ColorsManager.blackColor // Change color to black when selected + : ColorsManager.lightGrayColor, // Gray when not selected + fontWeight: FontWeight.w400, + ), + ), + ), + ), + ], + ), + // The expanded section (children) that shows when the tile is expanded + if (_isExpanded && widget.children != null && widget.children!.isNotEmpty) + Padding( + padding: const EdgeInsets.only(left: 48.0), // Indented children + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: widget.children!, + ), + ), + ], + ); + } +} diff --git a/lib/pages/space_tree/view/space_tile.dart b/lib/pages/space_tree/view/space_tile.dart new file mode 100644 index 00000000..12d20629 --- /dev/null +++ b/lib/pages/space_tree/view/space_tile.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_web/pages/space_tree/view/custom_expansion.dart'; + +class SpaceTileSpaceTree extends StatefulWidget { + final String title; + final bool isSelected; + + final bool initiallyExpanded; + final ValueChanged onExpansionChanged; + final List? children; + final Function() onItemSelected; + + const SpaceTileSpaceTree({ + super.key, + required this.title, + required this.initiallyExpanded, + required this.onExpansionChanged, + required this.onItemSelected, + required this.isSelected, + this.children, + }); + + @override + _SpaceTileState createState() => _SpaceTileState(); +} + +class _SpaceTileState extends State { + late bool _isExpanded; + + @override + void initState() { + super.initState(); + _isExpanded = widget.initiallyExpanded; + } + + @override + Widget build(BuildContext context) { + return CustomExpansionTileSpaceTree( + isSelected: widget.isSelected, + title: widget.title, + initiallyExpanded: _isExpanded, + onItemSelected: widget.onItemSelected, + onExpansionChanged: (bool expanded) { + setState(() { + _isExpanded = expanded; + }); + widget.onExpansionChanged(expanded); + }, + children: widget.children ?? [], + ); + } +} diff --git a/lib/pages/space_tree/view/space_tree_view.dart b/lib/pages/space_tree/view/space_tree_view.dart index 59e7b73a..06e77df0 100644 --- a/lib/pages/space_tree/view/space_tree_view.dart +++ b/lib/pages/space_tree/view/space_tree_view.dart @@ -4,10 +4,10 @@ import 'package:flutter_svg/svg.dart'; import 'package:syncrow_web/common/widgets/search_bar.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; +import 'package:syncrow_web/pages/space_tree/view/community_tile.dart'; +import 'package:syncrow_web/pages/space_tree/view/space_tile.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_tile.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_tile_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/style.dart'; @@ -194,7 +194,7 @@ class _SpaceTreeViewState extends State { Widget _buildCommunityTile(BuildContext context, CommunityModel community) { bool hasChildren = community.spaces.isNotEmpty; - return CommunityTile( + return CommunityTileSpaceTree( title: community.name, key: ValueKey(community.uuid), isSelected: _selectedCommunityId == community.uuid, @@ -221,7 +221,7 @@ class _SpaceTreeViewState extends State { } Widget _buildSpaceTile(SpaceModel space, CommunityModel community) { - return SpaceTile( + return SpaceTileSpaceTree( title: space.name, key: ValueKey(space.uuid), isSelected: _selectedSpaceUuid == space.uuid,