diff --git a/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart b/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart index 841027b3..4e69b7db 100644 --- a/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart +++ b/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart @@ -45,8 +45,8 @@ class RoutineBloc extends Bloc { final updatedIfItems = List>.from(state.ifItems); // Find the index of the item in teh current itemsList - int index = updatedIfItems.indexWhere( - (map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); + int index = + updatedIfItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); // Replace the map if the index is valid if (index != -1) { updatedIfItems[index] = event.item; @@ -55,21 +55,18 @@ class RoutineBloc extends Bloc { } if (event.isTabToRun) { - emit(state.copyWith( - ifItems: updatedIfItems, isTabToRun: true, isAutomation: false)); + emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: true, isAutomation: false)); } else { - emit(state.copyWith( - ifItems: updatedIfItems, isTabToRun: false, isAutomation: true)); + emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: false, isAutomation: true)); } } - void _onAddToThenContainer( - AddToThenContainer event, Emitter emit) { + void _onAddToThenContainer(AddToThenContainer event, Emitter emit) { final currentItems = List>.from(state.thenItems); // Find the index of the item in teh current itemsList - int index = currentItems.indexWhere( - (map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); + int index = + currentItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); // Replace the map if the index is valid if (index != -1) { currentItems[index] = event.item; @@ -80,26 +77,22 @@ class RoutineBloc extends Bloc { emit(state.copyWith(thenItems: currentItems)); } - void _onAddFunctionsToRoutine( - AddFunctionToRoutine event, Emitter emit) { + void _onAddFunctionsToRoutine(AddFunctionToRoutine event, Emitter emit) { try { if (event.functions.isEmpty) return; - List selectedFunction = - List.from(event.functions); + List selectedFunction = List.from(event.functions); Map> currentSelectedFunctions = Map>.from(state.selectedFunctions); if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) { List currentFunctions = - List.from( - currentSelectedFunctions[event.uniqueCustomId] ?? []); + List.from(currentSelectedFunctions[event.uniqueCustomId] ?? []); List functionCode = []; for (int i = 0; i < selectedFunction.length; i++) { for (int j = 0; j < currentFunctions.length; j++) { - if (selectedFunction[i].functionCode == - currentFunctions[j].functionCode) { + if (selectedFunction[i].functionCode == currentFunctions[j].functionCode) { currentFunctions[j] = selectedFunction[i]; if (!functionCode.contains(currentFunctions[j].functionCode)) { functionCode.add(currentFunctions[j].functionCode); @@ -109,15 +102,13 @@ class RoutineBloc extends Bloc { } for (int i = 0; i < functionCode.length; i++) { - selectedFunction - .removeWhere((code) => code.functionCode == functionCode[i]); + selectedFunction.removeWhere((code) => code.functionCode == functionCode[i]); } - currentSelectedFunctions[event.uniqueCustomId] = - List.from(currentFunctions)..addAll(selectedFunction); + currentSelectedFunctions[event.uniqueCustomId] = List.from(currentFunctions) + ..addAll(selectedFunction); } else { - currentSelectedFunctions[event.uniqueCustomId] = - List.from(event.functions); + currentSelectedFunctions[event.uniqueCustomId] = List.from(event.functions); } emit(state.copyWith(selectedFunctions: currentSelectedFunctions)); @@ -126,13 +117,11 @@ class RoutineBloc extends Bloc { } } - Future _onLoadScenes( - LoadScenes event, Emitter emit) async { + Future _onLoadScenes(LoadScenes event, Emitter emit) async { emit(state.copyWith(isLoading: true, errorMessage: null)); try { - final scenes = - await SceneApi.getScenesByUnitId(event.unitId, event.communityId); + final scenes = await SceneApi.getScenesByUnitId(event.unitId, event.communityId); emit(state.copyWith( scenes: scenes, isLoading: false, @@ -147,8 +136,7 @@ class RoutineBloc extends Bloc { } } - Future _onLoadAutomation( - LoadAutomation event, Emitter emit) async { + Future _onLoadAutomation(LoadAutomation event, Emitter emit) async { emit(state.copyWith(isLoading: true, errorMessage: null)); try { @@ -176,16 +164,14 @@ class RoutineBloc extends Bloc { } } - FutureOr _onSearchRoutines( - SearchRoutines event, Emitter emit) async { + FutureOr _onSearchRoutines(SearchRoutines event, Emitter emit) async { emit(state.copyWith(isLoading: true, errorMessage: null)); await Future.delayed(const Duration(seconds: 1)); emit(state.copyWith(isLoading: false, errorMessage: null)); emit(state.copyWith(searchText: event.query)); } - FutureOr _onAddSelectedIcon( - AddSelectedIcon event, Emitter emit) { + FutureOr _onAddSelectedIcon(AddSelectedIcon event, Emitter emit) { emit(state.copyWith(selectedIcon: event.icon)); } @@ -194,8 +180,12 @@ class RoutineBloc extends Bloc { return actions.first['deviceId'] == 'delay'; } - Future _onCreateScene( - CreateSceneEvent event, Emitter emit) async { + bool _isLastActionDelay(List> actions) { + if (actions.isEmpty) return false; + return actions.last['deviceId'] == 'delay'; + } + + Future _onCreateScene(CreateSceneEvent event, Emitter emit) async { try { // Check if first action is delay if (_isFirstActionDelay(state.thenItems)) { @@ -206,6 +196,14 @@ class RoutineBloc extends Bloc { return; } + if (_isLastActionDelay(state.thenItems)) { + emit(state.copyWith( + errorMessage: 'Cannot have delay as the last action', + isLoading: false, + )); + return; + } + emit(state.copyWith(isLoading: true)); final actions = state.thenItems.expand((item) { @@ -256,6 +254,7 @@ class RoutineBloc extends Bloc { if (result['success']) { emit(_resetState()); add(const LoadScenes(spaceId, communityId)); + add(const LoadAutomation(spaceId)); } else { emit(state.copyWith( isLoading: false, @@ -270,8 +269,7 @@ class RoutineBloc extends Bloc { } } - Future _onCreateAutomation( - CreateAutomationEvent event, Emitter emit) async { + Future _onCreateAutomation(CreateAutomationEvent event, Emitter emit) async { try { if (state.routineName == null || state.routineName!.isEmpty) { emit(state.copyWith( @@ -357,6 +355,7 @@ class RoutineBloc extends Bloc { if (result['success']) { emit(_resetState()); add(const LoadAutomation(spaceId)); + add(const LoadScenes(spaceId, communityId)); } else { emit(state.copyWith( isLoading: false, @@ -371,21 +370,17 @@ class RoutineBloc extends Bloc { } } - FutureOr _onRemoveDragCard( - RemoveDragCard event, Emitter emit) { + FutureOr _onRemoveDragCard(RemoveDragCard event, Emitter emit) { if (event.isFromThen) { final thenItems = List>.from(state.thenItems); - final selectedFunctions = - Map>.from(state.selectedFunctions); + final selectedFunctions = Map>.from(state.selectedFunctions); thenItems.removeAt(event.index); selectedFunctions.remove(event.key); - emit(state.copyWith( - thenItems: thenItems, selectedFunctions: selectedFunctions)); + emit(state.copyWith(thenItems: thenItems, selectedFunctions: selectedFunctions)); } else { final ifItems = List>.from(state.ifItems); - final selectedFunctions = - Map>.from(state.selectedFunctions); + final selectedFunctions = Map>.from(state.selectedFunctions); ifItems.removeAt(event.index); selectedFunctions.remove(event.key); @@ -396,8 +391,7 @@ class RoutineBloc extends Bloc { isAutomation: false, isTabToRun: false)); } else { - emit(state.copyWith( - ifItems: ifItems, selectedFunctions: selectedFunctions)); + emit(state.copyWith(ifItems: ifItems, selectedFunctions: selectedFunctions)); } } } @@ -409,18 +403,15 @@ class RoutineBloc extends Bloc { )); } - FutureOr _onEffectiveTimeEvent( - EffectiveTimePeriodEvent event, Emitter emit) { + FutureOr _onEffectiveTimeEvent(EffectiveTimePeriodEvent event, Emitter emit) { emit(state.copyWith(effectiveTime: event.effectiveTime)); } - FutureOr _onSetRoutineName( - SetRoutineName event, Emitter emit) { + FutureOr _onSetRoutineName(SetRoutineName event, Emitter emit) { emit(state.copyWith(routineName: event.name)); } - Future _onGetSceneDetails( - GetSceneDetails event, Emitter emit) async { + Future _onGetSceneDetails(GetSceneDetails event, Emitter emit) async { try { emit(state.copyWith( isLoading: true, @@ -448,8 +439,7 @@ class RoutineBloc extends Bloc { isTabToRun: false, isUpdate: true, )); - final automationDetails = - await SceneApi.getAutomationDetails(event.automationId); + final automationDetails = await SceneApi.getAutomationDetails(event.automationId); add(InitializeRoutineState(automationDetails)); } catch (e) { emit(state.copyWith( @@ -558,17 +548,17 @@ class RoutineBloc extends Bloc { ); } - FutureOr _onResetRoutineState( - ResetRoutineState event, Emitter emit) { + FutureOr _onResetRoutineState(ResetRoutineState event, Emitter emit) { emit(_resetState()); } FutureOr _deleteScene(DeleteScene event, Emitter emit) { try { - // emit(state.copyWith(isLoading: true)); + emit(state.copyWith(isLoading: true)); SceneApi.deleteScene(unitUuid: spaceId, sceneId: event.sceneId); add(const LoadScenes(spaceId, communityId)); - //emit(_resetState()); + add(const LoadAutomation(spaceId)); + emit(_resetState()); } catch (e) { emit(state.copyWith( isLoading: false, @@ -577,14 +567,13 @@ class RoutineBloc extends Bloc { } } - FutureOr _deleteAutomation( - DeleteAutomation event, Emitter emit) { + FutureOr _deleteAutomation(DeleteAutomation event, Emitter emit) { try { - //emit(state.copyWith(isLoading: true)); - SceneApi.deleteAutomation( - unitUuid: spaceId, automationId: event.automationId); + emit(state.copyWith(isLoading: true)); + SceneApi.deleteAutomation(unitUuid: spaceId, automationId: event.automationId); add(const LoadAutomation(spaceId)); - // emit(_resetState()); + add(const LoadScenes(spaceId, communityId)); + emit(_resetState()); } catch (e) { emit(state.copyWith( isLoading: false, diff --git a/lib/pages/routiens/widgets/delete_scene.dart b/lib/pages/routiens/widgets/delete_scene.dart new file mode 100644 index 00000000..ee1a7d4b --- /dev/null +++ b/lib/pages/routiens/widgets/delete_scene.dart @@ -0,0 +1,89 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/common/custom_dialog.dart'; +import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; + +class DeleteSceneWidget extends StatelessWidget { + const DeleteSceneWidget({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + const SizedBox( + height: 10, + ), + GestureDetector( + onTap: () async { + showCustomDialog( + context: context, + message: 'Are you sure you want to delete this scene?', + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + Navigator.of(context).pop(); + }, + child: Container( + alignment: AlignmentDirectional.center, + child: Text( + 'Cancel', + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: ColorsManager.textGray, + ), + ), + ), + ), + Container(width: 1, height: 50, color: ColorsManager.greyColor), + InkWell( + onTap: () { + // context.read().add( + // DeleteAutomation(automationId: automationId, unitUuid: unitUuid)); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + }, + child: Container( + alignment: AlignmentDirectional.center, + child: Text( + 'Confirm', + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: ColorsManager.primaryColorWithOpacity, + ), + ), + ), + ), + ], + ), + ]); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon( + Icons.delete, + color: ColorsManager.red, + ), + const SizedBox( + width: 2, + ), + Text( + 'Delete', + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: ColorsManager.red, + ), + ), + ], + ), + ), + const SizedBox( + height: 10, + ), + ], + ); + } +} diff --git a/lib/pages/routiens/widgets/main_routine_view/fetch_routine_scenes_automation.dart b/lib/pages/routiens/widgets/main_routine_view/fetch_routine_scenes_automation.dart index c9a5114f..6f4dfb8f 100644 --- a/lib/pages/routiens/widgets/main_routine_view/fetch_routine_scenes_automation.dart +++ b/lib/pages/routiens/widgets/main_routine_view/fetch_routine_scenes_automation.dart @@ -11,8 +11,7 @@ class FetchRoutineScenesAutomation extends StatefulWidget { const FetchRoutineScenesAutomation({super.key}); @override - State createState() => - _FetchRoutineScenesState(); + State createState() => _FetchRoutineScenesState(); } class _FetchRoutineScenesState extends State @@ -67,49 +66,12 @@ class _FetchRoutineScenesState extends State padding: EdgeInsets.only( right: isSmallScreenSize(context) ? 4.0 : 8.0, ), - child: Stack( - children: [ - RoutineViewCard( - onTap: () {}, - textString: state.scenes[index].name, - icon: state.scenes[index].icon ?? - Assets.logoHorizontal, - isFromScenes: true, - iconInBytes: - state.scenes[index].iconInBytes, - ), - Positioned( - top: 0, - right: 0, - child: InkWell( - onTap: () => context - .read() - .add( - DeleteScene( - sceneId: state.scenes[index].id, - unitUuid: spaceId, - ), - ), - child: Container( - height: 20, - width: 20, - decoration: BoxDecoration( - color: ColorsManager.whiteColors, - shape: BoxShape.circle, - border: Border.all( - color: ColorsManager.grayColor, - width: 2.0, - ), - ), - child: const Center( - child: Icon(Icons.delete, - size: 15, - color: ColorsManager.grayColor), - ), - ), - ), - ), - ], + child: RoutineViewCard( + onTap: () {}, + textString: state.scenes[index].name, + icon: state.scenes[index].icon ?? Assets.logoHorizontal, + isFromScenes: true, + iconInBytes: state.scenes[index].iconInBytes, ), ), ), @@ -142,46 +104,10 @@ class _FetchRoutineScenesState extends State padding: EdgeInsets.only( right: isSmallScreenSize(context) ? 4.0 : 8.0, ), - child: Stack( - children: [ - RoutineViewCard( - onTap: () {}, - textString: state.automations[index].name, - icon: state.automations[index].icon ?? - Assets.automation, - ), - Positioned( - top: 0, - right: 0, - child: InkWell( - onTap: () => - context.read().add( - DeleteAutomation( - automationId: state - .automations[index].id, - unitUuid: spaceId, - ), - ), - child: Container( - height: 20, - width: 20, - decoration: BoxDecoration( - color: ColorsManager.whiteColors, - shape: BoxShape.circle, - border: Border.all( - color: ColorsManager.grayColor, - width: 2.0, - ), - ), - child: const Center( - child: Icon(Icons.delete, - size: 15, - color: ColorsManager.grayColor), - ), - ), - ), - ), - ], + child: RoutineViewCard( + onTap: () {}, + textString: state.automations[index].name, + icon: state.automations[index].icon ?? Assets.automation, ), ), ), diff --git a/lib/pages/routiens/widgets/routine_dialogs/setting_dialog.dart b/lib/pages/routiens/widgets/routine_dialogs/setting_dialog.dart index 7fc723af..495d2e55 100644 --- a/lib/pages/routiens/widgets/routine_dialogs/setting_dialog.dart +++ b/lib/pages/routiens/widgets/routine_dialogs/setting_dialog.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/common/custom_dialog.dart'; import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_bloc.dart'; import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_state.dart'; import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart'; @@ -9,6 +10,7 @@ import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_state.dart' import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_automation_model.dart'; import 'package:syncrow_web/pages/routiens/models/icon_model.dart'; import 'package:syncrow_web/pages/routiens/view/effective_period_view.dart'; +import 'package:syncrow_web/pages/routiens/widgets/delete_scene.dart'; import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:flutter/cupertino.dart'; @@ -44,7 +46,7 @@ class SettingHelper { } return Container( width: context.read().isExpanded ? 800 : 400, - height: context.read().isExpanded && isAutomation ? 500 : 300, + height: context.read().isExpanded && isAutomation ? 500 : 350, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), @@ -167,6 +169,8 @@ class SettingHelper { fontSize: 14)), ], ), + // if (context.read().state.isAutomation) + const DeleteSceneWidget() ], )), ], @@ -284,6 +288,8 @@ class SettingHelper { fontSize: 14)), ], ), + // if (context.read().state.isAutomation) + const DeleteSceneWidget() ], )), ], diff --git a/lib/pages/routiens/widgets/routine_search_and_buttons.dart b/lib/pages/routiens/widgets/routine_search_and_buttons.dart index cdc560f6..e1c567df 100644 --- a/lib/pages/routiens/widgets/routine_search_and_buttons.dart +++ b/lib/pages/routiens/widgets/routine_search_and_buttons.dart @@ -301,7 +301,7 @@ class RoutineSearchAndButtons extends StatelessWidget { width: 200, child: Center( child: DefaultButton( - onPressed: () { + onPressed: () async { if (state.routineName == null || state.routineName!.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( @@ -335,7 +335,15 @@ class RoutineSearchAndButtons extends StatelessWidget { ); return; } - SaveRoutineHelper.showSaveRoutineDialog(context); + final result = await SaveRoutineHelper.showSaveRoutineDialog(context); + if (result != null && result) { + BlocProvider.of(context).add( + const CreateNewRoutineViewEvent(false), + ); + BlocProvider.of(context).add( + const TriggerSwitchTabsEvent(true), + ); + } }, borderRadius: 15, elevation: 0,