Implement SpaceTreeDropdownBloc for improved state management in SpaceTreeDropdown; refactor dropdown logic and event handling.

This commit is contained in:
mohammad
2025-06-11 14:14:21 +03:00
parent d66921c615
commit fc86042af7
4 changed files with 137 additions and 85 deletions

View File

@ -5,6 +5,7 @@ import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'space_tree_dropdown_bloc.dart';
class SpaceTreeDropdown extends StatefulWidget { class SpaceTreeDropdown extends StatefulWidget {
final String? selectedSpaceId; final String? selectedSpaceId;
@ -21,18 +22,19 @@ class SpaceTreeDropdown extends StatefulWidget {
} }
class _SpaceTreeDropdownState extends State<SpaceTreeDropdown> { class _SpaceTreeDropdownState extends State<SpaceTreeDropdown> {
late String? _selectedSpaceId; late SpaceTreeDropdownBloc _dropdownBloc;
final LayerLink _layerLink = LayerLink(); final LayerLink _layerLink = LayerLink();
OverlayEntry? _overlayEntry; OverlayEntry? _overlayEntry;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_selectedSpaceId = widget.selectedSpaceId; _dropdownBloc = SpaceTreeDropdownBloc(widget.selectedSpaceId);
} }
@override @override
void dispose() { void dispose() {
_dropdownBloc.close();
_removeOverlay(); _removeOverlay();
super.dispose(); super.dispose();
} }
@ -44,21 +46,27 @@ class _SpaceTreeDropdownState extends State<SpaceTreeDropdown> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<SpaceTreeBloc, SpaceTreeState>( return BlocProvider.value(
builder: (context, state) { value: _dropdownBloc,
final communities = state.searchQuery.isNotEmpty child: BlocBuilder<SpaceTreeBloc, SpaceTreeState>(
? state.filteredCommunity builder: (context, spaceTreeState) {
: state.communityList; final communities = spaceTreeState.searchQuery.isNotEmpty
final selectedCommunity = _findCommunity(communities, _selectedSpaceId); ? spaceTreeState.filteredCommunity
: spaceTreeState.communityList;
return BlocBuilder<SpaceTreeDropdownBloc, SpaceTreeDropdownState>(
builder: (context, dropdownState) {
final selectedCommunity = _findCommunity(
communities,
dropdownState.selectedSpaceId,
);
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(horizontal: 10),
horizontal: 10,
),
child: Text( child: Text(
"Community", "Community",
style: Theme.of(context).textTheme.bodyMedium!.copyWith( style: Theme.of(context).textTheme.bodyMedium!.copyWith(
@ -71,21 +79,20 @@ class _SpaceTreeDropdownState extends State<SpaceTreeDropdown> {
CompositedTransformTarget( CompositedTransformTarget(
link: _layerLink, link: _layerLink,
child: GestureDetector( child: GestureDetector(
onTap: _toggleDropdown, onTap: () => _toggleDropdown(context, communities),
child: Container( child: Container(
height: 46, height: 46,
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300), border: Border.all(color: Colors.grey.shade300),
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
margin: const EdgeInsets.symmetric( margin: const EdgeInsets.symmetric(horizontal: 10),
horizontal: 10,
),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 10), padding:
const EdgeInsets.symmetric(horizontal: 10),
child: Text( child: Text(
selectedCommunity?.name ?? 'Please Select', selectedCommunity?.name ?? 'Please Select',
style: TextStyle( style: TextStyle(
@ -122,9 +129,12 @@ class _SpaceTreeDropdownState extends State<SpaceTreeDropdown> {
); );
}, },
); );
},
),
);
} }
void _toggleDropdown() { void _toggleDropdown(BuildContext context, List<CommunityModel> communities) {
if (_overlayEntry != null) { if (_overlayEntry != null) {
_removeOverlay(); _removeOverlay();
return; return;
@ -141,10 +151,10 @@ class _SpaceTreeDropdownState extends State<SpaceTreeDropdown> {
elevation: 8, elevation: 8,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
child: DropdownMenuContent( child: DropdownMenuContent(
selectedSpaceId: _selectedSpaceId, selectedSpaceId: _dropdownBloc.state.selectedSpaceId,
onChanged: (id) { onChanged: (id) {
if (id != null && mounted) { if (id != null && mounted) {
setState(() => _selectedSpaceId = id); _dropdownBloc.add(SpaceTreeDropdownSelectEvent(id));
widget.onChanged?.call(id); widget.onChanged?.call(id);
_removeOverlay(); _removeOverlay();
} }
@ -162,17 +172,10 @@ class _SpaceTreeDropdownState extends State<SpaceTreeDropdown> {
CommunityModel? _findCommunity( CommunityModel? _findCommunity(
List<CommunityModel> communities, String? communityId) { List<CommunityModel> communities, String? communityId) {
if (communityId == null) return null; if (communityId == null) return null;
try { try {
return communities.firstWhere((c) => c.uuid == communityId); return communities.firstWhere((c) => c.uuid == communityId);
} catch (e) { } catch (e) {
return CommunityModel( return null;
uuid: '',
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
name: '',
description: '',
spaces: []);
} }
} }
} }

View File

@ -0,0 +1,27 @@
import 'package:flutter_bloc/flutter_bloc.dart';
part 'space_tree_dropdown_event.dart';
part 'space_tree_dropdown_state.dart';
class SpaceTreeDropdownBloc
extends Bloc<SpaceTreeDropdownEvent, SpaceTreeDropdownState> {
SpaceTreeDropdownBloc(String? initialId)
: super(SpaceTreeDropdownState(selectedSpaceId: initialId)) {
on<SpaceTreeDropdownSelectEvent>(_onSelect);
on<SpaceTreeDropdownResetEvent>(_onReset);
}
void _onSelect(
SpaceTreeDropdownSelectEvent event,
Emitter<SpaceTreeDropdownState> emit,
) {
emit(SpaceTreeDropdownState(selectedSpaceId: event.spaceId));
}
void _onReset(
SpaceTreeDropdownResetEvent event,
Emitter<SpaceTreeDropdownState> emit,
) {
emit(SpaceTreeDropdownState(selectedSpaceId: event.initialId));
}
}

View File

@ -0,0 +1,15 @@
part of 'space_tree_dropdown_bloc.dart';
abstract class SpaceTreeDropdownEvent {}
class SpaceTreeDropdownSelectEvent extends SpaceTreeDropdownEvent {
final String? spaceId;
SpaceTreeDropdownSelectEvent(this.spaceId);
}
class SpaceTreeDropdownResetEvent extends SpaceTreeDropdownEvent {
final String? initialId;
SpaceTreeDropdownResetEvent(this.initialId);
}

View File

@ -0,0 +1,7 @@
part of 'space_tree_dropdown_bloc.dart';
class SpaceTreeDropdownState {
final String? selectedSpaceId;
SpaceTreeDropdownState({this.selectedSpaceId});
}