From ca44f3bf55234adb0f0ed0b0acdf01961286972b Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 7 Apr 2025 12:53:12 +0300 Subject: [PATCH 1/4] fix routine popup --- .../create_routine_bloc.dart | 20 +- .../create_routine_event.dart | 8 + .../create_routine_state.dart | 7 + .../create_new_routines/commu_dropdown.dart | 224 +++++++-------- .../create_new_routines.dart | 265 ++++++++++-------- lib/pages/routines/widgets/if_container.dart | 2 - 6 files changed, 290 insertions(+), 236 deletions(-) diff --git a/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart b/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart index 5a8e5590..b472d034 100644 --- a/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart +++ b/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart @@ -2,6 +2,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_event.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_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/space_model.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; @@ -10,11 +11,12 @@ class CreateRoutineBloc extends Bloc { on(_fetchSpaceOnlyWithDevices); on(saveSpaceIdCommunityId); on(resetSelected); + on(_fetchCommunity); } String selectedSpaceId = ''; String selectedCommunityId = ''; - + List communities = []; List spacesOnlyWithDevices = []; Future _fetchSpaceOnlyWithDevices( @@ -30,7 +32,7 @@ class CreateRoutineBloc extends Bloc { emit(SpaceWithDeviceLoadedState(spacesOnlyWithDevices)); } catch (e) { - emit(SpaceTreeErrorState('Error loading communities and spaces: $e')); + emit(SpaceTreeErrorState('Error loading spaces: $e')); } } @@ -48,4 +50,18 @@ class CreateRoutineBloc extends Bloc { selectedCommunityId = ''; emit(const ResetSelectedState()); } + + Future _fetchCommunity( + FetchCommunityEvent event, Emitter emit) async { + emit(const CommunitiesLoadingState()); + + try { + final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + communities = + await CommunitySpaceManagementApi().fetchCommunities(projectUuid); + emit(const CommunityLoadedState()); + } catch (e) { + emit(SpaceTreeErrorState('Error loading communities $e')); + } + } } diff --git a/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart b/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart index 24e620c0..ba901497 100644 --- a/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart +++ b/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart @@ -41,3 +41,11 @@ class ResetSelectedEvent extends CreateRoutineEvent { @override List get props => []; } + + +class FetchCommunityEvent extends CreateRoutineEvent { + const FetchCommunityEvent(); + + @override + List get props => []; +} \ No newline at end of file diff --git a/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart b/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart index 4911304b..5ebc20f7 100644 --- a/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart +++ b/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart @@ -44,3 +44,10 @@ class ResetSelectedState extends CreateRoutineState { const ResetSelectedState(); } +class CommunityLoadedState extends CreateRoutineState { + const CommunityLoadedState(); +} + +class CommunitiesLoadingState extends CreateRoutineState { + const CommunitiesLoadingState(); +} \ No newline at end of file diff --git a/lib/pages/routines/create_new_routines/commu_dropdown.dart b/lib/pages/routines/create_new_routines/commu_dropdown.dart index 32ee7219..5b96e977 100644 --- a/lib/pages/routines/create_new_routines/commu_dropdown.dart +++ b/lib/pages/routines/create_new_routines/commu_dropdown.dart @@ -1,12 +1,11 @@ import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -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/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class CommunityDropdown extends StatelessWidget { final String? selectedValue; + final List communities; final Function(String?) onChanged; final TextEditingController _searchController = TextEditingController(); @@ -14,6 +13,7 @@ class CommunityDropdown extends StatelessWidget { Key? key, required this.selectedValue, required this.onChanged, + required this.communities, }) : super(key: key); @override @@ -32,123 +32,123 @@ class CommunityDropdown extends StatelessWidget { ), ), const SizedBox(height: 8), - BlocBuilder( - builder: (context, state) { - return SizedBox( - child: Container( + SizedBox( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + ), + child: DropdownButton2( + underline: const SizedBox(), + value: selectedValue, + items: communities.map((community) { + return DropdownMenuItem( + value: community.uuid, + child: Text( + ' ${community.name}', + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ); + }).toList(), + onChanged: onChanged, + style: const TextStyle(color: Colors.black), + hint: Padding( + padding: const EdgeInsets.only(left: 10), + child: Text( + " Please Select", + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.textGray, + ), + ), + ), + customButton: Container( + height: 45, + decoration: BoxDecoration( + border: Border.all(color: ColorsManager.textGray, width: 1.0), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 5, + child: Text( + selectedValue != null + ? " ${communities.firstWhere((element) => element.uuid == selectedValue).name}" + : ' Please Select', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: selectedValue != null + ? Colors.black + : ColorsManager.textGray, + ), + overflow: TextOverflow.ellipsis, + ), + ), + Expanded( + child: Container( + decoration: BoxDecoration( + color: Colors.grey[100], + borderRadius: const BorderRadius.only( + topRight: Radius.circular(10), + bottomRight: Radius.circular(10), + ), + ), + height: 45, + child: const Icon( + Icons.keyboard_arrow_down, + color: ColorsManager.textGray, + ), + ), + ), + ], + ), + ), + dropdownStyleData: DropdownStyleData( + maxHeight: MediaQuery.of(context).size.height * 0.4, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), ), - child: DropdownButton2( - underline: SizedBox(), - value: selectedValue, - items: state.communityList.map((community) { - return DropdownMenuItem( - value: community.uuid, - child: Text( - ' ${community.name}', - overflow: TextOverflow.ellipsis, - maxLines: 1, + ), + dropdownSearchData: DropdownSearchData( + searchController: _searchController, + searchInnerWidgetHeight: 50, + searchInnerWidget: Container( + height: 50, + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + child: TextFormField( + style: const TextStyle(color: Colors.black), + controller: _searchController, + decoration: InputDecoration( + isDense: true, + contentPadding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 12, ), - ); - }).toList(), - onChanged: onChanged, - style: TextStyle(color: Colors.black), - hint: Padding( - padding: EdgeInsets.only(left: 10), - child: Text( - " Please Select", - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.textGray, - ), - ), - ), - customButton: Container( - height: 45, - decoration: BoxDecoration( - border: Border.all(color: ColorsManager.textGray, width: 1.0), - borderRadius: BorderRadius.circular(10), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 5, - child: Text( - selectedValue != null - ? " ${state.communityList.firstWhere((element) => element.uuid == selectedValue).name}" - : ' Please Select', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: - selectedValue != null ? Colors.black : ColorsManager.textGray, - ), - overflow: TextOverflow.ellipsis, - ), - ), - Expanded( - child: Container( - decoration: BoxDecoration( - color: Colors.grey[100], - borderRadius: const BorderRadius.only( - topRight: Radius.circular(10), - bottomRight: Radius.circular(10), - ), - ), - height: 45, - child: const Icon( - Icons.keyboard_arrow_down, - color: ColorsManager.textGray, - ), - ), - ), - ], - ), - ), - dropdownStyleData: DropdownStyleData( - maxHeight: MediaQuery.of(context).size.height * 0.4, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - ), - ), - dropdownSearchData: DropdownSearchData( - searchController: _searchController, - searchInnerWidgetHeight: 50, - searchInnerWidget: Container( - height: 50, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - child: TextFormField( - style: const TextStyle(color: Colors.black), - controller: _searchController, - decoration: InputDecoration( - isDense: true, - contentPadding: const EdgeInsets.symmetric( - horizontal: 10, - vertical: 12, - ), - hintText: 'Search for community...', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - ), - ), + hintText: 'Search for community...', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), ), ), - searchMatchFn: (item, searchValue) { - final communityName = (item.child as Text).data?.toLowerCase() ?? ''; - return communityName.contains(searchValue.toLowerCase().trim()); - }, - ), - onMenuStateChange: (isOpen) { - if (!isOpen) { - _searchController.clear(); - } - }, - menuItemStyleData: const MenuItemStyleData( - height: 40, ), ), - )); - }, - ), + searchMatchFn: (item, searchValue) { + final communityName = + (item.child as Text).data?.toLowerCase() ?? ''; + return communityName + .contains(searchValue.toLowerCase().trim()); + }, + ), + onMenuStateChange: (isOpen) { + if (!isOpen) { + _searchController.clear(); + } + }, + menuItemStyleData: const MenuItemStyleData( + height: 40, + ), + ), + )) ], ), ); diff --git a/lib/pages/routines/create_new_routines/create_new_routines.dart b/lib/pages/routines/create_new_routines/create_new_routines.dart index baf10748..4900af9b 100644 --- a/lib/pages/routines/create_new_routines/create_new_routines.dart +++ b/lib/pages/routines/create_new_routines/create_new_routines.dart @@ -5,11 +5,10 @@ import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routi import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart'; import 'package:syncrow_web/pages/routines/create_new_routines/commu_dropdown.dart'; import 'package:syncrow_web/pages/routines/create_new_routines/space_dropdown.dart'; - import 'package:syncrow_web/utils/color_manager.dart'; class CreateNewRoutinesDialog extends StatefulWidget { - const CreateNewRoutinesDialog({Key? key}) : super(key: key); + const CreateNewRoutinesDialog({super.key}); @override State createState() => @@ -19,136 +18,162 @@ class CreateNewRoutinesDialog extends StatefulWidget { class _CreateNewRoutinesDialogState extends State { String? _selectedCommunity; String? _selectedSpace; - void _fetchSpaces(String communityId) { - context - .read() - .add(SpaceOnlyWithDevicesEvent(communityId)); - } @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - final spaces = _bloc.spacesOnlyWithDevices; - final isLoading = state is SpaceWithDeviceLoadingState; + return BlocProvider( + create: (BuildContext context) => + CreateRoutineBloc()..add(const FetchCommunityEvent()), + child: BlocBuilder( + builder: (context, state) { + final _bloc = BlocProvider.of(context); + final spaces = _bloc.spacesOnlyWithDevices; + final isLoadingCommunities = state is CommunitiesLoadingState; + final isLoadingSpaces = state is SpaceWithDeviceLoadingState; + String spaceHint = 'Select a community first'; + if (_selectedCommunity != null) { + if (isLoadingSpaces) { + spaceHint = 'Loading spaces...'; + } else if (spaces.isEmpty) { + spaceHint = 'No spaces available'; + } else { + spaceHint = 'Select Space'; + } + } - String spaceHint = 'Select a community first'; - - if (_selectedCommunity != null) { - if (isLoading) { - spaceHint = 'Loading spaces...'; - } else if (spaces.isEmpty) { - spaceHint = 'No spaces available'; - } else { - spaceHint = 'Select Space'; - } - } - - return AlertDialog( - backgroundColor: Colors.white, - insetPadding: EdgeInsets.zero, - contentPadding: EdgeInsets.zero, - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), - title: Text( - 'Create New Routines', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: ColorsManager.primaryColor, - ), - ), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Divider(), - Padding( - padding: const EdgeInsets.only(left: 15, right: 15), - child: CommunityDropdown( - selectedValue: _selectedCommunity, - onChanged: (String? newValue) { - setState(() { - _selectedCommunity = newValue; - _selectedSpace = null; - }); - if (newValue != null) { - _fetchSpaces(newValue); - } - }, - ), + return AlertDialog( + backgroundColor: Colors.white, + insetPadding: EdgeInsets.zero, + contentPadding: EdgeInsets.zero, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12)), + title: Text( + 'Create New Routines', + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: ColorsManager.primaryColor, + ), ), - const SizedBox(height: 5), - Padding( - padding: const EdgeInsets.only(left: 15, right: 15), - child: SpaceDropdown( - hintMessage: spaceHint, - spaces: spaces, - selectedValue: _selectedSpace, - onChanged: (String? newValue) { - setState(() { - _selectedSpace = newValue; - }); - }, - ), - ), - const Divider(), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, + content: Stack( children: [ - Padding( - padding: const EdgeInsets.only( - left: 20, - right: 20, - ), - child: TextButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: Text( - 'Cancel', - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w400, - fontSize: 14, - color: ColorsManager.blackColor, - ), + Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Divider(), + Padding( + padding: const EdgeInsets.only(left: 15, right: 15), + child: CommunityDropdown( + communities: _bloc.communities, + selectedValue: _selectedCommunity, + onChanged: (String? newValue) { + setState(() { + _selectedCommunity = newValue; + _selectedSpace = null; + }); + if (newValue != null) { + _bloc.add(SpaceOnlyWithDevicesEvent(newValue)); + } + }, + ), ), - ), - ), - Padding( - padding: const EdgeInsets.only( - left: 20, - right: 20, - ), - child: TextButton( - onPressed: - _selectedCommunity != null && _selectedSpace != null - ? () { - Navigator.of(context).pop({ - 'community': _selectedCommunity, - 'space': _selectedSpace, - }); - } - : null, - child: Text( - 'Next', - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w400, - fontSize: 14, - color: _selectedCommunity != null && + const SizedBox(height: 5), + Padding( + padding: const EdgeInsets.only(left: 15, right: 15), + child: SpaceDropdown( + hintMessage: spaceHint, + spaces: spaces, + selectedValue: _selectedSpace, + onChanged: (String? newValue) { + setState(() { + _selectedSpace = newValue; + }); + }, + ), + ), + const Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 20, + right: 20, + ), + child: TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text( + 'Cancel', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith( + fontWeight: FontWeight.w400, + fontSize: 14, + color: ColorsManager.blackColor, + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 20, + right: 20, + ), + child: TextButton( + onPressed: _selectedCommunity != null && _selectedSpace != null - ? ColorsManager.blueColor - : Colors.blue.shade100, + ? () { + Navigator.of(context).pop({ + 'community': _selectedCommunity, + 'space': _selectedSpace, + }); + } + : null, + child: Text( + 'Next', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith( + fontWeight: FontWeight.w400, + fontSize: 14, + color: _selectedCommunity != null && + _selectedSpace != null + ? ColorsManager.blueColor + : Colors.blue.shade100, + ), + ), ), + ), + ], + ), + const SizedBox(height: 10), + ], + ), + if (isLoadingCommunities) + const SizedBox( + height: 200, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Center( + child: Center( + child: CircularProgressIndicator( + color: ColorsManager.primaryColor, + ), + ), + ), + ], ), ), - ), ], ), - SizedBox(height: 10), - ], - ), - ); - }, - ); + ); + }, + )); } } diff --git a/lib/pages/routines/widgets/if_container.dart b/lib/pages/routines/widgets/if_container.dart index d6078143..eebf3fb7 100644 --- a/lib/pages/routines/widgets/if_container.dart +++ b/lib/pages/routines/widgets/if_container.dart @@ -105,9 +105,7 @@ class IfContainer extends StatelessWidget { ); }, onAcceptWithDetails: (data) async { - print('data.data=${data.data}'); final uniqueCustomId = const Uuid().v4(); - final mutableData = Map.from(data.data); mutableData['uniqueCustomId'] = uniqueCustomId; From d264409d29ad786a0062d466ec255b138dbc057d Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 7 Apr 2025 14:27:36 +0300 Subject: [PATCH 2/4] - Refactor the WpsFunctions class in wps_functions.dart to use 'cm' instead of 'temp' for the description of operational values. - Update the WallPresenceSensor class in wall_presence_sensor.dart to use the selected operation name --- lib/pages/routines/models/wps/wps_functions.dart | 7 ++++--- .../wall_sensor/wall_presence_sensor.dart | 10 +++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/lib/pages/routines/models/wps/wps_functions.dart b/lib/pages/routines/models/wps/wps_functions.dart index 4f48300e..8907927c 100644 --- a/lib/pages/routines/models/wps/wps_functions.dart +++ b/lib/pages/routines/models/wps/wps_functions.dart @@ -244,11 +244,12 @@ class CurrentDistanceFunction extends WpsFunctions { @override List getOperationalValues() { List values = []; - for (int temp = min; temp <= max; temp += step) { + for (int cm = min; cm <= max; cm += step) { values.add(WpsOperationalValue( icon: Assets.assetsTempreture, - description: "${temp}CM", - value: temp, + description: "${cm}CM", + + value: cm, )); } return values; diff --git a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart index ee91b321..e065080f 100644 --- a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart +++ b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart @@ -13,7 +13,6 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart'; - class WallPresenceSensor extends StatefulWidget { final List functions; final AllDevicesModel? device; @@ -171,7 +170,7 @@ class _WallPresenceSensorState extends State { orElse: () => DeviceFunctionData( entityId: '', functionCode: selectedFunction, - operationName: '', + operationName: state.selectedOperationName!, value: null, ), ); @@ -251,11 +250,8 @@ class _ValueSelector extends StatelessWidget { ); } - bool _isSliderFunction(String function) => [ - 'dis_current', - 'presence_time', - 'illuminance_value' - ].contains(function); + bool _isSliderFunction(String function) => + ['dis_current', 'presence_time', 'illuminance_value'].contains(function); } class _SliderValueSelector extends StatelessWidget { From 6bd9fb7e4e28f6a0ff697cec20d5751bd4094f10 Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 7 Apr 2025 16:22:21 +0300 Subject: [PATCH 3/4] Refactor routine_view_card.dart to adjust the size o --- .../fetch_routine_scenes_automation.dart | 312 ++++++++++-------- .../main_routine_view/routine_view_card.dart | 2 + 2 files changed, 168 insertions(+), 146 deletions(-) diff --git a/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart b/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart index 99c131ee..0a22208c 100644 --- a/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart +++ b/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart @@ -31,165 +31,185 @@ class _FetchRoutineScenesState extends State ? const Center( child: CircularProgressIndicator(), ) - : Padding( - padding: const EdgeInsets.symmetric(vertical: 16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Scenes (Tab to Run)", - style: Theme.of(context).textTheme.titleLarge?.copyWith( - color: ColorsManager.grayColor, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 10), - if (state.scenes.isEmpty) - Expanded( - child: Text( + : SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Scenes (Tab to Run)", + style: Theme.of(context).textTheme.titleLarge?.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 10), + if (state.scenes.isEmpty) + Text( "No scenes found", style: context.textTheme.bodyMedium?.copyWith( color: ColorsManager.grayColor, ), ), - ), - if (state.scenes.isNotEmpty) - ConstrainedBox( - constraints: BoxConstraints( - maxHeight: isSmallScreenSize(context) ? 190 : 200, - maxWidth: MediaQuery.sizeOf(context).width * 0.8), - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: state.scenes.length, - itemBuilder: (context, index) { - final scene = state.scenes[index]; - final isLoading = - state.loadingSceneId == scene.id; + if (state.scenes.isNotEmpty) + SizedBox( + height: 200, + child: ListView.builder( + shrinkWrap: true, + scrollDirection: Axis.horizontal, + itemCount: state.scenes.length, + itemBuilder: (context, index) { + final scene = state.scenes[index]; + final isLoading = + state.loadingSceneId == scene.id; - return Padding( - padding: EdgeInsets.only( - right: isSmallScreenSize(context) ? 4.0 : 8.0, - ), - child: RoutineViewCard( - isLoading: isLoading, - sceneOnTap: () { - context.read().add( - SceneTrigger( - sceneId: scene.id, - name: scene.name)); - }, - status: state.scenes[index].status, - communityId: - state.scenes[index].communityId ?? '', - spaceId: state.scenes[index].spaceId, - sceneId: state.scenes[index].sceneTuyaId!, - automationId: state.scenes[index].id, - cardType: 'scenes', - spaceName: state.scenes[index].spaceName, - onTap: () { - BlocProvider.of(context).add( - const CreateNewRoutineViewEvent( - createRoutineView: true), - ); - context.read().add( - GetSceneDetails( - sceneId: state.scenes[index].id, - isTabToRun: true, - isUpdate: true, - ), - ); - }, - textString: state.scenes[index].name, - icon: state.scenes[index].icon ?? - Assets.logoHorizontal, - isFromScenes: true, - iconInBytes: state.scenes[index].iconInBytes, - ), - ); - }), + return Padding( + padding: EdgeInsets.only( + right: + isSmallScreenSize(context) ? 4.0 : 8.0, + ), + child: Column( + children: [ + RoutineViewCard( + isLoading: isLoading, + sceneOnTap: () { + context.read().add( + SceneTrigger( + sceneId: scene.id, + name: scene.name)); + }, + status: state.scenes[index].status, + communityId: + state.scenes[index].communityId ?? + '', + spaceId: state.scenes[index].spaceId, + sceneId: + state.scenes[index].sceneTuyaId!, + automationId: state.scenes[index].id, + cardType: 'scenes', + spaceName: + state.scenes[index].spaceName, + onTap: () { + BlocProvider.of(context) + .add( + const CreateNewRoutineViewEvent( + createRoutineView: true), + ); + context.read().add( + GetSceneDetails( + sceneId: + state.scenes[index].id, + isTabToRun: true, + isUpdate: true, + ), + ); + }, + textString: state.scenes[index].name, + icon: state.scenes[index].icon ?? + Assets.logoHorizontal, + isFromScenes: true, + iconInBytes: + state.scenes[index].iconInBytes, + ), + ], + ), + ); + }), + ), + const SizedBox(height: 10), + Text( + "Automations", + style: Theme.of(context).textTheme.titleLarge?.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.bold, + ), ), - const SizedBox(height: 10), - Text( - "Automations", - style: Theme.of(context).textTheme.titleLarge?.copyWith( - color: ColorsManager.grayColor, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 3), - if (state.automations.isEmpty) - Expanded( - child: Text( + const SizedBox(height: 3), + if (state.automations.isEmpty) + Text( "No automations found", style: context.textTheme.bodyMedium?.copyWith( color: ColorsManager.grayColor, ), ), - ), - if (state.automations.isNotEmpty) - ConstrainedBox( - constraints: BoxConstraints( - maxHeight: isSmallScreenSize(context) ? 190 : 195, - ), - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: state.automations.length, - itemBuilder: (context, index) { - final isLoading = state.automations! - .contains(state.automations[index].id); + if (state.automations.isNotEmpty) + SizedBox( + height: 200, - return Padding( - padding: EdgeInsets.only( - right: isSmallScreenSize(context) ? 4.0 : 8.0, - ), - child: RoutineViewCard( - isLoading: isLoading, - onChanged: (v) { - // BlocProvider.of(context) - context.read().add( - UpdateAutomationStatus( - automationId: - state.automations[index].id, - automationStatusUpdate: - AutomationStatusUpdate( - spaceUuid: state - .automations[index] - .spaceId, - isEnable: v), - communityId: state - .automations[index].communityId, - ), - ); - }, - status: state.automations[index].status, - communityId: '', - spaceId: state.automations[index].spaceId, - sceneId: '', - automationId: state.automations[index].id, - cardType: 'automations', - spaceName: state.scenes[index].spaceName, - onTap: () { - BlocProvider.of(context).add( - const CreateNewRoutineViewEvent( - createRoutineView: true), - ); - context.read().add( - GetAutomationDetails( - automationId: - state.automations[index].id, - isAutomation: true, - isUpdate: true), - ); - }, - textString: state.automations[index].name, - icon: state.automations[index].icon ?? - Assets.automation, - ), - ); - }), - ), - ], + child: ListView.builder( + shrinkWrap: true, + scrollDirection: Axis.horizontal, + itemCount: state.automations.length, + itemBuilder: (context, index) { + final isLoading = state.automations! + .contains(state.automations[index].id); + + return Column( + children: [ + Padding( + padding: EdgeInsets.only( + right: isSmallScreenSize(context) + ? 4.0 + : 8.0, + ), + child: RoutineViewCard( + isLoading: isLoading, + onChanged: (v) { + context.read().add( + UpdateAutomationStatus( + automationId: state + .automations[index].id, + automationStatusUpdate: + AutomationStatusUpdate( + spaceUuid: state + .automations[ + index] + .spaceId, + isEnable: v), + communityId: state + .automations[index] + .communityId, + ), + ); + }, + status: state.automations[index].status, + communityId: '', + spaceId: + state.automations[index].spaceId, + sceneId: '', + automationId: + state.automations[index].id, + cardType: 'automations', + spaceName: + state.scenes[index].spaceName, + onTap: () { + BlocProvider.of(context) + .add( + const CreateNewRoutineViewEvent( + createRoutineView: true), + ); + context.read().add( + GetAutomationDetails( + automationId: state + .automations[index].id, + isAutomation: true, + isUpdate: true), + ); + }, + textString: + state.automations[index].name, + icon: state.automations[index].icon ?? + Assets.automation, + ), + ), + ], + ); + }), + ), + ], + ), ), ); }, diff --git a/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart b/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart index 5f471973..841ffa6e 100644 --- a/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart +++ b/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart @@ -177,6 +177,8 @@ class _RoutineViewCardState extends State { : (widget.icon is String && widget.icon.endsWith('.svg')) ? SvgPicture.asset( + height: iconSize, + width: iconSize, widget.icon, fit: BoxFit.contain, ) From a56f4e488e8da0039e0359c9d853de5b7fccdb0e Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 7 Apr 2025 16:42:44 +0300 Subject: [PATCH 4/4] Refactor routine_view_card.dart to adjust the size of the CircularProgressIndicator Fix routine popup Update wall_presence_sensor.dart to handle null selectedOperationName --- .../routines/create_new_routines/create_new_routines.dart | 6 ++---- .../routine_dialogs/wall_sensor/wall_presence_sensor.dart | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/pages/routines/create_new_routines/create_new_routines.dart b/lib/pages/routines/create_new_routines/create_new_routines.dart index 4900af9b..0542f888 100644 --- a/lib/pages/routines/create_new_routines/create_new_routines.dart +++ b/lib/pages/routines/create_new_routines/create_new_routines.dart @@ -161,10 +161,8 @@ class _CreateNewRoutinesDialogState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ Center( - child: Center( - child: CircularProgressIndicator( - color: ColorsManager.primaryColor, - ), + child: CircularProgressIndicator( + color: ColorsManager.primaryColor, ), ), ], diff --git a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart index e065080f..b7733511 100644 --- a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart +++ b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart @@ -170,7 +170,7 @@ class _WallPresenceSensorState extends State { orElse: () => DeviceFunctionData( entityId: '', functionCode: selectedFunction, - operationName: state.selectedOperationName!, + operationName: state.selectedOperationName ?? '', value: null, ), );