diff --git a/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart b/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart index ea7428bd..841027b3 100644 --- a/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart +++ b/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart @@ -9,8 +9,6 @@ import 'package:syncrow_web/pages/routiens/models/device_functions.dart'; import 'package:syncrow_web/pages/routiens/models/routine_details_model.dart'; import 'package:syncrow_web/pages/routiens/models/routine_model.dart'; import 'package:syncrow_web/services/routines_api.dart'; -import 'package:syncrow_web/utils/constants/assets.dart'; -import 'package:uuid/uuid.dart'; part 'routine_event.dart'; part 'routine_state.dart'; @@ -36,7 +34,9 @@ class RoutineBloc extends Bloc { on(_onResetRoutineState); on(_onGetSceneDetails); on(_onGetAutomationDetails); - on(_onInitializeRoutineState); + // on(_onInitializeRoutineState); + on(_deleteScene); + on(_deleteAutomation); // on(_onRemoveFunction); // on(_onClearFunctions); } @@ -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,18 +55,21 @@ 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; @@ -77,22 +80,26 @@ 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); @@ -102,13 +109,15 @@ 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)); @@ -117,11 +126,13 @@ 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, @@ -136,7 +147,8 @@ 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 { @@ -164,14 +176,16 @@ 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)); } @@ -180,7 +194,8 @@ class RoutineBloc extends Bloc { return actions.first['deviceId'] == 'delay'; } - Future _onCreateScene(CreateSceneEvent event, Emitter emit) async { + Future _onCreateScene( + CreateSceneEvent event, Emitter emit) async { try { // Check if first action is delay if (_isFirstActionDelay(state.thenItems)) { @@ -255,7 +270,8 @@ 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( @@ -355,17 +371,21 @@ 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); @@ -376,7 +396,8 @@ class RoutineBloc extends Bloc { isAutomation: false, isTabToRun: false)); } else { - emit(state.copyWith(ifItems: ifItems, selectedFunctions: selectedFunctions)); + emit(state.copyWith( + ifItems: ifItems, selectedFunctions: selectedFunctions)); } } } @@ -388,15 +409,18 @@ 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, @@ -424,7 +448,8 @@ 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( @@ -434,81 +459,83 @@ class RoutineBloc extends Bloc { } } - void _onInitializeRoutineState(InitializeRoutineState event, Emitter emit) { - final routineDetails = event.routineDetails; + // void _onInitializeRoutineState( + // InitializeRoutineState event, Emitter emit) { + // final routineDetails = event.routineDetails; - // Convert actions to draggable cards for the THEN container - final thenItems = routineDetails.actions.map((action) { - final Map cardData = { - 'entityId': action.entityId, - 'uniqueCustomId': const Uuid().v4(), - 'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId, - 'title': action.actionExecutor == 'delay' ? 'Delay' : 'Device', - // fix this - 'imagePath': action.actionExecutor == 'delay' ? Assets.delay : Assets.logo, - }; + // // Convert actions to draggable cards for the THEN container + // final thenItems = routineDetails.actions.map((action) { + // final Map cardData = { + // 'entityId': action.entityId, + // 'uniqueCustomId': const Uuid().v4(), + // 'deviceId': + // action.actionExecutor == 'delay' ? 'delay' : action.entityId, + // 'title': action.actionExecutor == 'delay' ? 'Delay' : 'Device', + // // fix this + // 'imagePath': + // action.actionExecutor == 'delay' ? Assets.delay : Assets.logo, + // }; - // Add functions to selectedFunctions - if (action.executorProperty != null) { - final functions = [ - DeviceFunctionData( - entityId: action.entityId, - functionCode: action.executorProperty!.functionCode ?? '', - value: action.executorProperty!.functionValue, + // // Add functions to selectedFunctions + // if (action.executorProperty != null) { + // final functions = [ + // DeviceFunctionData( + // entityId: action.entityId, + // functionCode: action.executorProperty!.functionCode ?? '', + // value: action.executorProperty!.functionValue, - /// fix this - operationName: action.executorProperty?.functionCode ?? ''), - ]; - state.selectedFunctions[cardData['uniqueCustomId']] = functions; - } + // /// fix this + // operationName: action.executorProperty?.functionCode ?? ''), + // ]; + // state.selectedFunctions[cardData['uniqueCustomId']] = functions; + // } - return cardData; - }).toList() ?? - []; + // return cardData; + // }).toList(); - // Convert conditions to draggable cards for the IF container - final ifItems = routineDetails.conditions?.map((condition) { - final Map cardData = { - 'entityId': condition.entityId, - 'uniqueCustomId': const Uuid().v4(), - 'deviceId': condition.entityId, + // // Convert conditions to draggable cards for the IF container + // final ifItems = routineDetails.conditions?.map((condition) { + // final Map cardData = { + // 'entityId': condition.entityId, + // 'uniqueCustomId': const Uuid().v4(), + // 'deviceId': condition.entityId, - /// fix this - 'title': 'Device', + // /// fix this + // 'title': 'Device', - /// fix this - 'imagePath': Assets.logo, - }; + // /// fix this + // 'imagePath': Assets.logo, + // }; - // Add functions to selectedFunctions - final functions = [ - DeviceFunctionData( - entityId: condition.entityId, - functionCode: condition.expr.statusCode, - value: condition.expr.statusValue, - condition: condition.expr.comparator, - operationName: condition.expr.comparator, - ), - ]; - state.selectedFunctions[cardData['uniqueCustomId']] = functions; + // // Add functions to selectedFunctions + // final functions = [ + // DeviceFunctionData( + // entityId: condition.entityId, + // functionCode: condition.expr.statusCode, + // value: condition.expr.statusValue, + // condition: condition.expr.comparator, + // operationName: condition.expr.comparator, + // ), + // ]; + // state.selectedFunctions[cardData['uniqueCustomId']] = functions; - return cardData; - }).toList() ?? - []; + // return cardData; + // }).toList() ?? + // []; - emit(state.copyWith( - isLoading: false, - routineName: routineDetails.name, - selectedIcon: routineDetails.iconId, - selectedAutomationOperator: routineDetails.decisionExpr, - effectiveTime: routineDetails.effectiveTime, - isAutomation: routineDetails.conditions != null, - isTabToRun: routineDetails.conditions == null, - thenItems: thenItems, - ifItems: ifItems, - selectedFunctions: Map.from(state.selectedFunctions), - )); - } + // emit(state.copyWith( + // isLoading: false, + // routineName: routineDetails.name, + // selectedIcon: routineDetails.iconId, + // selectedAutomationOperator: routineDetails.decisionExpr, + // effectiveTime: routineDetails.effectiveTime, + // isAutomation: routineDetails.conditions != null, + // isTabToRun: routineDetails.conditions == null, + // thenItems: thenItems, + // ifItems: ifItems, + // selectedFunctions: Map.from(state.selectedFunctions), + // )); + // } RoutineState _resetState() { return const RoutineState( @@ -531,7 +558,38 @@ 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)); + SceneApi.deleteScene(unitUuid: spaceId, sceneId: event.sceneId); + add(const LoadScenes(spaceId, communityId)); + //emit(_resetState()); + } catch (e) { + emit(state.copyWith( + isLoading: false, + errorMessage: 'Failed to delete scene', + )); + } + } + + FutureOr _deleteAutomation( + DeleteAutomation event, Emitter emit) { + try { + //emit(state.copyWith(isLoading: true)); + SceneApi.deleteAutomation( + unitUuid: spaceId, automationId: event.automationId); + add(const LoadAutomation(spaceId)); + // emit(_resetState()); + } catch (e) { + emit(state.copyWith( + isLoading: false, + errorMessage: 'Failed to delete automation', + )); + } + } } diff --git a/lib/pages/routiens/bloc/routine_bloc/routine_event.dart b/lib/pages/routiens/bloc/routine_bloc/routine_event.dart index ad93a5ac..82e7875b 100644 --- a/lib/pages/routiens/bloc/routine_bloc/routine_event.dart +++ b/lib/pages/routiens/bloc/routine_bloc/routine_event.dart @@ -158,6 +158,22 @@ class InitializeRoutineState extends RoutineEvent { List get props => [routineDetails]; } +class DeleteScene extends RoutineEvent { + final String sceneId; + final String unitUuid; + const DeleteScene({required this.sceneId, required this.unitUuid}); + @override + List get props => [sceneId]; +} + +class DeleteAutomation extends RoutineEvent { + final String automationId; + final String unitUuid; + const DeleteAutomation({required this.automationId, required this.unitUuid}); + @override + List get props => [automationId]; +} + class ResetRoutineState extends RoutineEvent {} class ClearFunctions extends RoutineEvent {} diff --git a/lib/pages/routiens/widgets/dragable_card.dart b/lib/pages/routiens/widgets/dragable_card.dart index db8ad1c9..5b4de81f 100644 --- a/lib/pages/routiens/widgets/dragable_card.dart +++ b/lib/pages/routiens/widgets/dragable_card.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -81,7 +83,9 @@ class DraggableCard extends StatelessWidget { ? SvgPicture.asset( imagePath, ) - : Image.network(imagePath), + : Image.memory( + base64Decode(imagePath), + ), ), const SizedBox(height: 8), Padding( 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 6f4dfb8f..c9a5114f 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,7 +11,8 @@ class FetchRoutineScenesAutomation extends StatefulWidget { const FetchRoutineScenesAutomation({super.key}); @override - State createState() => _FetchRoutineScenesState(); + State createState() => + _FetchRoutineScenesState(); } class _FetchRoutineScenesState extends State @@ -66,12 +67,49 @@ class _FetchRoutineScenesState extends State padding: EdgeInsets.only( right: isSmallScreenSize(context) ? 4.0 : 8.0, ), - child: RoutineViewCard( - onTap: () {}, - textString: state.scenes[index].name, - icon: state.scenes[index].icon ?? Assets.logoHorizontal, - isFromScenes: true, - iconInBytes: state.scenes[index].iconInBytes, + 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), + ), + ), + ), + ), + ], ), ), ), @@ -104,10 +142,46 @@ class _FetchRoutineScenesState extends State padding: EdgeInsets.only( right: isSmallScreenSize(context) ? 4.0 : 8.0, ), - child: RoutineViewCard( - onTap: () {}, - textString: state.automations[index].name, - icon: state.automations[index].icon ?? Assets.automation, + 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), + ), + ), + ), + ), + ], ), ), ), diff --git a/lib/services/routines_api.dart b/lib/services/routines_api.dart index 7fc3b1bf..333156ba 100644 --- a/lib/services/routines_api.dart +++ b/lib/services/routines_api.dart @@ -212,38 +212,39 @@ class SceneApi { // } // } // - // //delete Scene - // - // static Future deleteScene( - // {required String unitUuid, required String sceneId}) async { - // try { - // final response = await _httpService.delete( - // path: ApiEndpoints.deleteScene - // .replaceAll('{sceneId}', sceneId) - // .replaceAll('{unitUuid}', unitUuid), - // showServerMessage: false, - // expectedResponseModel: (json) => json['statusCode'] == 200, - // ); - // return response; - // } catch (e) { - // rethrow; - // } - // } - // - // // delete automation - // static Future deleteAutomation( - // {required String unitUuid, required String automationId}) async { - // try { - // final response = await _httpService.delete( - // path: ApiEndpoints.deleteAutomation - // .replaceAll('{automationId}', automationId) - // .replaceAll('{unitUuid}', unitUuid), - // showServerMessage: false, - // expectedResponseModel: (json) => json['statusCode'] == 200, - // ); - // return response; - // } catch (e) { - // rethrow; - // } - // } + + + //delete Scene + static Future deleteScene( + {required String unitUuid, required String sceneId}) async { + try { + final response = await _httpService.delete( + path: ApiEndpoints.deleteScene + .replaceAll('{sceneId}', sceneId) + .replaceAll('{unitUuid}', unitUuid), + showServerMessage: false, + expectedResponseModel: (json) => json['statusCode'] == 200, + ); + return response; + } catch (e) { + rethrow; + } + } + + // delete automation + static Future deleteAutomation( + {required String unitUuid, required String automationId}) async { + try { + final response = await _httpService.delete( + path: ApiEndpoints.deleteAutomation + .replaceAll('{automationId}', automationId) + .replaceAll('{unitUuid}', unitUuid), + showServerMessage: false, + expectedResponseModel: (json) => json['statusCode'] == 200, + ); + return response; + } catch (e) { + rethrow; + } + } } diff --git a/lib/utils/constants/api_const.dart b/lib/utils/constants/api_const.dart index 26af5793..dcf6b367 100644 --- a/lib/utils/constants/api_const.dart +++ b/lib/utils/constants/api_const.dart @@ -59,4 +59,7 @@ abstract class ApiEndpoints { static const String getAutomationDetails = '/automation/details/{automationId}'; static const String getScene = '/scene/tap-to-run/{sceneId}'; + static const String deleteScene = '/scene/tap-to-run/{sceneId}'; + + static const String deleteAutomation = '/automation/{automationId}'; }