From 2c684a94953d9076f7ad0c1d82a6f8051b215351 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 23 Apr 2025 16:58:50 +0300 Subject: [PATCH 1/2] SP-1441 rework. --- .../widgets/routine_dialogs/ac_dialog.dart | 29 +++++++++-- .../ceiling_sensor/ceiling_sensor_dialog.dart | 6 ++- .../ceiling_sensor/cps_functions_list.dart | 40 ++++++++++++--- .../one_gang_switch_dialog.dart | 50 ++++++++++++++----- .../three_gang_switch_dialog.dart | 43 ++++++++++------ .../two_gang_switch_dialog.dart | 45 ++++++++++------- .../wall_sensor/wall_presence_sensor.dart | 43 +++++++++++++--- 7 files changed, 192 insertions(+), 64 deletions(-) diff --git a/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart index 68cf857d..11bedf24 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart @@ -74,11 +74,33 @@ class ACHelper { child: _buildFunctionsList( context: context, acFunctions: acFunctions, - onFunctionSelected: (functionCode, operationName) => - context.read().add(SelectFunction( + device: device, + onFunctionSelected: (functionCode, operationName) { + context.read().add( + SelectFunction( functionCode: functionCode, operationName: operationName, - )), + ), + ); + if (functionCode == 'temp_set' || + functionCode == 'temp_current') { + context.read().add( + AddFunction( + functionData: DeviceFunctionData( + entityId: device?.uuid ?? '', + functionCode: functionCode, + operationName: operationName, + value: functionCode == 'temp_set' + ? 200 + : -100, + condition: '==', + valueDescription: selectedFunctionData + .valueDescription, + ), + ), + ); + } + }, ), ), // Value selector @@ -137,6 +159,7 @@ class ACHelper { required BuildContext context, required List acFunctions, required Function(String, String) onFunctionSelected, + required AllDevicesModel? device, }) { return ListView.separated( shrinkWrap: false, diff --git a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_dialog.dart index c18706f0..4e174265 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_dialog.dart @@ -131,7 +131,11 @@ class _CeilingSensorDialogState extends State { return Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - CpsFunctionsList(cpsFunctions: _cpsFunctions), + CpsFunctionsList( + cpsFunctions: _cpsFunctions, + device: widget.device, + selectedFunctionData: selectedFunctionData, + ), if (state.selectedFunction != null) Expanded( child: isToggleFunction diff --git a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart index 2a35428a..707246c4 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart @@ -1,14 +1,24 @@ 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/routines/bloc/functions_bloc/functions_bloc_bloc.dart'; import 'package:syncrow_web/pages/routines/models/ceiling_presence_sensor_functions.dart'; +import 'package:syncrow_web/pages/routines/models/device_functions.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialog_function_list_tile.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class CpsFunctionsList extends StatelessWidget { - const CpsFunctionsList({required this.cpsFunctions, super.key}); + const CpsFunctionsList({ + required this.cpsFunctions, + required this.device, + required this.selectedFunctionData, + super.key, + }); final List cpsFunctions; + final AllDevicesModel? device; + final DeviceFunctionData? selectedFunctionData; @override Widget build(BuildContext context) { @@ -26,12 +36,28 @@ class CpsFunctionsList extends StatelessWidget { return RoutineDialogFunctionListTile( iconPath: function.icon, operationName: function.operationName, - onTap: () => context.read().add( - SelectFunction( - functionCode: function.code, - operationName: function.operationName, - ), - ), + onTap: () { + context.read().add( + SelectFunction( + functionCode: function.code, + operationName: function.operationName, + ), + ); + if (!CeilingSensorHelper.toggleCodes.contains(function.code)) { + context.read().add( + AddFunction( + functionData: DeviceFunctionData( + entityId: device?.uuid ?? '', + functionCode: function.code, + operationName: function.operationName, + value: 0, + condition: '==', + valueDescription: selectedFunctionData?.valueDescription, + ), + ), + ); + } + }, ); }, ), diff --git a/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart index 51a99f3b..a2d6d8db 100644 --- a/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart @@ -24,21 +24,23 @@ class OneGangSwitchHelper { required String uniqueCustomId, required bool removeComparetors, }) async { - List oneGangFunctions = functions.whereType().toList(); + List oneGangFunctions = + functions.whereType().toList(); return showDialog?>( context: context, builder: (BuildContext context) { return BlocProvider( - create: (_) => FunctionBloc()..add(InitializeFunctions(deviceSelectedFunctions ?? [])), + create: (_) => FunctionBloc() + ..add(InitializeFunctions(deviceSelectedFunctions ?? [])), child: AlertDialog( contentPadding: EdgeInsets.zero, content: BlocBuilder( builder: (context, state) { final selectedFunction = state.selectedFunction; final selectedOperationName = state.selectedOperationName; - final selectedFunctionData = - state.addedFunctions.firstWhere((f) => f.functionCode == selectedFunction, + final selectedFunctionData = state.addedFunctions + .firstWhere((f) => f.functionCode == selectedFunction, orElse: () => DeviceFunctionData( entityId: '', functionCode: selectedFunction ?? '', @@ -85,10 +87,29 @@ class OneGangSwitchHelper { color: ColorsManager.textGray, ), onTap: () { - context.read().add(SelectFunction( + context + .read() + .add(SelectFunction( functionCode: function.code, operationName: function.operationName, )); + if (function.code == 'countdown_1') { + context.read().add( + AddFunction( + functionData: DeviceFunctionData( + entityId: device?.uuid ?? '', + functionCode: function.code, + operationName: + function.operationName, + value: 0, + condition: '==', + valueDescription: + selectedFunctionData + .valueDescription, + ), + ), + ); + } }, ); }, @@ -220,11 +241,11 @@ class OneGangSwitchHelper { selectedFunctionData, ), const SizedBox(height: 20), - _buildCountDownDisplay( - context, initialValue, device, operationName, selectedFunctionData, selectCode), + _buildCountDownDisplay(context, initialValue, device, operationName, + selectedFunctionData, selectCode), const SizedBox(height: 20), - _buildCountDownSlider( - context, initialValue, device, operationName, selectedFunctionData, selectCode), + _buildCountDownSlider(context, initialValue, device, operationName, + selectedFunctionData, selectCode), ], ); } @@ -314,9 +335,10 @@ class OneGangSwitchHelper { value: (initialValue ?? 0).toDouble(), min: operationalValues.minValue?.toDouble() ?? 0.0, max: operationalValues.maxValue?.toDouble() ?? 0.0, - divisions: (((operationalValues.maxValue ?? 0) - (operationalValues.minValue ?? 0)) / - (operationalValues.stepValue ?? 1)) - .round(), + divisions: + (((operationalValues.maxValue ?? 0) - (operationalValues.minValue ?? 0)) / + (operationalValues.stepValue ?? 1)) + .round(), onChanged: (value) { context.read().add( AddFunction( @@ -368,7 +390,9 @@ class OneGangSwitchHelper { trailing: Icon( isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked, size: 24, - color: isSelected ? ColorsManager.primaryColorWithOpacity : ColorsManager.textGray, + color: isSelected + ? ColorsManager.primaryColorWithOpacity + : ColorsManager.textGray, ), onTap: () { if (!isSelected) { diff --git a/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart index a83fc4a0..fdc2cb98 100644 --- a/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart @@ -90,9 +90,27 @@ class ThreeGangSwitchHelper { .read() .add(SelectFunction( functionCode: function.code, - operationName: - function.operationName, + operationName: function.operationName, )); + if (function.code == 'countdown_1' || + function.code == 'countdown_2' || + function.code == 'countdown_3') { + context.read().add( + AddFunction( + functionData: DeviceFunctionData( + entityId: device?.uuid ?? '', + functionCode: function.code, + operationName: + function.operationName, + value: 0, + condition: '==', + valueDescription: + selectedFunctionData + .valueDescription, + ), + ), + ); + } }, ); }, @@ -183,8 +201,7 @@ class ThreeGangSwitchHelper { ); } - final selectedFn = - switchFunctions.firstWhere((f) => f.code == selectedFunction); + final selectedFn = switchFunctions.firstWhere((f) => f.code == selectedFunction); final values = selectedFn.getOperationalValues(); return _buildOperationalValuesList( @@ -266,8 +283,7 @@ class ThreeGangSwitchHelper { minHeight: 40.0, minWidth: 40.0, ), - isSelected: - conditions.map((c) => c == (currentCondition ?? "==")).toList(), + isSelected: conditions.map((c) => c == (currentCondition ?? "==")).toList(), children: conditions.map((c) => Text(c)).toList(), ); } @@ -316,10 +332,10 @@ class ThreeGangSwitchHelper { value: (initialValue ?? 0).toDouble(), min: operationalValues.minValue?.toDouble() ?? 0.0, max: operationalValues.maxValue?.toDouble() ?? 0.0, - divisions: (((operationalValues.maxValue ?? 0) - - (operationalValues.minValue ?? 0)) / - (operationalValues.stepValue ?? 1)) - .round(), + divisions: + (((operationalValues.maxValue ?? 0) - (operationalValues.minValue ?? 0)) / + (operationalValues.stepValue ?? 1)) + .round(), onChanged: (value) { context.read().add( AddFunction( @@ -369,9 +385,7 @@ class ThreeGangSwitchHelper { style: context.textTheme.bodyMedium, ), trailing: Icon( - isSelected - ? Icons.radio_button_checked - : Icons.radio_button_unchecked, + isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked, size: 24, color: isSelected ? ColorsManager.primaryColorWithOpacity @@ -387,8 +401,7 @@ class ThreeGangSwitchHelper { operationName: operationName, value: value.value, condition: selectedFunctionData?.condition, - valueDescription: - selectedFunctionData?.valueDescription, + valueDescription: selectedFunctionData?.valueDescription, ), ), ); diff --git a/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart index 2bb6b6e5..14e9f4a7 100644 --- a/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart @@ -90,9 +90,26 @@ class TwoGangSwitchHelper { .read() .add(SelectFunction( functionCode: function.code, - operationName: - function.operationName, + operationName: function.operationName, )); + if (function.code == 'countdown_1' || + function.code == 'countdown_2') { + context.read().add( + AddFunction( + functionData: DeviceFunctionData( + entityId: device?.uuid ?? '', + functionCode: function.code, + operationName: + function.operationName, + value: 0, + condition: '==', + valueDescription: + selectedFunctionData + .valueDescription, + ), + ), + ); + } }, ); }, @@ -167,8 +184,7 @@ class TwoGangSwitchHelper { required String operationName, required bool removeComparetors, }) { - if (selectedFunction == 'countdown_1' || - selectedFunction == 'countdown_2') { + if (selectedFunction == 'countdown_1' || selectedFunction == 'countdown_2') { final initialValue = selectedFunctionData?.value ?? 0; return _buildTemperatureSelector( context: context, @@ -182,8 +198,7 @@ class TwoGangSwitchHelper { ); } - final selectedFn = - switchFunctions.firstWhere((f) => f.code == selectedFunction); + final selectedFn = switchFunctions.firstWhere((f) => f.code == selectedFunction); final values = selectedFn.getOperationalValues(); return _buildOperationalValuesList( @@ -265,8 +280,7 @@ class TwoGangSwitchHelper { minHeight: 40.0, minWidth: 40.0, ), - isSelected: - conditions.map((c) => c == (currentCondition ?? "==")).toList(), + isSelected: conditions.map((c) => c == (currentCondition ?? "==")).toList(), children: conditions.map((c) => Text(c)).toList(), ); } @@ -315,10 +329,10 @@ class TwoGangSwitchHelper { value: (initialValue ?? 0).toDouble(), min: operationalValues.minValue?.toDouble() ?? 0.0, max: operationalValues.maxValue?.toDouble() ?? 0.0, - divisions: (((operationalValues.maxValue ?? 0) - - (operationalValues.minValue ?? 0)) / - (operationalValues.stepValue ?? 1)) - .round(), + divisions: + (((operationalValues.maxValue ?? 0) - (operationalValues.minValue ?? 0)) / + (operationalValues.stepValue ?? 1)) + .round(), onChanged: (value) { context.read().add( AddFunction( @@ -368,9 +382,7 @@ class TwoGangSwitchHelper { style: context.textTheme.bodyMedium, ), trailing: Icon( - isSelected - ? Icons.radio_button_checked - : Icons.radio_button_unchecked, + isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked, size: 24, color: isSelected ? ColorsManager.primaryColorWithOpacity @@ -386,8 +398,7 @@ class TwoGangSwitchHelper { operationName: operationName, value: value.value, condition: selectedFunctionData?.condition, - valueDescription: - selectedFunctionData?.valueDescription, + valueDescription: selectedFunctionData?.valueDescription, ), ), ); diff --git a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart index 91abb34e..44f1efcc 100644 --- a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart +++ b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart @@ -111,13 +111,23 @@ class _WallPresenceSensorState extends State { return Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - _buildFunctionList(context), + _buildFunctionList(context, state), if (state.selectedFunction != null) _buildValueSelector(context, state), ], ); } - Widget _buildFunctionList(BuildContext context) { + Widget _buildFunctionList(BuildContext context, FunctionBlocState state) { + final selectedFunction = state.selectedFunction; + final selectedFunctionData = state.addedFunctions.firstWhere( + (f) => f.functionCode == selectedFunction, + orElse: () => DeviceFunctionData( + entityId: '', + functionCode: selectedFunction ?? '', + operationName: '', + value: null, + ), + ); return SizedBox( width: 360, child: ListView.separated( @@ -149,12 +159,29 @@ class _WallPresenceSensorState extends State { size: 16, color: ColorsManager.textGray, ), - onTap: () => context.read().add( - SelectFunction( - functionCode: function.code, - operationName: function.operationName, - ), - ), + onTap: () { + context.read().add( + SelectFunction( + functionCode: function.code, + operationName: function.operationName, + ), + ); + if (['dis_current', 'presence_time', 'illuminance_value'] + .contains(function.code)) { + context.read().add( + AddFunction( + functionData: DeviceFunctionData( + entityId: widget.device?.uuid ?? '', + functionCode: function.code, + operationName: function.operationName, + value: 0, + condition: '==', + valueDescription: selectedFunctionData.valueDescription, + ), + ), + ); + } + }, ); }, ), From c03b8f290c4ac7799e0e84519c133e8bd6b23f75 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 24 Apr 2025 10:25:41 +0300 Subject: [PATCH 2/2] refactor function tap handlers to use `RoutineTapFunctionHelper` for improved code reuse and readability, and to remove code duplication. --- .../widgets/routine_dialogs/ac_dialog.dart | 42 +++++++-------- .../ceiling_sensor/ceiling_sensor_dialog.dart | 1 + .../ceiling_sensor/cps_functions_list.dart | 53 +++++++++---------- .../helpers/routine_tap_function_helper.dart | 46 ++++++++++++++++ .../one_gang_switch_dialog.dart | 39 +++++--------- .../three_gang_switch_dialog.dart | 43 ++++++--------- .../two_gang_switch_dialog.dart | 41 ++++++-------- .../wall_sensor/wall_presence_sensor.dart | 36 +++++-------- 8 files changed, 149 insertions(+), 152 deletions(-) create mode 100644 lib/pages/routines/widgets/routine_dialogs/helpers/routine_tap_function_helper.dart diff --git a/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart index 11bedf24..1de9b0d4 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart @@ -9,6 +9,7 @@ import 'package:syncrow_web/pages/routines/models/ac/ac_operational_value.dart'; import 'package:syncrow_web/pages/routines/models/device_functions.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/helpers/routine_tap_function_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; @@ -76,30 +77,23 @@ class ACHelper { acFunctions: acFunctions, device: device, onFunctionSelected: (functionCode, operationName) { - context.read().add( - SelectFunction( - functionCode: functionCode, - operationName: operationName, - ), - ); - if (functionCode == 'temp_set' || - functionCode == 'temp_current') { - context.read().add( - AddFunction( - functionData: DeviceFunctionData( - entityId: device?.uuid ?? '', - functionCode: functionCode, - operationName: operationName, - value: functionCode == 'temp_set' - ? 200 - : -100, - condition: '==', - valueDescription: selectedFunctionData - .valueDescription, - ), - ), - ); - } + RoutineTapFunctionHelper.onTapFunction( + context, + functionCode: functionCode, + functionOperationName: operationName, + functionValueDescription: + selectedFunctionData.valueDescription, + deviceUuid: device?.uuid, + codesToAddIntoFunctionsWithDefaultValue: [ + 'temp_set', + 'temp_current', + ], + defaultValue: functionCode == 'temp_set' + ? 200 + : functionCode == 'temp_current' + ? -100 + : 0, + ); }, ), ), diff --git a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_dialog.dart index 4e174265..f3d07a66 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_dialog.dart @@ -135,6 +135,7 @@ class _CeilingSensorDialogState extends State { cpsFunctions: _cpsFunctions, device: widget.device, selectedFunctionData: selectedFunctionData, + dialogType: widget.dialogType, ), if (state.selectedFunction != null) Expanded( diff --git a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart index 707246c4..efc57653 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart @@ -1,24 +1,24 @@ 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/routines/bloc/functions_bloc/functions_bloc_bloc.dart'; import 'package:syncrow_web/pages/routines/models/ceiling_presence_sensor_functions.dart'; import 'package:syncrow_web/pages/routines/models/device_functions.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialog_function_list_tile.dart'; -import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_helper.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/helpers/routine_tap_function_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class CpsFunctionsList extends StatelessWidget { const CpsFunctionsList({ required this.cpsFunctions, - required this.device, - required this.selectedFunctionData, + required this.device, + required this.selectedFunctionData, + required this.dialogType, super.key, }); final List cpsFunctions; final AllDevicesModel? device; final DeviceFunctionData? selectedFunctionData; + final String dialogType; @override Widget build(BuildContext context) { @@ -36,28 +36,27 @@ class CpsFunctionsList extends StatelessWidget { return RoutineDialogFunctionListTile( iconPath: function.icon, operationName: function.operationName, - onTap: () { - context.read().add( - SelectFunction( - functionCode: function.code, - operationName: function.operationName, - ), - ); - if (!CeilingSensorHelper.toggleCodes.contains(function.code)) { - context.read().add( - AddFunction( - functionData: DeviceFunctionData( - entityId: device?.uuid ?? '', - functionCode: function.code, - operationName: function.operationName, - value: 0, - condition: '==', - valueDescription: selectedFunctionData?.valueDescription, - ), - ), - ); - } - }, + onTap: () => RoutineTapFunctionHelper.onTapFunction( + context, + functionCode: function.code, + functionOperationName: function.operationName, + functionValueDescription: selectedFunctionData?.valueDescription, + deviceUuid: device?.uuid, + codesToAddIntoFunctionsWithDefaultValue: [ + 'static_max_dis', + 'presence_reference', + 'moving_reference', + 'perceptual_boundary', + 'moving_boundary', + 'moving_rigger_time', + 'moving_static_time', + 'none_body_time', + 'moving_max_dis', + 'moving_range', + 'presence_range', + if (dialogType == "IF") 'sensitivity', + ], + ), ); }, ), diff --git a/lib/pages/routines/widgets/routine_dialogs/helpers/routine_tap_function_helper.dart b/lib/pages/routines/widgets/routine_dialogs/helpers/routine_tap_function_helper.dart new file mode 100644 index 00000000..2b09f579 --- /dev/null +++ b/lib/pages/routines/widgets/routine_dialogs/helpers/routine_tap_function_helper.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart'; +import 'package:syncrow_web/pages/routines/models/device_functions.dart'; + +abstract final class RoutineTapFunctionHelper { + const RoutineTapFunctionHelper._(); + + static void onTapFunction( + BuildContext context, { + required String functionCode, + required String functionOperationName, + required String? functionValueDescription, + required String? deviceUuid, + required List codesToAddIntoFunctionsWithDefaultValue, + int defaultValue = 0, + }) { + final functionsBloc = context.read(); + functionsBloc.add( + SelectFunction( + functionCode: functionCode, + operationName: functionOperationName, + ), + ); + final addedFunctions = functionsBloc.state.addedFunctions; + final isFunctionAlreadyAdded = addedFunctions.any( + (e) => e.functionCode == functionCode, + ); + final shouldAddFunction = + codesToAddIntoFunctionsWithDefaultValue.contains(functionCode); + if (!isFunctionAlreadyAdded && shouldAddFunction) { + context.read().add( + AddFunction( + functionData: DeviceFunctionData( + entityId: deviceUuid ?? '', + functionCode: functionCode, + operationName: functionOperationName, + value: defaultValue, + condition: '==', + valueDescription: functionValueDescription, + ), + ), + ); + } + } +} diff --git a/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart index a2d6d8db..3c786045 100644 --- a/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart @@ -11,6 +11,7 @@ import 'package:syncrow_web/pages/routines/models/gang_switches/one_gang_switch/ import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/helpers/routine_tap_function_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; @@ -86,31 +87,19 @@ class OneGangSwitchHelper { size: 16, color: ColorsManager.textGray, ), - onTap: () { - context - .read() - .add(SelectFunction( - functionCode: function.code, - operationName: function.operationName, - )); - if (function.code == 'countdown_1') { - context.read().add( - AddFunction( - functionData: DeviceFunctionData( - entityId: device?.uuid ?? '', - functionCode: function.code, - operationName: - function.operationName, - value: 0, - condition: '==', - valueDescription: - selectedFunctionData - .valueDescription, - ), - ), - ); - } - }, + onTap: () => + RoutineTapFunctionHelper.onTapFunction( + context, + functionCode: function.code, + functionOperationName: + function.operationName, + functionValueDescription: + selectedFunctionData.valueDescription, + deviceUuid: device?.uuid, + codesToAddIntoFunctionsWithDefaultValue: [ + 'countdown_1', + ], + ), ); }, ), diff --git a/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart index fdc2cb98..44a367ef 100644 --- a/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart @@ -10,6 +10,7 @@ import 'package:syncrow_web/pages/routines/models/gang_switches/base_switch_func import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/helpers/routine_tap_function_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; @@ -85,33 +86,21 @@ class ThreeGangSwitchHelper { size: 16, color: ColorsManager.textGray, ), - onTap: () { - context - .read() - .add(SelectFunction( - functionCode: function.code, - operationName: function.operationName, - )); - if (function.code == 'countdown_1' || - function.code == 'countdown_2' || - function.code == 'countdown_3') { - context.read().add( - AddFunction( - functionData: DeviceFunctionData( - entityId: device?.uuid ?? '', - functionCode: function.code, - operationName: - function.operationName, - value: 0, - condition: '==', - valueDescription: - selectedFunctionData - .valueDescription, - ), - ), - ); - } - }, + onTap: () => + RoutineTapFunctionHelper.onTapFunction( + context, + functionCode: function.code, + functionOperationName: + function.operationName, + functionValueDescription: + selectedFunctionData.valueDescription, + deviceUuid: device?.uuid, + codesToAddIntoFunctionsWithDefaultValue: [ + 'countdown_1', + 'countdown_2', + 'countdown_3', + ], + ), ); }, ), diff --git a/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart index 14e9f4a7..f551d21b 100644 --- a/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart @@ -10,6 +10,7 @@ import 'package:syncrow_web/pages/routines/models/gang_switches/base_switch_func import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/helpers/routine_tap_function_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; @@ -85,32 +86,20 @@ class TwoGangSwitchHelper { size: 16, color: ColorsManager.textGray, ), - onTap: () { - context - .read() - .add(SelectFunction( - functionCode: function.code, - operationName: function.operationName, - )); - if (function.code == 'countdown_1' || - function.code == 'countdown_2') { - context.read().add( - AddFunction( - functionData: DeviceFunctionData( - entityId: device?.uuid ?? '', - functionCode: function.code, - operationName: - function.operationName, - value: 0, - condition: '==', - valueDescription: - selectedFunctionData - .valueDescription, - ), - ), - ); - } - }, + onTap: () => + RoutineTapFunctionHelper.onTapFunction( + context, + functionCode: function.code, + functionOperationName: + function.operationName, + functionValueDescription: + selectedFunctionData.valueDescription, + deviceUuid: device?.uuid, + codesToAddIntoFunctionsWithDefaultValue: [ + 'countdown_1', + 'countdown_2', + ], + ), ); }, ), diff --git a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart index 44f1efcc..4d04102d 100644 --- a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart +++ b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart @@ -8,6 +8,7 @@ import 'package:syncrow_web/pages/routines/models/device_functions.dart'; import 'package:syncrow_web/pages/routines/models/wps/wps_functions.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/helpers/routine_tap_function_helper.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/wall_sensor/wps_value_selector_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; @@ -159,29 +160,18 @@ class _WallPresenceSensorState extends State { size: 16, color: ColorsManager.textGray, ), - onTap: () { - context.read().add( - SelectFunction( - functionCode: function.code, - operationName: function.operationName, - ), - ); - if (['dis_current', 'presence_time', 'illuminance_value'] - .contains(function.code)) { - context.read().add( - AddFunction( - functionData: DeviceFunctionData( - entityId: widget.device?.uuid ?? '', - functionCode: function.code, - operationName: function.operationName, - value: 0, - condition: '==', - valueDescription: selectedFunctionData.valueDescription, - ), - ), - ); - } - }, + onTap: () => RoutineTapFunctionHelper.onTapFunction( + context, + functionCode: function.code, + functionOperationName: function.operationName, + functionValueDescription: selectedFunctionData.valueDescription, + deviceUuid: widget.device?.uuid, + codesToAddIntoFunctionsWithDefaultValue: [ + 'dis_current', + 'presence_time', + 'illuminance_value', + ], + ), ); }, ),