diff --git a/lib/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart b/lib/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart index 2824ef0..41cab5f 100644 --- a/lib/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart +++ b/lib/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart @@ -32,6 +32,7 @@ class DeviceManagerBloc extends Bloc { final allDevices = await HomeManagementAPI.fetchDevicesByUnitId(); emit(state.copyWith(devices: allDevices, loading: false)); } catch (e) { + print(e); emit(state.copyWith(error: e.toString(), loading: false)); } } diff --git a/lib/features/scene/bloc/create_scene/create_scene_bloc.dart b/lib/features/scene/bloc/create_scene/create_scene_bloc.dart index 024faf4..ac6072e 100644 --- a/lib/features/scene/bloc/create_scene/create_scene_bloc.dart +++ b/lib/features/scene/bloc/create_scene/create_scene_bloc.dart @@ -60,7 +60,8 @@ class CreateSceneBloc extends Bloc String selectedIcon = ''; bool showInDeviceScreen = false; - FutureOr _onAddSceneTask(AddTaskEvent event, Emitter emit) { + FutureOr _onAddSceneTask( + AddTaskEvent event, Emitter emit) { emit(CreateSceneLoading()); if (event.isAutomation == true) { final copyList = List.from(automationTempTasksList); @@ -95,7 +96,8 @@ class CreateSceneBloc extends Bloc } } - void addToTempTaskList(TempHoldSceneTasksEvent event, Emitter emit) { + void addToTempTaskList( + TempHoldSceneTasksEvent event, Emitter emit) { emit(CreateSceneLoading()); bool updated = false; @@ -180,7 +182,8 @@ class CreateSceneBloc extends Bloc )); } - void addToTempAutomationTaskList(TempHoldSceneTasksEvent event, Emitter emit) { + void addToTempAutomationTaskList( + TempHoldSceneTasksEvent event, Emitter emit) { emit(CreateSceneLoading()); bool updated = false; for (var element in automationTempTasksList) { @@ -202,8 +205,10 @@ class CreateSceneBloc extends Bloc ], comparator: automationComparatorValues[element.code], ); - automationTempTasksList[automationTempTasksList.indexOf(element)] = updatedElement; - automationSelectedValues[updatedElement.code] = event.deviceControlModel.value; + automationTempTasksList[automationTempTasksList.indexOf(element)] = + updatedElement; + automationSelectedValues[updatedElement.code] = + event.deviceControlModel.value; updated = true; break; } @@ -223,10 +228,12 @@ class CreateSceneBloc extends Bloc icon: '', ), ], - comparator: automationComparatorValues[event.deviceControlModel.code] ?? '==', + comparator: + automationComparatorValues[event.deviceControlModel.code] ?? '==', ); automationTempTasksList.add(newElement); - automationSelectedValues[newElement.code] = event.deviceControlModel.value; + automationSelectedValues[newElement.code] = + event.deviceControlModel.value; } emit(AddSceneTask( tasksList: tasksList, @@ -235,7 +242,8 @@ class CreateSceneBloc extends Bloc )); } - FutureOr _selectedValue(SelectedValueEvent event, Emitter emit) { + FutureOr _selectedValue( + SelectedValueEvent event, Emitter emit) { if (event.isAutomation == true) { automationSelectedValues[event.code] = event.value; automationComparatorValues[event.code] = event.comparator ?? '=='; @@ -272,7 +280,8 @@ class CreateSceneBloc extends Bloc )); } - FutureOr _removeTaskById(RemoveTaskByIdEvent event, Emitter emit) { + FutureOr _removeTaskById( + RemoveTaskByIdEvent event, Emitter emit) { emit(CreateSceneLoading()); if (event.isAutomation == true) { for (var element in automationTasksList) { @@ -345,7 +354,8 @@ class CreateSceneBloc extends Bloc : await SceneApi.createScene(event.createSceneModel!); } else if (event.createAutomationModel != null) { response = event.updateScene - ? await SceneApi.updateAutomation(event.createAutomationModel!, event.sceneId) + ? await SceneApi.updateAutomation( + event.createAutomationModel!, event.sceneId) : await SceneApi.createAutomation(event.createAutomationModel!); } @@ -359,12 +369,14 @@ class CreateSceneBloc extends Bloc automationComparatorValues.clear(); selectedIcon = ''; showInDeviceScreen = false; - effectiveTime = EffectiveTime(start: '00:00', end: '23:59', loops: '1111111'); + effectiveTime = + EffectiveTime(start: '00:00', end: '23:59', loops: '1111111'); sceneType = CreateSceneEnum.none; conditionRule = 'or'; emit(const CreateSceneWithTasks(success: true)); - CustomSnackBar.greenSnackBar( - event.updateScene ? 'Scene updated successfully' : 'Scene created successfully'); + CustomSnackBar.greenSnackBar(event.updateScene + ? 'Scene updated successfully' + : 'Scene created successfully'); } else { emit(const CreateSceneError(message: 'Something went wrong')); } @@ -378,7 +390,8 @@ class CreateSceneBloc extends Bloc } } - FutureOr _clearTaskList(ClearTaskListEvent event, Emitter emit) { + FutureOr _clearTaskList( + ClearTaskListEvent event, Emitter emit) { emit(CreateSceneLoading()); automationTasksList.clear(); tasksList.clear(); @@ -389,7 +402,8 @@ class CreateSceneBloc extends Bloc )); } - FutureOr _clearTabToRunSetting(ClearTabToRunSetting event, Emitter emit) { + FutureOr _clearTabToRunSetting( + ClearTabToRunSetting event, Emitter emit) { emit(CreateSceneLoading()); selectedIcon = ''; showInDeviceScreen = false; @@ -416,7 +430,8 @@ class CreateSceneBloc extends Bloc automationComparatorValues.clear(); selectedIcon = ''; showInDeviceScreen = false; - effectiveTime = EffectiveTime(start: '00:00', end: '23:59', loops: '1111111'); + effectiveTime = + EffectiveTime(start: '00:00', end: '23:59', loops: '1111111'); sceneType = CreateSceneEnum.none; conditionRule = 'or'; @@ -425,10 +440,14 @@ class CreateSceneBloc extends Bloc : await SceneApi.getSceneDetails(event.sceneId); if (response.id.isNotEmpty) { if (event.isAutomation) { - automationTasksList = List.from(getTaskListFunctionsFromApi( - actions: [], isAutomation: true, conditions: response.conditions)); + automationTasksList = List.from( + getTaskListFunctionsFromApi( + actions: [], + isAutomation: true, + conditions: response.conditions)); tasksList = List.from( - getTaskListFunctionsFromApi(actions: response.actions, isAutomation: false)); + getTaskListFunctionsFromApi( + actions: response.actions, isAutomation: false)); conditionRule = response.decisionExpr ?? conditionRule; @@ -441,11 +460,13 @@ class CreateSceneBloc extends Bloc : EffectiveTime(start: '00:00', end: '23:59', loops: '1111111'); // Set the days directly from the API response - BlocProvider.of(NavigationService.navigatorKey.currentContext!) + BlocProvider.of( + NavigationService.navigatorKey.currentContext!) .add(SetDays(response.effectiveTime?.loops ?? '1111111')); // Set Custom Time and reset days first - BlocProvider.of(NavigationService.navigatorKey.currentContext!) + BlocProvider.of( + NavigationService.navigatorKey.currentContext!) .add(SetCustomTime(effectiveTime!.start, effectiveTime!.end)); emit(AddSceneTask( @@ -457,7 +478,8 @@ class CreateSceneBloc extends Bloc showInDevice: showInDeviceScreen)); } else { tasksList = List.from( - getTaskListFunctionsFromApi(actions: response.actions, isAutomation: false)); + getTaskListFunctionsFromApi( + actions: response.actions, isAutomation: false)); selectedIcon = response.icon!; showInDeviceScreen = response.showInDevice!; emit(AddSceneTask( @@ -475,7 +497,8 @@ class CreateSceneBloc extends Bloc } } - FutureOr _fetchIconScene(SceneIconEvent event, Emitter emit) async { + FutureOr _fetchIconScene( + SceneIconEvent event, Emitter emit) async { emit(CreateSceneLoading()); try { iconModelList = await SceneApi.getIcon(); @@ -491,7 +514,8 @@ class CreateSceneBloc extends Bloc } } - FutureOr _iconSelected(IconSelected event, Emitter emit) async { + FutureOr _iconSelected( + IconSelected event, Emitter emit) async { try { if (event.confirmSelection) { selectedIcon = event.iconId; @@ -531,7 +555,8 @@ class CreateSceneBloc extends Bloc return days[index]; } - FutureOr _clearTempTaskList(ClearTempTaskListEvent event, Emitter emit) { + FutureOr _clearTempTaskList( + ClearTempTaskListEvent event, Emitter emit) { emit(CreateSceneLoading()); if (event.isAutomation == true) { automationTempTasksList.clear(); @@ -575,13 +600,18 @@ class CreateSceneBloc extends Bloc } } - FutureOr _deleteScene(DeleteSceneEvent event, Emitter emit) async { + FutureOr _deleteScene( + DeleteSceneEvent event, Emitter emit) async { emit(DeleteSceneLoading()); try { - final response = sceneType.name == CreateSceneEnum.deviceStatusChanges.name - ? await SceneApi.deleteAutomation(automationId: event.sceneId, unitUuid: event.unitUuid) - : await SceneApi.deleteScene(sceneId: event.sceneId, unitUuid: event.unitUuid); + final response = + sceneType.name == CreateSceneEnum.deviceStatusChanges.name + ? await SceneApi.deleteAutomation( + automationId: event.sceneId, unitUuid: event.unitUuid) + : await SceneApi.deleteScene( + sceneId: event.sceneId, + ); if (response == true) { emit(const DeleteSceneSuccess(true)); } else { @@ -592,7 +622,8 @@ class CreateSceneBloc extends Bloc } } - FutureOr _updateTaskValue(UpdateTaskEvent event, Emitter emit) { + FutureOr _updateTaskValue( + UpdateTaskEvent event, Emitter emit) { emit(CreateSceneLoading()); if (event.isAutomation == true) { for (var i = 0; i < automationTasksList.length; i++) { @@ -628,7 +659,8 @@ class CreateSceneBloc extends Bloc )); } - FutureOr _selectConditionRule(SelectConditionEvent event, Emitter emit) { + FutureOr _selectConditionRule( + SelectConditionEvent event, Emitter emit) { emit(CreateSceneInitial()); if (event.condition.contains('any')) { conditionRule = 'or'; @@ -643,7 +675,8 @@ class CreateSceneBloc extends Bloc )); } - FutureOr _sceneTypeEvent(SceneTypeEvent event, Emitter emit) { + FutureOr _sceneTypeEvent( + SceneTypeEvent event, Emitter emit) { // emit(CreateSceneInitial()); if (event.type == CreateSceneEnum.tabToRun) { diff --git a/lib/features/scene/bloc/scene_bloc/scene_bloc.dart b/lib/features/scene/bloc/scene_bloc/scene_bloc.dart index 701e30a..35bdbd6 100644 --- a/lib/features/scene/bloc/scene_bloc/scene_bloc.dart +++ b/lib/features/scene/bloc/scene_bloc/scene_bloc.dart @@ -24,7 +24,9 @@ class SceneBloc extends Bloc { try { if (event.unitId.isNotEmpty) { - scenes = await SceneApi.getScenesByUnitId(event.unitId, showInDevice: event.showInDevice); + scenes = await SceneApi.getScenesByUnitId( + event.unitId, event.unit.community.uuid, + showInDevice: event.showInDevice); emit(SceneLoaded(scenes, automationList)); } else { emit(const SceneError(message: 'Unit ID is empty')); @@ -34,7 +36,8 @@ class SceneBloc extends Bloc { } } - Future _onLoadAutomation(LoadAutomation event, Emitter emit) async { + Future _onLoadAutomation( + LoadAutomation event, Emitter emit) async { emit(SceneLoading()); try { @@ -49,7 +52,8 @@ class SceneBloc extends Bloc { } } - Future _onSceneTrigger(SceneTrigger event, Emitter emit) async { + Future _onSceneTrigger( + SceneTrigger event, Emitter emit) async { final currentState = state; if (currentState is SceneLoaded) { emit(SceneLoaded( @@ -76,8 +80,9 @@ class SceneBloc extends Bloc { UpdateAutomationStatus event, Emitter emit) async { final currentState = state; if (currentState is SceneLoaded) { - final newLoadingStates = Map.from(currentState.loadingStates) - ..[event.automationId] = true; + final newLoadingStates = + Map.from(currentState.loadingStates) + ..[event.automationId] = true; emit(SceneLoaded( currentState.scenes, @@ -86,11 +91,11 @@ class SceneBloc extends Bloc { )); try { - final success = - await SceneApi.updateAutomationStatus(event.automationId, event.automationStatusUpdate); + final success = await SceneApi.updateAutomationStatus( + event.automationId, event.automationStatusUpdate); if (success) { - automationList = - await SceneApi.getAutomationByUnitId(event.automationStatusUpdate.unitUuid); + automationList = await SceneApi.getAutomationByUnitId( + event.automationStatusUpdate.unitUuid); newLoadingStates[event.automationId] = false; emit(SceneLoaded( currentState.scenes, diff --git a/lib/features/scene/bloc/scene_bloc/scene_event.dart b/lib/features/scene/bloc/scene_bloc/scene_event.dart index d72f3a7..7807bbb 100644 --- a/lib/features/scene/bloc/scene_bloc/scene_event.dart +++ b/lib/features/scene/bloc/scene_bloc/scene_event.dart @@ -1,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/features/app_layout/model/space_model.dart'; import 'package:syncrow_app/features/scene/model/update_automation.dart'; abstract class SceneEvent extends Equatable { @@ -11,8 +12,9 @@ abstract class SceneEvent extends Equatable { class LoadScenes extends SceneEvent { final String unitId; final bool showInDevice; + final SpaceModel unit; - const LoadScenes(this.unitId, {this.showInDevice = false}); + const LoadScenes(this.unitId, this.unit, {this.showInDevice = false}); @override List get props => [unitId, showInDevice]; diff --git a/lib/features/scene/model/create_automation_model.dart b/lib/features/scene/model/create_automation_model.dart index a349dc2..e54c3e4 100644 --- a/lib/features/scene/model/create_automation_model.dart +++ b/lib/features/scene/model/create_automation_model.dart @@ -39,7 +39,7 @@ class CreateAutomationModel { Map toMap([String? automationId]) { return { - if (automationId == null) 'unitUuid': unitUuid, + if (automationId == null) 'spaceUuid': unitUuid, 'automationName': automationName, 'decisionExpr': decisionExpr, 'effectiveTime': effectiveTime.toMap(), @@ -50,7 +50,7 @@ class CreateAutomationModel { factory CreateAutomationModel.fromMap(Map map) { return CreateAutomationModel( - unitUuid: map['unitUuid'] ?? '', + unitUuid: map['spaceUuid'] ?? '', automationName: map['automationName'] ?? '', decisionExpr: map['decisionExpr'] ?? '', effectiveTime: EffectiveTime.fromMap(map['effectiveTime']), diff --git a/lib/features/scene/model/scene_details_model.dart b/lib/features/scene/model/scene_details_model.dart index 99a2c5f..05453f7 100644 --- a/lib/features/scene/model/scene_details_model.dart +++ b/lib/features/scene/model/scene_details_model.dart @@ -25,28 +25,34 @@ class SceneDetailsModel { this.effectiveTime, }); - factory SceneDetailsModel.fromRawJson(String str) => SceneDetailsModel.fromJson(json.decode(str)); + factory SceneDetailsModel.fromRawJson(String str) => + SceneDetailsModel.fromJson(json.decode(str)); String toRawJson() => json.encode(toJson()); - factory SceneDetailsModel.fromJson(Map json) => SceneDetailsModel( - id: json["id"], - name: json["name"], - status: json["status"], - type: json["type"], - actions: (json["actions"] as List) - .map((x) => Action.fromJson(x)) - .where((x) => x != null) - .toList() - .cast(), - conditions: json["conditions"] != null - ? (json["conditions"] as List).map((x) => Condition.fromJson(x)).toList() - : null, - decisionExpr: json["decisionExpr"], - effectiveTime: - json["effectiveTime"] != null ? EffectiveTime.fromJson(json["effectiveTime"]) : null, - icon: json["iconUuid"] != null ? json["iconUuid"] ?? '' : '', - showInDevice: json['showInHome'] != null ? json['showInHome'] ?? false : false); + factory SceneDetailsModel.fromJson(Map json) => + SceneDetailsModel( + id: json["uuid"], + name: json["name"], + status: json["status"], + type: json["type"], + actions: (json["actions"] as List) + .map((x) => Action.fromJson(x)) + .where((x) => x != null) + .toList() + .cast(), + conditions: json["conditions"] != null + ? (json["conditions"] as List) + .map((x) => Condition.fromJson(x)) + .toList() + : null, + decisionExpr: json["decisionExpr"], + effectiveTime: json["effectiveTime"] != null + ? EffectiveTime.fromJson(json["effectiveTime"]) + : null, + icon: json["iconUuid"] != null ? json["iconUuid"] ?? '' : '', + showInDevice: + json['showInHome'] != null ? json['showInHome'] ?? false : false); Map toJson() => { "id": id, @@ -54,8 +60,9 @@ class SceneDetailsModel { "status": status, "type": type, "actions": List.from(actions.map((x) => x.toJson())), - "conditions": - conditions != null ? List.from(conditions!.map((x) => x.toJson())) : null, + "conditions": conditions != null + ? List.from(conditions!.map((x) => x.toJson())) + : null, "decisionExpr": decisionExpr, "effectiveTime": effectiveTime?.toJson(), }; @@ -116,7 +123,8 @@ class ExecutorProperty { this.delaySeconds, }); - factory ExecutorProperty.fromJson(Map json) => ExecutorProperty( + factory ExecutorProperty.fromJson(Map json) => + ExecutorProperty( functionCode: json["functionCode"] ?? '', functionValue: json["functionValue"] ?? '', delaySeconds: json["delaySeconds"] ?? 0, @@ -142,7 +150,8 @@ class Condition { required this.expr, }); - factory Condition.fromRawJson(String str) => Condition.fromJson(json.decode(str)); + factory Condition.fromRawJson(String str) => + Condition.fromJson(json.decode(str)); String toRawJson() => json.encode(toJson()); @@ -200,7 +209,8 @@ class EffectiveTime { required this.loops, }); - factory EffectiveTime.fromRawJson(String str) => EffectiveTime.fromJson(json.decode(str)); + factory EffectiveTime.fromRawJson(String str) => + EffectiveTime.fromJson(json.decode(str)); String toRawJson() => json.encode(toJson()); diff --git a/lib/features/scene/model/scenes_model.dart b/lib/features/scene/model/scenes_model.dart index 8f4b2fd..7f9d654 100644 --- a/lib/features/scene/model/scenes_model.dart +++ b/lib/features/scene/model/scenes_model.dart @@ -3,32 +3,40 @@ import 'dart:typed_data'; class ScenesModel { final String id; + final String? sceneTuyaId; final String name; final String status; final String type; - final String icon; + final String? icon; ScenesModel( {required this.id, + this.sceneTuyaId, required this.name, required this.status, required this.type, - required this.icon}); + this.icon}); - factory ScenesModel.fromRawJson(String str) => ScenesModel.fromJson(json.decode(str)); + factory ScenesModel.fromRawJson(String str) => + ScenesModel.fromJson(json.decode(str)); String toRawJson() => json.encode(toJson()); - Uint8List get iconInBytes => base64Decode(icon); - - factory ScenesModel.fromJson(Map json) => ScenesModel( - id: json["uuid"], - name: json["name"] ?? '', - status: json["status"] ?? '', - type: json["type"] ?? '', - icon: json["icon"] ?? ''); + Uint8List get iconInBytes => base64Decode(icon ?? ''); + factory ScenesModel.fromJson(Map json) { + return ScenesModel( + id: json["id"] ?? json["uuid"] ?? '', // Fallback to empty string if id is null + sceneTuyaId: json["sceneTuyaId"] as String?, // Nullable + name: json["name"] ?? '', // Fallback to empty string if name is null + status: + json["status"] ?? '', // Fallback to empty string if status is null + type: json["type"] ?? '', // Fallback to empty string if type is null + icon: json["icon"] as String?, // Nullable + ); + } Map toJson() => { "id": id, + "sceneTuyaId": sceneTuyaId ?? '', "name": name, "status": status, "type": type, diff --git a/lib/features/scene/view/scene_view.dart b/lib/features/scene/view/scene_view.dart index a2d1881..41d1fdd 100644 --- a/lib/features/scene/view/scene_view.dart +++ b/lib/features/scene/view/scene_view.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; +import 'package:syncrow_app/features/app_layout/model/community_model.dart'; +import 'package:syncrow_app/features/app_layout/model/space_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/scene_listview.dart'; import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart'; import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_bloc.dart'; @@ -21,32 +23,47 @@ class SceneView extends StatelessWidget { Widget build(BuildContext context) { return BlocProvider( create: (BuildContext context) => SceneBloc() - ..add(LoadScenes(HomeCubit.getInstance().selectedSpace?.id ?? '', showInDevice: pageType)) + ..add(LoadScenes( + HomeCubit.getInstance().selectedSpace?.id ?? '', + HomeCubit.getInstance().selectedSpace ?? + SpaceModel( + id: '-1', + name: '', + community: Community( + uuid: '-1', + name: '', + )), + showInDevice: pageType)) ..add(LoadAutomation(HomeCubit.getInstance().selectedSpace?.id ?? '')), child: BlocBuilder( builder: (context, state) { if (state is DeleteSceneSuccess) { if (state.success) { + BlocProvider.of(context).add(LoadScenes( + HomeCubit.getInstance().selectedSpace!.id!,HomeCubit.getInstance().selectedSpace!, + showInDevice: pageType)); BlocProvider.of(context).add( - LoadScenes(HomeCubit.getInstance().selectedSpace!.id!, showInDevice: pageType)); - BlocProvider.of(context) - .add(LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!)); + LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!)); } } if (state is CreateSceneWithTasks) { if (state.success == true) { + BlocProvider.of(context).add(LoadScenes( + HomeCubit.getInstance().selectedSpace!.id!,HomeCubit.getInstance().selectedSpace!, + showInDevice: pageType)); BlocProvider.of(context).add( - LoadScenes(HomeCubit.getInstance().selectedSpace!.id!, showInDevice: pageType)); - BlocProvider.of(context) - .add(LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!)); - context.read().add(const SmartSceneClearEvent()); + LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!)); + context + .read() + .add(const SmartSceneClearEvent()); } } return BlocListener( listener: (context, state) { if (state is SceneTriggerSuccess) { context.showCustomSnackbar( - message: 'Scene ${state.sceneName} triggered successfully!'); + message: + 'Scene ${state.sceneName} triggered successfully!'); } }, child: HomeCubit.getInstance().spaces?.isEmpty ?? true @@ -83,25 +100,30 @@ class SceneView extends StatelessWidget { child: ListView( children: [ Theme( - data: ThemeData() - .copyWith(dividerColor: Colors.transparent), + data: ThemeData().copyWith( + dividerColor: Colors.transparent), child: ExpansionTile( - tilePadding: const EdgeInsets.symmetric(horizontal: 6), + tilePadding: + const EdgeInsets.symmetric( + horizontal: 6), initiallyExpanded: true, iconColor: ColorsManager.grayColor, - title: const BodyMedium(text: 'Tap to run routines'), + title: const BodyMedium( + text: 'Tap to run routines'), children: [ scenes.isNotEmpty ? SceneGrid( scenes: scenes, - loadingSceneId: state.loadingSceneId, + loadingSceneId: + state.loadingSceneId, disablePlayButton: false, - loadingStates: - state.loadingStates, // Add this line + loadingStates: state + .loadingStates, // Add this line ) : const Center( child: BodyMedium( - text: 'No scenes have been added yet', + text: + 'No scenes have been added yet', ), ), const SizedBox( @@ -111,25 +133,30 @@ class SceneView extends StatelessWidget { ), ), Theme( - data: ThemeData() - .copyWith(dividerColor: Colors.transparent), + data: ThemeData().copyWith( + dividerColor: Colors.transparent), child: ExpansionTile( initiallyExpanded: true, iconColor: ColorsManager.grayColor, - tilePadding: const EdgeInsets.symmetric(horizontal: 6), - title: const BodyMedium(text: 'Automation'), + tilePadding: + const EdgeInsets.symmetric( + horizontal: 6), + title: const BodyMedium( + text: 'Automation'), children: [ automationList.isNotEmpty ? SceneGrid( scenes: automationList, - loadingSceneId: state.loadingSceneId, + loadingSceneId: + state.loadingSceneId, disablePlayButton: true, - loadingStates: - state.loadingStates, // Add this line + loadingStates: state + .loadingStates, // Add this line ) : const Center( child: BodyMedium( - text: 'No automations have been added yet', + text: + 'No automations have been added yet', ), ), const SizedBox( diff --git a/lib/features/scene/widgets/delete_routine_b.dart b/lib/features/scene/widgets/delete_routine_b.dart index 18293b1..b344683 100644 --- a/lib/features/scene/widgets/delete_routine_b.dart +++ b/lib/features/scene/widgets/delete_routine_b.dart @@ -24,7 +24,7 @@ class DeleteRoutineButton extends StatelessWidget { if (state.success) { navigateToRoute(context, Routes.homeRoute); BlocProvider.of(context) - .add(LoadScenes(HomeCubit.getInstance().selectedSpace!.id!)); + .add(LoadScenes(HomeCubit.getInstance().selectedSpace!.id!,HomeCubit.getInstance().selectedSpace!)); BlocProvider.of(context).add( LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!)); } diff --git a/lib/features/scene/widgets/select_smart_scene/smart_enable_tab_run.dart b/lib/features/scene/widgets/select_smart_scene/smart_enable_tab_run.dart index 37a5e7c..a50aa6f 100644 --- a/lib/features/scene/widgets/select_smart_scene/smart_enable_tab_run.dart +++ b/lib/features/scene/widgets/select_smart_scene/smart_enable_tab_run.dart @@ -17,7 +17,7 @@ class SmartEnableTabRun extends StatelessWidget { width: double.infinity, child: BlocBuilder( bloc: context.read() - ..add(LoadScenes(HomeCubit.getInstance().selectedSpace?.id ?? '')), + ..add(LoadScenes(HomeCubit.getInstance().selectedSpace?.id ?? '',HomeCubit.getInstance().selectedSpace!)), builder: (context, state) { if (state is SceneLoading) { return const Align( diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index 319bdef..fe6cc56 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -150,9 +150,9 @@ class DevicesAPI { }) async { try { final String path = ApiEndpoints.deviceByRoom - .replaceAll(':communityUuid', communityUuid) - .replaceAll(':spaceUuid', spaceUuid) - .replaceAll(':subSpaceUuid', roomId); + .replaceAll('{communityUuid}', communityUuid) + .replaceAll('{spaceUuid}', spaceUuid) + .replaceAll('{subSpaceUuid}', roomId); final response = await _httpService.get( path: path, diff --git a/lib/services/api/home_management_api.dart b/lib/services/api/home_management_api.dart index 63b5f22..faf92d4 100644 --- a/lib/services/api/home_management_api.dart +++ b/lib/services/api/home_management_api.dart @@ -37,15 +37,17 @@ class HomeManagementAPI { // Ensure both placeholders are replaced final path = ApiEndpoints.spaceDevices - .replaceAll("{communityUuid}", communityUuid) - .replaceAll("{spaceUuid}", spaceUuid); + .replaceAll('{communityUuid}', communityUuid) + .replaceAll('{spaceUuid}', spaceUuid); await _httpService.get( path: path, showServerMessage: false, expectedResponseModel: (json) { - json.forEach((value) { - list.add(DeviceModel.fromJson(value)); - }); + if (json['data'] != null) { + json['data'].forEach((value) { + list.add(DeviceModel.fromJson(value)); + }); + } }, ); diff --git a/lib/services/api/scene_api.dart b/lib/services/api/scene_api.dart index 6e0d981..65e4382 100644 --- a/lib/services/api/scene_api.dart +++ b/lib/services/api/scene_api.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:syncrow_app/features/scene/model/create_automation_model.dart'; import 'package:syncrow_app/features/scene/model/create_scene_model.dart'; import 'package:syncrow_app/features/scene/model/icon_model.dart'; @@ -11,7 +13,8 @@ class SceneApi { static final HTTPService _httpService = HTTPService(); //create scene - static Future> createScene(CreateSceneModel createSceneModel) async { + static Future> createScene( + CreateSceneModel createSceneModel) async { try { final response = await _httpService.post( path: ApiEndpoints.createScene, @@ -47,15 +50,21 @@ class SceneApi { //get scene by unit id - static Future> getScenesByUnitId(String unitId, {showInDevice = false}) async { + static Future> getScenesByUnitId( + String unitId, String communityId, + {showInDevice = false}) async { try { final response = await _httpService.get( - path: ApiEndpoints.getUnitScenes.replaceAll('{unitUuid}', unitId), + path: ApiEndpoints.getUnitScenes + .replaceAll('{spaceUuid}', unitId) + .replaceAll('{communityUuid}', communityId), queryParameters: {'showInHomePage': showInDevice}, showServerMessage: false, expectedResponseModel: (json) { + final scenesJson = json['data'] as List; + List scenes = []; - for (var scene in json) { + for (var scene in scenesJson) { scenes.add(ScenesModel.fromJson(scene)); } return scenes; @@ -102,10 +111,12 @@ class SceneApi { } //automation details - static Future getAutomationDetails(String automationId) async { + static Future getAutomationDetails( + String automationId) async { try { final response = await _httpService.get( - path: ApiEndpoints.getAutomationDetails.replaceAll('{automationId}', automationId), + path: ApiEndpoints.getAutomationDetails + .replaceAll('{automationId}', automationId), showServerMessage: false, expectedResponseModel: (json) => SceneDetailsModel.fromJson(json), ); @@ -116,11 +127,12 @@ class SceneApi { } //updateAutomationStatus - static Future updateAutomationStatus( - String automationId, AutomationStatusUpdate createAutomationEnable) async { + static Future updateAutomationStatus(String automationId, + AutomationStatusUpdate createAutomationEnable) async { try { final response = await _httpService.put( - path: ApiEndpoints.updateAutomationStatus.replaceAll('{automationId}', automationId), + path: ApiEndpoints.updateAutomationStatus + .replaceAll('{automationId}', automationId), body: createAutomationEnable.toMap(), expectedResponseModel: (json) => json['success'], ); @@ -135,7 +147,13 @@ class SceneApi { final response = await _httpService.get( path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId), showServerMessage: false, - expectedResponseModel: (json) => SceneDetailsModel.fromJson(json), + expectedResponseModel: (json) { + if (json != null && json['data'] != null) { + return SceneDetailsModel.fromJson(json['data']); + } else { + throw Exception('Data field is null'); + } + }, ); return response; } catch (e) { @@ -163,7 +181,8 @@ class SceneApi { try { final response = await _httpService.put( path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId), - body: createSceneModel.toJson(sceneId.isNotEmpty == true ? sceneId : null), + body: createSceneModel + .toJson(sceneId.isNotEmpty == true ? sceneId : null), expectedResponseModel: (json) { return json; }, @@ -175,11 +194,14 @@ class SceneApi { } //update automation - static updateAutomation(CreateAutomationModel createAutomationModel, String automationId) async { + static updateAutomation( + CreateAutomationModel createAutomationModel, String automationId) async { try { final response = await _httpService.put( - path: ApiEndpoints.updateAutomation.replaceAll('{automationId}', automationId), - body: createAutomationModel.toJson(automationId.isNotEmpty == true ? automationId : null), + path: ApiEndpoints.updateAutomation + .replaceAll('{automationId}', automationId), + body: createAutomationModel + .toJson(automationId.isNotEmpty == true ? automationId : null), expectedResponseModel: (json) { return json; }, @@ -192,12 +214,10 @@ class SceneApi { //delete Scene - static Future deleteScene({required String unitUuid, required String sceneId}) async { + static Future deleteScene({required String sceneId}) async { try { final response = await _httpService.delete( - path: ApiEndpoints.deleteScene - .replaceAll('{sceneId}', sceneId) - .replaceAll('{unitUuid}', unitUuid), + path: ApiEndpoints.deleteScene.replaceAll('{sceneId}', sceneId), showServerMessage: false, expectedResponseModel: (json) => json['statusCode'] == 200, );