diff --git a/assets/icons/functions_icons/ac_cooling.svg b/assets/icons/functions_icons/ac_cooling.svg new file mode 100644 index 00000000..e95c0d4e --- /dev/null +++ b/assets/icons/functions_icons/ac_cooling.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/ac_fan_auto.svg b/assets/icons/functions_icons/ac_fan_auto.svg new file mode 100644 index 00000000..0acacfef --- /dev/null +++ b/assets/icons/functions_icons/ac_fan_auto.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/icons/functions_icons/ac_fan_high.svg b/assets/icons/functions_icons/ac_fan_high.svg new file mode 100644 index 00000000..d6131531 --- /dev/null +++ b/assets/icons/functions_icons/ac_fan_high.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/ac_fan_low.svg b/assets/icons/functions_icons/ac_fan_low.svg new file mode 100644 index 00000000..f4bf56b7 --- /dev/null +++ b/assets/icons/functions_icons/ac_fan_low.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/ac_fan_middle.svg b/assets/icons/functions_icons/ac_fan_middle.svg new file mode 100644 index 00000000..ee940238 --- /dev/null +++ b/assets/icons/functions_icons/ac_fan_middle.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/ac_heating.svg b/assets/icons/functions_icons/ac_heating.svg new file mode 100644 index 00000000..47a160c8 --- /dev/null +++ b/assets/icons/functions_icons/ac_heating.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/ac_power.svg b/assets/icons/functions_icons/ac_power.svg new file mode 100644 index 00000000..cc2127f0 --- /dev/null +++ b/assets/icons/functions_icons/ac_power.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/functions_icons/ac_power_off.svg b/assets/icons/functions_icons/ac_power_off.svg new file mode 100644 index 00000000..70f7f9aa --- /dev/null +++ b/assets/icons/functions_icons/ac_power_off.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/functions_icons/automation_functions/card_unlock.svg b/assets/icons/functions_icons/automation_functions/card_unlock.svg new file mode 100644 index 00000000..dd77680a --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/card_unlock.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/current_temp.svg b/assets/icons/functions_icons/automation_functions/current_temp.svg new file mode 100644 index 00000000..42cceb23 --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/current_temp.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/doorbell.svg b/assets/icons/functions_icons/automation_functions/doorbell.svg new file mode 100644 index 00000000..1dc515a9 --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/doorbell.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/doorlock_normal_open.svg b/assets/icons/functions_icons/automation_functions/doorlock_normal_open.svg new file mode 100644 index 00000000..8f4a5901 --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/doorlock_normal_open.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/double_lock.svg b/assets/icons/functions_icons/automation_functions/double_lock.svg new file mode 100644 index 00000000..d8ad971d --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/double_lock.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/fingerprint_unlock.svg b/assets/icons/functions_icons/automation_functions/fingerprint_unlock.svg new file mode 100644 index 00000000..f9f5b84c --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/fingerprint_unlock.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/hijack_alarm.svg b/assets/icons/functions_icons/automation_functions/hijack_alarm.svg new file mode 100644 index 00000000..e32997fb --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/hijack_alarm.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/lock_alarm.svg b/assets/icons/functions_icons/automation_functions/lock_alarm.svg new file mode 100644 index 00000000..8bd2deeb --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/lock_alarm.svg @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/motion.svg b/assets/icons/functions_icons/automation_functions/motion.svg new file mode 100644 index 00000000..8d69463b --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/motion.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/password_unlock.svg b/assets/icons/functions_icons/automation_functions/password_unlock.svg new file mode 100644 index 00000000..1920b69f --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/password_unlock.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/presence.svg b/assets/icons/functions_icons/automation_functions/presence.svg new file mode 100644 index 00000000..d71a474d --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/presence.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/presence_state.svg b/assets/icons/functions_icons/automation_functions/presence_state.svg new file mode 100644 index 00000000..d5de48e1 --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/presence_state.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/remote_unlock_req.svg b/assets/icons/functions_icons/automation_functions/remote_unlock_req.svg new file mode 100644 index 00000000..da128ff7 --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/remote_unlock_req.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/remote_unlock_via_app.svg b/assets/icons/functions_icons/automation_functions/remote_unlock_via_app.svg new file mode 100644 index 00000000..39fc859b --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/remote_unlock_via_app.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/residual_electricity.svg b/assets/icons/functions_icons/automation_functions/residual_electricity.svg new file mode 100644 index 00000000..6a5b6127 --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/residual_electricity.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/functions_icons/automation_functions/self_test_result.svg b/assets/icons/functions_icons/automation_functions/self_test_result.svg new file mode 100644 index 00000000..8739327b --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/self_test_result.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/automation_functions/temp_password_unlock.svg b/assets/icons/functions_icons/automation_functions/temp_password_unlock.svg new file mode 100644 index 00000000..98d7573c --- /dev/null +++ b/assets/icons/functions_icons/automation_functions/temp_password_unlock.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/celsius_degrees.svg b/assets/icons/functions_icons/celsius_degrees.svg new file mode 100644 index 00000000..7acbd6e7 --- /dev/null +++ b/assets/icons/functions_icons/celsius_degrees.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/assets/icons/functions_icons/child_lock.svg b/assets/icons/functions_icons/child_lock.svg new file mode 100644 index 00000000..6b0138bf --- /dev/null +++ b/assets/icons/functions_icons/child_lock.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/functions_icons/factory_reset.svg b/assets/icons/functions_icons/factory_reset.svg new file mode 100644 index 00000000..7a47f24b --- /dev/null +++ b/assets/icons/functions_icons/factory_reset.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/icons/functions_icons/fan_speed.svg b/assets/icons/functions_icons/fan_speed.svg new file mode 100644 index 00000000..07a48834 --- /dev/null +++ b/assets/icons/functions_icons/fan_speed.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/far_detection.svg b/assets/icons/functions_icons/far_detection.svg new file mode 100644 index 00000000..2827d94a --- /dev/null +++ b/assets/icons/functions_icons/far_detection.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/far_detection_function.svg b/assets/icons/functions_icons/far_detection_function.svg new file mode 100644 index 00000000..894b84ed --- /dev/null +++ b/assets/icons/functions_icons/far_detection_function.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/freezing.svg b/assets/icons/functions_icons/freezing.svg new file mode 100644 index 00000000..6c02f2e4 --- /dev/null +++ b/assets/icons/functions_icons/freezing.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/functions_icons/indicator.svg b/assets/icons/functions_icons/indicator.svg new file mode 100644 index 00000000..b58a976e --- /dev/null +++ b/assets/icons/functions_icons/indicator.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/light_countdown.svg b/assets/icons/functions_icons/light_countdown.svg new file mode 100644 index 00000000..94f65b9a --- /dev/null +++ b/assets/icons/functions_icons/light_countdown.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/master_state.svg b/assets/icons/functions_icons/master_state.svg new file mode 100644 index 00000000..0aafae1a --- /dev/null +++ b/assets/icons/functions_icons/master_state.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/motion_detection.svg b/assets/icons/functions_icons/motion_detection.svg new file mode 100644 index 00000000..a9b2d685 --- /dev/null +++ b/assets/icons/functions_icons/motion_detection.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/motionless_detection.svg b/assets/icons/functions_icons/motionless_detection.svg new file mode 100644 index 00000000..25a767c1 --- /dev/null +++ b/assets/icons/functions_icons/motionless_detection.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/icons/functions_icons/nobody_time.svg b/assets/icons/functions_icons/nobody_time.svg new file mode 100644 index 00000000..df80b517 --- /dev/null +++ b/assets/icons/functions_icons/nobody_time.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/functions_icons/reset_off.svg b/assets/icons/functions_icons/reset_off.svg new file mode 100644 index 00000000..eac88f2b --- /dev/null +++ b/assets/icons/functions_icons/reset_off.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/icons/functions_icons/scene_child_lock.svg b/assets/icons/functions_icons/scene_child_lock.svg new file mode 100644 index 00000000..7e56164a --- /dev/null +++ b/assets/icons/functions_icons/scene_child_lock.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/scene_child_unlock.svg b/assets/icons/functions_icons/scene_child_unlock.svg new file mode 100644 index 00000000..4eafbdea --- /dev/null +++ b/assets/icons/functions_icons/scene_child_unlock.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/scene_refresh.svg b/assets/icons/functions_icons/scene_refresh.svg new file mode 100644 index 00000000..c54ffb04 --- /dev/null +++ b/assets/icons/functions_icons/scene_refresh.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/icons/functions_icons/sensitivity.svg b/assets/icons/functions_icons/sensitivity.svg new file mode 100644 index 00000000..b75ebd3e --- /dev/null +++ b/assets/icons/functions_icons/sensitivity.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/icons/functions_icons/sesitivity_operation_icon.svg b/assets/icons/functions_icons/sesitivity_operation_icon.svg new file mode 100644 index 00000000..612148c5 --- /dev/null +++ b/assets/icons/functions_icons/sesitivity_operation_icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/functions_icons/switch_alarm_sound.svg b/assets/icons/functions_icons/switch_alarm_sound.svg new file mode 100644 index 00000000..db645338 --- /dev/null +++ b/assets/icons/functions_icons/switch_alarm_sound.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/icons/functions_icons/tempreture.svg b/assets/icons/functions_icons/tempreture.svg new file mode 100644 index 00000000..448083a7 --- /dev/null +++ b/assets/icons/functions_icons/tempreture.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/lib/pages/device_managment/all_devices/models/devices_model.dart b/lib/pages/device_managment/all_devices/models/devices_model.dart index 50e588b0..b37ff36c 100644 --- a/lib/pages/device_managment/all_devices/models/devices_model.dart +++ b/lib/pages/device_managment/all_devices/models/devices_model.dart @@ -2,6 +2,8 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/device_com import 'package:syncrow_web/pages/device_managment/all_devices/models/device_space_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/room.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/unit.dart'; +import 'package:syncrow_web/pages/routiens/models/ac/ac_function.dart'; +import 'package:syncrow_web/pages/routiens/models/device_functions.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/enum/device_types.dart'; @@ -69,6 +71,7 @@ class AllDevicesModel { int? batteryLevel; String? productName; List? spaces; + List? _deviceFunctions; AllDevicesModel({ this.room, @@ -215,6 +218,28 @@ SOS return tempIcon; } + List get deviceFunctions { + _deviceFunctions ??= _getDeviceFunctions(); + return _deviceFunctions!; + } + + List _getDeviceFunctions() { + switch (productType) { + case 'AC': + return [ + SwitchFunction(deviceId: uuid ?? '', deviceName: name ?? ''), + ModeFunction(deviceId: uuid ?? '', deviceName: name ?? ''), + TempSetFunction(deviceId: uuid ?? '', deviceName: name ?? ''), + LevelFunction(deviceId: uuid ?? '', deviceName: name ?? ''), + ChildLockFunction(deviceId: uuid ?? '', deviceName: name ?? ''), + ]; + + // other product types + default: + return []; + } + } + Map toJson() { final data = {}; if (room != null) { diff --git a/lib/pages/routiens/bloc/routine_bloc.dart b/lib/pages/routiens/bloc/routine_bloc.dart index a7fd7228..dfbb824c 100644 --- a/lib/pages/routiens/bloc/routine_bloc.dart +++ b/lib/pages/routiens/bloc/routine_bloc.dart @@ -17,13 +17,21 @@ class RoutineBloc extends Bloc { } void _onAddToIfContainer(AddToIfContainer event, Emitter emit) { - final updatedIfItems = List>.from(state.ifItems)..add(event.item); - emit(state.copyWith(ifItems: updatedIfItems)); + if (!_isDuplicate(state.ifItems, event.item)) { + final updatedIfItems = List>.from(state.ifItems)..add(event.item); + emit(state.copyWith(ifItems: updatedIfItems)); + } } void _onAddToThenContainer(AddToThenContainer event, Emitter emit) { - final updatedThenItems = List>.from(state.thenItems)..add(event.item); - emit(state.copyWith(thenItems: updatedThenItems)); + if (!_isDuplicate(state.thenItems, event.item)) { + final updatedThenItems = List>.from(state.thenItems)..add(event.item); + emit(state.copyWith(thenItems: updatedThenItems)); + } + } + + bool _isDuplicate(List> items, Map newItem) { + return items.any((item) => item['imagePath'] == newItem['imagePath'] && item['title'] == newItem['title']); } Future _onLoadScenes(LoadScenes event, Emitter emit) async { diff --git a/lib/pages/routiens/bloc/routine_event.dart b/lib/pages/routiens/bloc/routine_event.dart index 6dcacf9c..aaee73c7 100644 --- a/lib/pages/routiens/bloc/routine_event.dart +++ b/lib/pages/routiens/bloc/routine_event.dart @@ -8,7 +8,7 @@ abstract class RoutineEvent extends Equatable { } class AddToIfContainer extends RoutineEvent { - final Map item; + final Map item; const AddToIfContainer(this.item); @@ -17,7 +17,7 @@ class AddToIfContainer extends RoutineEvent { } class AddToThenContainer extends RoutineEvent { - final Map item; + final Map item; const AddToThenContainer(this.item); diff --git a/lib/pages/routiens/bloc/routine_state.dart b/lib/pages/routiens/bloc/routine_state.dart index 8f715428..63d2e6f8 100644 --- a/lib/pages/routiens/bloc/routine_state.dart +++ b/lib/pages/routiens/bloc/routine_state.dart @@ -1,8 +1,8 @@ part of 'routine_bloc.dart'; class RoutineState extends Equatable { - final List> ifItems; - final List> thenItems; + final List> ifItems; + final List> thenItems; final List> availableCards; final List scenes; final List automations; @@ -20,8 +20,8 @@ class RoutineState extends Equatable { }); RoutineState copyWith({ - List>? ifItems, - List>? thenItems, + List>? ifItems, + List>? thenItems, List? scenes, List? automations, bool? isLoading, diff --git a/lib/pages/routiens/enum/ac_values_enum.dart b/lib/pages/routiens/enum/ac_values_enum.dart new file mode 100644 index 00000000..e7d0f865 --- /dev/null +++ b/lib/pages/routiens/enum/ac_values_enum.dart @@ -0,0 +1,9 @@ +enum AcValuesEnums { + Cooling, + Heating, + Ventilation, +} + +enum TempModes { hot, cold, wind } + +enum FanSpeeds { auto, low, middle, high } diff --git a/lib/pages/routiens/helper/ac_helper.dart b/lib/pages/routiens/helper/ac_helper.dart new file mode 100644 index 00000000..6cdb415d --- /dev/null +++ b/lib/pages/routiens/helper/ac_helper.dart @@ -0,0 +1,190 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; +import 'package:syncrow_web/pages/routiens/bloc/routine_bloc.dart'; +import 'package:syncrow_web/pages/routiens/models/ac/ac_function.dart'; +import 'package:syncrow_web/pages/routiens/models/device_functions.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; + +mixin ACHelper { + Future?> showACFunctionsDialog(BuildContext context, List> functions) { + List acFunctions = functions.whereType().toList(); + String? selectedFunction; + dynamic selectedValue; + + return showDialog( + context: context, + builder: (BuildContext context) { + return StatefulBuilder( + builder: (context, setState) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Container( + width: selectedFunction != null ? 600 : 360, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20), + ), + padding: const EdgeInsets.only(top: 20), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + 'AC Functions', + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: ColorsManager.primaryColorWithOpacity, + fontWeight: FontWeight.bold, + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 50), + child: Container( + height: 1, + width: double.infinity, + color: ColorsManager.greyColor, + ), + ), + Flexible( + child: Row( + children: [ + Expanded( + child: ListView.separated( + shrinkWrap: true, + itemCount: acFunctions.length, + separatorBuilder: (context, index) => Divider(), + itemBuilder: (context, index) { + final function = acFunctions[index]; + return ListTile( + leading: Image.asset(function.icon, width: 24, height: 24), + title: Text(function.operationName), + trailing: Icon(Icons.arrow_forward_ios), + onTap: () { + setState(() { + selectedFunction = function.code; + selectedValue = null; + }); + }, + ); + }, + ), + ), + if (selectedFunction != null) + Container( + width: 1, + color: ColorsManager.greyColor, + ), + if (selectedFunction != null) + Expanded( + child: ListView.separated( + shrinkWrap: true, + itemCount: acFunctions + .firstWhere((f) => f.code == selectedFunction) + .getOperationalValues() + .length, + separatorBuilder: (context, index) => Divider(), + itemBuilder: (context, index) { + final operationalValue = acFunctions.firstWhere((f) => f.code == selectedFunction) + ..getOperationalValues()[index]; + return ListTile( + leading: Image.asset(operationalValue.icon, width: 24, height: 24), + title: Text(operationalValue.getOperationalValues()[index].description), + trailing: Radio( + value: operationalValue.getOperationalValues()[index].value, + groupValue: selectedValue, + onChanged: (value) { + setState(() { + selectedValue = value; + }); + }, + ), + ); + }, + ), + ), + ], + ), + ), + Container( + height: 1, + width: double.infinity, + color: ColorsManager.greyColor, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Center( + child: Text( + 'Cancel', + style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: ColorsManager.greyColor), + ), + ), + ), + Container( + height: 50, + width: 1, + color: ColorsManager.greyColor, + ), + GestureDetector( + onTap: () { + // Handle the confirmation action here + Navigator.pop(context, { + 'function': selectedFunction, + 'value': selectedValue, + }); + }, + child: Center( + child: Text( + 'Confirm', + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: ColorsManager.primaryColorWithOpacity, + ), + ), + ), + ), + ], + ), + ], + ), + ), + ); + }, + ); + }, + ); + } + + void handleACDeviceDrop(BuildContext context, Map data) { + final device = data['device'] as AllDevicesModel; + final acFunctions = device.deviceFunctions; + + showACFunctionsDialog(context, acFunctions).then((result) { + if (result != null) { + _addACDeviceToRoutine(context, data, result); + } + }); + } + + void handleNonACDeviceDrop(BuildContext context, Map data) { + context.read().add(AddToThenContainer(data)); + } + + void _addACDeviceToRoutine(BuildContext context, Map deviceData, Map functionData) { + final updatedData = { + ...deviceData, + 'function': functionData['function'], + 'value': functionData['value'], + }; + + context.read().add(AddToThenContainer(updatedData)); + + _logACFunctionSelection(functionData); + } + + void _logACFunctionSelection(Map functionData) { + print('Selected AC function: ${functionData['function']}, Value: ${functionData['value']}'); + } +} diff --git a/lib/pages/routiens/models/ac/ac_function.dart b/lib/pages/routiens/models/ac/ac_function.dart new file mode 100644 index 00000000..3afe74c6 --- /dev/null +++ b/lib/pages/routiens/models/ac/ac_function.dart @@ -0,0 +1,215 @@ +import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart'; +import 'package:syncrow_web/pages/routiens/models/ac/ac_operational_value.dart'; +import 'package:syncrow_web/pages/routiens/models/device_functions.dart'; +import 'package:syncrow_web/utils/constants/assets.dart'; + +abstract class ACFunction extends DeviceFunction { + ACFunction({ + required String deviceId, + required String deviceName, + required String code, + required String operationName, + required String icon, + }) : super( + deviceId: deviceId, + deviceName: deviceName, + code: code, + operationName: operationName, + icon: icon, + ); + + @override + AcStatusModel execute(AcStatusModel currentStatus, dynamic newValue); + + List getOperationalValues(); +} + +class SwitchFunction extends ACFunction { + SwitchFunction({required super.deviceId, required super.deviceName}) + : super( + code: 'switch', + operationName: 'Power', + icon: Assets.assetsAcPower, + ); + + @override + AcStatusModel execute(AcStatusModel currentStatus, dynamic newValue) { + return currentStatus.copyWith(acSwitch: newValue as bool); + } + + @override + List getOperationalValues() => [ + ACOperationalValue( + icon: Assets.assetsAcPower, + description: "ON", + value: true, + ), + ACOperationalValue( + icon: Assets.assetsAcPowerOFF, + description: "OFF", + value: false, + ), + ]; +} + +class ModeFunction extends ACFunction { + ModeFunction({required super.deviceId, required super.deviceName}) + : super( + code: 'mode', + operationName: 'Mode', + icon: Assets.assetsFreezing, + ); + + @override + AcStatusModel execute(AcStatusModel currentStatus, dynamic newValue) { + return currentStatus.copyWith(modeString: (newValue as TempModes).toString().split('.').last); + } + + @override + List getOperationalValues() => [ + ACOperationalValue( + icon: Assets.assetsAcCooling, + description: "Cooling", + value: TempModes.cold, + ), + ACOperationalValue( + icon: Assets.assetsAcHeating, + description: "Heating", + value: TempModes.hot, + ), + ACOperationalValue( + icon: Assets.assetsFanSpeed, + description: "Ventilation", + value: TempModes.wind, + ), + ]; +} + +class TempSetFunction extends ACFunction { + final int min; + final int max; + final int step; + + TempSetFunction({required super.deviceId, required super.deviceName}) + : min = 200, + max = 300, + step = 5, + super( + code: 'temp_set', + operationName: 'Set Temperature', + icon: Assets.assetsTempreture, + ); + + @override + AcStatusModel execute(AcStatusModel currentStatus, dynamic newValue) { + return currentStatus.copyWith(tempSet: newValue as int); + } + + @override + List getOperationalValues() { + List values = []; + for (int temp = min; temp <= max; temp += step) { + values.add(ACOperationalValue( + icon: Assets.assetsTempreture, + description: "${temp / 10}°C", + value: temp, + )); + } + return values; + } +} + +class LevelFunction extends ACFunction { + LevelFunction({required super.deviceId, required super.deviceName}) + : super( + code: 'level', + operationName: 'Fan Speed', + icon: Assets.assetsFanSpeed, + ); + + @override + AcStatusModel execute(AcStatusModel currentStatus, dynamic newValue) { + return currentStatus.copyWith(fanSpeedsString: (newValue as FanSpeeds).toString().split('.').last); + } + + @override + List getOperationalValues() => [ + ACOperationalValue( + icon: Assets.assetsAcFanLow, + description: "LOW", + value: FanSpeeds.low, + ), + ACOperationalValue( + icon: Assets.assetsAcFanMiddle, + description: "MIDDLE", + value: FanSpeeds.middle, + ), + ACOperationalValue( + icon: Assets.assetsAcFanHigh, + description: "HIGH", + value: FanSpeeds.high, + ), + ACOperationalValue( + icon: Assets.assetsAcFanAuto, + description: "AUTO", + value: FanSpeeds.auto, + ), + ]; +} + +class ChildLockFunction extends ACFunction { + ChildLockFunction({required super.deviceId, required super.deviceName}) + : super( + code: 'child_lock', + operationName: 'Child Lock', + icon: Assets.assetsChildLock, + ); + + @override + AcStatusModel execute(AcStatusModel currentStatus, dynamic newValue) { + return currentStatus.copyWith(childLock: newValue as bool); + } + + @override + List getOperationalValues() => [ + ACOperationalValue( + icon: Assets.assetsSceneChildLock, + description: "Lock", + value: true, + ), + ACOperationalValue( + icon: Assets.assetsSceneChildUnlock, + description: "Unlock", + value: false, + ), + ]; +} + +/* + + final deviceId = 'AC001'; + final deviceName = 'Living Room AC'; + + // Initial AC status + var acStatus = AcStatusModel( + uuid: deviceId, + acSwitch: false, + modeString: 'cold', + tempSet: 220, + currentTemp: 250, + fanSpeedsString: 'auto', + childLock: false, + ); + + // Get all AC functions + final acFunctions = getACFunctions(deviceId, deviceName); + + // Example: Turn on the AC + final switchFunction = acFunctions.firstWhere((f) => f is SwitchFunction) as SwitchFunction; + acStatus = switchFunction.execute(acStatus, true); + + // Example: Change mode to heat + final modeFunction = acFunctions.firstWhere((f) => f is ModeFunction) as ModeFunction; + acStatus = modeFunction.execute(acStatus, TempModes.hot); + + */ diff --git a/lib/pages/routiens/models/ac/ac_operational_value.dart b/lib/pages/routiens/models/ac/ac_operational_value.dart new file mode 100644 index 00000000..4ca45d10 --- /dev/null +++ b/lib/pages/routiens/models/ac/ac_operational_value.dart @@ -0,0 +1,11 @@ +class ACOperationalValue { + final String icon; + final String description; + final dynamic value; + + ACOperationalValue({ + required this.icon, + required this.description, + required this.value, + }); +} diff --git a/lib/pages/routiens/models/device_functions.dart b/lib/pages/routiens/models/device_functions.dart new file mode 100644 index 00000000..fa6ac673 --- /dev/null +++ b/lib/pages/routiens/models/device_functions.dart @@ -0,0 +1,17 @@ +abstract class DeviceFunction { + final String deviceId; + final String deviceName; + final String code; + final String operationName; + final String icon; + + DeviceFunction({ + required this.deviceId, + required this.deviceName, + required this.code, + required this.operationName, + required this.icon, + }); + + T execute(T currentStatus, dynamic newValue); +} diff --git a/lib/pages/routiens/models/routine_item.dart b/lib/pages/routiens/models/routine_item.dart new file mode 100644 index 00000000..33920634 --- /dev/null +++ b/lib/pages/routiens/models/routine_item.dart @@ -0,0 +1,29 @@ +import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; + +class RoutineItem { + final AllDevicesModel device; + final String? function; + final dynamic value; + + RoutineItem({ + required this.device, + this.function, + this.value, + }); + + Map toMap() { + return { + 'device': device, + 'function': function, + 'value': value, + }; + } + + factory RoutineItem.fromMap(Map map) { + return RoutineItem( + device: map['device'] as AllDevicesModel, + function: map['function'], + value: map['value'], + ); + } +} diff --git a/lib/pages/routiens/widgets/dragable_card.dart b/lib/pages/routiens/widgets/dragable_card.dart index 7e98da28..2e7d1a0e 100644 --- a/lib/pages/routiens/widgets/dragable_card.dart +++ b/lib/pages/routiens/widgets/dragable_card.dart @@ -10,24 +10,32 @@ class DraggableCard extends StatelessWidget { required this.title, this.titleColor, this.isDragged = false, + this.isDisabled = false, }); final String imagePath; final String title; final Color? titleColor; final bool isDragged; + final bool isDisabled; @override Widget build(BuildContext context) { - return Draggable>( + Widget card = Draggable>( data: {'key': UniqueKey().toString(), 'imagePath': imagePath, 'title': title}, feedback: Transform.rotate( angle: -0.1, child: _buildCardContent(context), ), childWhenDragging: _buildGreyContainer(), - child: isDragged ? _buildGreyContainer() : _buildCardContent(context), + child: _buildCardContent(context), ); + + if (isDisabled) { + card = AbsorbPointer(child: card); + } + + return card; } Widget _buildCardContent(BuildContext context) { diff --git a/lib/pages/routiens/widgets/routine_devices.dart b/lib/pages/routiens/widgets/routine_devices.dart index 9fba225c..12d8492e 100644 --- a/lib/pages/routiens/widgets/routine_devices.dart +++ b/lib/pages/routiens/widgets/routine_devices.dart @@ -28,12 +28,14 @@ class RoutineDevices extends StatelessWidget { return Wrap( spacing: 10, runSpacing: 10, - children: deviceList - .map((device) => DraggableCard( - imagePath: device.getDefaultIcon(device.productType), - title: device.name ?? '', - )) - .toList(), + children: deviceList.asMap().entries.map((entry) { + final index = entry.key; + final device = entry.value; + return DraggableCard( + imagePath: device.getDefaultIcon(device.productType), + title: device.name ?? '', + ); + }).toList(), ); } return const Center(child: CircularProgressIndicator()); diff --git a/lib/pages/routiens/widgets/scenes_and_automations.dart b/lib/pages/routiens/widgets/scenes_and_automations.dart index 9819f0fe..7c90305b 100644 --- a/lib/pages/routiens/widgets/scenes_and_automations.dart +++ b/lib/pages/routiens/widgets/scenes_and_automations.dart @@ -26,12 +26,14 @@ class ScenesAndAutomations extends StatelessWidget { return Wrap( spacing: 10, runSpacing: 10, - children: scenes - .map((scene) => DraggableCard( - imagePath: Assets.logo, - title: scene.name ?? '', - )) - .toList(), + children: scenes.asMap().entries.map((entry) { + final index = entry.key; + final scene = entry.value; + return DraggableCard( + imagePath: Assets.logo, + title: scene.name ?? '', + ); + }).toList(), ); } return const Center(child: CircularProgressIndicator()); diff --git a/lib/utils/constants/assets.dart b/lib/utils/constants/assets.dart index 2c0c526f..6c542017 100644 --- a/lib/utils/constants/assets.dart +++ b/lib/utils/constants/assets.dart @@ -210,4 +210,59 @@ class Assets { //assets/icons/routine/delay.svg static const String delay = 'assets/icons/routine/delay.svg'; + + // Assets for functions_icons + static const String assetsSensitivityFunction = "assets/icons/functions_icons/sensitivity.svg"; + static const String assetsSensitivityOperationIcon = "assets/icons/functions_icons/sesitivity_operation_icon.svg"; + static const String assetsAcPower = "assets/icons/functions_icons/ac_power.svg"; + static const String assetsAcPowerOFF = "assets/icons/functions_icons/ac_power_off.svg"; + static const String assetsChildLock = "assets/icons/functions_icons/child_lock.svg"; + static const String assetsFreezing = "assets/icons/functions_icons/freezing.svg"; + static const String assetsFanSpeed = "assets/icons/functions_icons/fan_speed.svg"; + static const String assetsAcCooling = "assets/icons/functions_icons/ac_cooling.svg"; + static const String assetsAcHeating = "assets/icons/functions_icons/ac_heating.svg"; + static const String assetsCelsiusDegrees = "assets/icons/functions_icons/celsius_degrees.svg"; + static const String assetsTempreture = "assets/icons/functions_icons/tempreture.svg"; + static const String assetsAcFanLow = "assets/icons/functions_icons/ac_fan_low.svg"; + static const String assetsAcFanMiddle = "assets/icons/functions_icons/ac_fan_middle.svg"; + static const String assetsAcFanHigh = "assets/icons/functions_icons/ac_fan_high.svg"; + static const String assetsAcFanAuto = "assets/icons/functions_icons/ac_fan_auto.svg"; + static const String assetsSceneChildLock = "assets/icons/functions_icons/scene_child_lock.svg"; + static const String assetsSceneChildUnlock = "assets/icons/functions_icons/scene_child_unlock.svg"; + static const String assetsSceneRefresh = "assets/icons/functions_icons/scene_refresh.svg"; + static const String assetsLightCountdown = "assets/icons/functions_icons/light_countdown.svg"; + static const String assetsFarDetection = "assets/icons/functions_icons/far_detection.svg"; + static const String assetsFarDetectionFunction = "assets/icons/functions_icons/far_detection_function.svg"; + static const String assetsIndicator = "assets/icons/functions_icons/indicator.svg"; + static const String assetsMotionDetection = "assets/icons/functions_icons/motion_detection.svg"; + static const String assetsMotionlessDetection = "assets/icons/functions_icons/motionless_detection.svg"; + static const String assetsNobodyTime = "assets/icons/functions_icons/nobody_time.svg"; + static const String assetsFactoryReset = "assets/icons/functions_icons/factory_reset.svg"; + static const String assetsMasterState = "assets/icons/functions_icons/master_state.svg"; + static const String assetsSwitchAlarmSound = "assets/icons/functions_icons/switch_alarm_sound.svg"; + static const String assetsResetOff = "assets/icons/functions_icons/reset_off.svg"; + +// Assets for automation_functions + static const String assetsCardUnlock = "assets/icons/functions_icons/automation_functions/card_unlock.svg"; + static const String assetsDoorbell = "assets/icons/functions_icons/automation_functions/doorbell.svg"; + static const String assetsDoorlockNormalOpen = + "assets/icons/functions_icons/automation_functions/doorlock_normal_open.svg"; + static const String assetsDoubleLock = "assets/icons/functions_icons/automation_functions/double_lock.svg"; + static const String assetsFingerprintUnlock = + "assets/icons/functions_icons/automation_functions/fingerprint_unlock.svg"; + static const String assetsHijackAlarm = "assets/icons/functions_icons/automation_functions/hijack_alarm.svg"; + static const String assetsLockAlarm = "assets/icons/functions_icons/automation_functions/lock_alarm.svg"; + static const String assetsPasswordUnlock = "assets/icons/functions_icons/automation_functions/password_unlock.svg"; + static const String assetsRemoteUnlockReq = "assets/icons/functions_icons/automation_functions/remote_unlock_req.svg"; + static const String assetsRemoteUnlockViaApp = + "assets/icons/functions_icons/automation_functions/remote_unlock_via_app.svg"; + static const String assetsResidualElectricity = + "assets/icons/functions_icons/automation_functions/residual_electricity.svg"; + static const String assetsTempPasswordUnlock = + "assets/icons/functions_icons/automation_functions/temp_password_unlock.svg"; + static const String assetsSelfTestResult = "assets/icons/functions_icons/automation_functions/self_test_result.svg"; + static const String assetsPresence = "assets/icons/functions_icons/automation_functions/presence.svg"; + static const String assetsMotion = "assets/icons/functions_icons/automation_functions/motion.svg"; + static const String assetsCurrentTemp = "assets/icons/functions_icons/automation_functions/current_temp.svg"; + static const String assetsPresenceState = "assets/icons/functions_icons/automation_functions/presence_state.svg"; }