Refactor SpaceDetailsDialog and SpaceIconPicker to integrate Bloc for state management, enhancing icon selection and dialog functionality.

This commit is contained in:
Faris Armoush
2025-07-02 15:20:52 +03:00
parent 63353af38b
commit 9dfb3ed369
6 changed files with 99 additions and 65 deletions

View File

@ -7,7 +7,6 @@ import 'package:syncrow_web/pages/space_management_v2/modules/communities/data/s
import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/params/load_communities_param.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/params/load_communities_param.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/bloc/communities_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/bloc/communities_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/communities_tree_selection_bloc/communities_tree_selection_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/communities_tree_selection_bloc/communities_tree_selection_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/update_space/presentation/bloc/space_details_model_bloc/space_details_model_bloc.dart';
import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/theme/responsive_text_theme.dart'; import 'package:syncrow_web/utils/theme/responsive_text_theme.dart';
import 'package:syncrow_web/web_layout/web_scaffold.dart'; import 'package:syncrow_web/web_layout/web_scaffold.dart';
@ -19,7 +18,6 @@ class SpaceManagementPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MultiBlocProvider( return MultiBlocProvider(
providers: [ providers: [
BlocProvider(create: (context) => SpaceDetailsModelBloc()),
BlocProvider( BlocProvider(
create: (context) => CommunitiesBloc( create: (context) => CommunitiesBloc(
communitiesService: DebouncedCommunitiesService( communitiesService: DebouncedCommunitiesService(

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/space_details_model.dart' import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/space_details_model.dart'
show SpaceDetailsModel; show SpaceDetailsModel;
import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_details_action_buttons.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_details_action_buttons.dart';
@ -6,6 +7,7 @@ import 'package:syncrow_web/pages/space_management_v2/modules/space_details/pres
import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_icon_picker.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_icon_picker.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_name_text_field.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_name_text_field.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_sub_spaces_box.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_sub_spaces_box.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/update_space/presentation/bloc/space_details_model_bloc/space_details_model_bloc.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';
@ -23,6 +25,10 @@ class SpaceDetailsDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider(
create: (context) => SpaceDetailsModelBloc(initialState: space),
child: Builder(builder: (context) {
final space = context.watch<SpaceDetailsModelBloc>().state;
return AlertDialog( return AlertDialog(
title: title, title: title,
backgroundColor: ColorsManager.whiteColors, backgroundColor: ColorsManager.whiteColors,
@ -34,9 +40,7 @@ class SpaceDetailsDialog extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
flex: 1, flex: 1,
child: SpaceIconPicker( child: SpaceIconPicker(iconPath: space.icon)
iconPath: space.icon,
),
), ),
Expanded( Expanded(
flex: 2, flex: 2,
@ -44,7 +48,6 @@ class SpaceDetailsDialog extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Text(context.watch<SpaceDetailsModelBloc>().state.toString()),
SpaceNameTextField( SpaceNameTextField(
initialValue: space.spaceName, initialValue: space.spaceName,
isNameFieldExist: (value) { isNameFieldExist: (value) {
@ -74,5 +77,7 @@ class SpaceDetailsDialog extends StatelessWidget {
), ),
], ],
); );
}),
);
} }
} }

View File

@ -1,6 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_icon_selection_dialog.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_icon_selection_dialog.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/update_space/presentation/bloc/space_details_model_bloc/space_details_model_bloc.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';
@ -39,10 +41,22 @@ class SpaceIconPicker extends StatelessWidget {
top: 20, top: 20,
right: 20, right: 20,
child: InkWell( child: InkWell(
onTap: () => showDialog<void>( onTap: () {
showDialog<String?>(
context: context, context: context,
builder: (context) => const SpaceIconSelectionDialog(), builder: (context) => SpaceIconSelectionDialog(
selectedIcon: iconPath,
), ),
).then((value) {
if (value != null) {
if (context.mounted) {
context.read<SpaceDetailsModelBloc>().add(
UpdateSpaceDetailsIcon(value),
);
}
}
});
},
child: Container( child: Container(
width: 24, width: 24,
height: 24, height: 24,

View File

@ -5,7 +5,8 @@ import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';
class SpaceIconSelectionDialog extends StatelessWidget { class SpaceIconSelectionDialog extends StatelessWidget {
const SpaceIconSelectionDialog({super.key}); const SpaceIconSelectionDialog({super.key, required this.selectedIcon});
final String selectedIcon;
static const List<String> _icons = [ static const List<String> _icons = [
Assets.location, Assets.location,
@ -47,14 +48,26 @@ class SpaceIconSelectionDialog extends StatelessWidget {
mainAxisSpacing: 16, mainAxisSpacing: 16,
), ),
itemCount: _icons.length, itemCount: _icons.length,
itemBuilder: (context, index) => IconButton( itemBuilder: (context, index) {
onPressed: Navigator.of(context).pop, final isSelected = selectedIcon == _icons[index];
return Container(
padding: const EdgeInsetsDirectional.all(2),
decoration: BoxDecoration(
shape: BoxShape.circle,
border: isSelected
? Border.all(color: ColorsManager.vividBlue, width: 2)
: null,
),
child: IconButton(
onPressed: () => Navigator.of(context).pop(_icons[index]),
icon: SvgPicture.asset( icon: SvgPicture.asset(
_icons[index], _icons[index],
width: context.screenWidth * 0.03, width: context.screenWidth * 0.03,
height: context.screenHeight * 0.08, height: context.screenHeight * 0.08,
), ),
), ),
);
},
), ),
), ),
); );

View File

@ -30,7 +30,6 @@ class SpaceSubSpacesBox extends StatelessWidget {
child: const ButtonContentWidget( child: const ButtonContentWidget(
svgAssets: Assets.addIcon, svgAssets: Assets.addIcon,
label: 'Create Sub Spaces', label: 'Create Sub Spaces',
// disabled: widget.isTagsAndSubspaceModelDisabled,
disabled: false, disabled: false,
), ),
) )
@ -55,7 +54,10 @@ class SpaceSubSpacesBox extends StatelessWidget {
(e) => SubspaceNameDisplayWidget(subSpace: e), (e) => SubspaceNameDisplayWidget(subSpace: e),
), ),
EditChip( EditChip(
onTap: () {}, onTap: () => showDialog<void>(
context: context,
builder: (_) => const SpaceSubSpacesDialog(subspaces: []),
),
), ),
], ],
), ),

View File

@ -5,7 +5,9 @@ import 'package:syncrow_web/pages/space_management_v2/modules/space_details/doma
part 'space_details_model_event.dart'; part 'space_details_model_event.dart';
class SpaceDetailsModelBloc extends Bloc<SpaceDetailsModelEvent, SpaceDetailsModel> { class SpaceDetailsModelBloc extends Bloc<SpaceDetailsModelEvent, SpaceDetailsModel> {
SpaceDetailsModelBloc() : super(SpaceDetailsModel.empty()) { SpaceDetailsModelBloc({
required SpaceDetailsModel initialState,
}) : super(initialState) {
on<UpdateSpaceDetailsIcon>(_onUpdateSpaceDetailsIcon); on<UpdateSpaceDetailsIcon>(_onUpdateSpaceDetailsIcon);
on<UpdateSpaceDetailsName>(_onUpdateSpaceDetailsName); on<UpdateSpaceDetailsName>(_onUpdateSpaceDetailsName);
on<UpdateSpaceDetailsSubspaces>(_onUpdateSpaceDetailsSubspaces); on<UpdateSpaceDetailsSubspaces>(_onUpdateSpaceDetailsSubspaces);