diff --git a/lib/features/scene/bloc/effective_period/effect_period_bloc.dart b/lib/features/scene/bloc/effective_period/effect_period_bloc.dart index 551c06b..9b20627 100644 --- a/lib/features/scene/bloc/effective_period/effect_period_bloc.dart +++ b/lib/features/scene/bloc/effective_period/effect_period_bloc.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:bloc/bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart'; import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_event.dart'; diff --git a/lib/features/scene/helper/scene_logic_helper.dart b/lib/features/scene/helper/scene_logic_helper.dart index c2f50b6..3219ba2 100644 --- a/lib/features/scene/helper/scene_logic_helper.dart +++ b/lib/features/scene/helper/scene_logic_helper.dart @@ -34,6 +34,7 @@ mixin SceneLogicHelper { required List conditions, }) { final sceneBloc = context.read(); + final effectiveTime = sceneBloc.effectiveTime; if (isOnlyDelayOrDelayLast(actions)) { context.showCustomSnackbar( @@ -46,6 +47,17 @@ mixin SceneLogicHelper { return; } + if (isAutomation == true && effectiveTime?.loops == '0000000') { + context.showCustomSnackbar( + message: 'At least one day in Effective Period must be selected!', + icon: const Icon( + Icons.error, + color: Colors.red, + ), + ); + return; + } + if (isAutomation) { final createAutomationModel = CreateAutomationModel( unitUuid: HomeCubit.getInstance().selectedSpace!.id ?? '', @@ -81,7 +93,7 @@ mixin SceneLogicHelper { executorProperty: CreateSceneExecutorProperty( functionCode: '', functionValue: '', - delaySeconds: task.functionValue, + delaySeconds: task.functionValue ?? 1, ), ); } @@ -159,21 +171,24 @@ mixin SceneLogicHelper { } } - Widget getTheCorrectDialogBody(SceneStaticFunction taskItem, dynamic functionValue, + Widget getTheCorrectDialogBody( + SceneStaticFunction taskItem, dynamic functionValue, {required bool isAutomation}) { if (taskItem.operationDialogType == OperationDialogType.temperature) { return AlertDialogTemperatureBody( taskItem: taskItem, functionValue: functionValue ?? taskItem.functionValue, ); - } else if ((taskItem.operationDialogType == OperationDialogType.countdown) || + } else if ((taskItem.operationDialogType == + OperationDialogType.countdown) || (taskItem.operationDialogType == OperationDialogType.delay)) { return AlertDialogCountdown( durationValue: taskItem.functionValue ?? 0, functionValue: functionValue ?? taskItem.functionValue, function: taskItem, ); - } else if (taskItem.operationDialogType == OperationDialogType.integerSteps) { + } else if (taskItem.operationDialogType == + OperationDialogType.integerSteps) { return AlertDialogSliderSteps( taskItem: taskItem, functionValue: functionValue ?? taskItem.functionValue, diff --git a/lib/features/scene/view/scene_auto_settings.dart b/lib/features/scene/view/scene_auto_settings.dart index d73d268..af9db38 100644 --- a/lib/features/scene/view/scene_auto_settings.dart +++ b/lib/features/scene/view/scene_auto_settings.dart @@ -15,10 +15,12 @@ class SceneAutoSettings extends StatelessWidget { @override Widget build(BuildContext context) { - final sceneSettings = ModalRoute.of(context)!.settings.arguments as Map? ?? {}; + final sceneSettings = + ModalRoute.of(context)!.settings.arguments as Map? ?? + {}; final sceneId = sceneSettings['sceneId'] as String? ?? ''; - final isAutomation = - context.read().sceneType == CreateSceneEnum.deviceStatusChanges; + final isAutomation = context.read().sceneType == + CreateSceneEnum.deviceStatusChanges; final sceneName = sceneSettings['sceneName'] as String? ?? ''; return DefaultScaffold( @@ -48,9 +50,11 @@ class SceneAutoSettings extends StatelessWidget { Visibility( visible: isAutomation, child: SceneListTile( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + padding: const EdgeInsets.symmetric( + horizontal: 16, vertical: 8), titleString: "Effective Period", - trailingWidget: const Icon(Icons.arrow_forward_ios_rounded), + trailingWidget: + const Icon(Icons.arrow_forward_ios_rounded), onPressed: () { context.customBottomSheet( child: const EffectPeriodBottomSheetContent(), diff --git a/lib/features/scene/widgets/alert_dialogs/alert_dialog_slider_steps.dart b/lib/features/scene/widgets/alert_dialogs/alert_dialog_slider_steps.dart index 0447e8a..3503e46 100644 --- a/lib/features/scene/widgets/alert_dialogs/alert_dialog_slider_steps.dart +++ b/lib/features/scene/widgets/alert_dialogs/alert_dialog_slider_steps.dart @@ -48,12 +48,21 @@ class _AlertDialogSliderStepsState extends State { } } } - - if (widget.functionValue != null) { - groupValue = _normalizeValue(widget.functionValue); + if (widget.taskItem.code == 'temp_current') { + if (widget.functionValue != null) { + groupValue = _normalizeValue( + double.tryParse(widget.functionValue.toString()) ?? + widget.taskItem.operationalValues[0].minValue); + } else { + groupValue = widget.taskItem.operationalValues[0].minValue; + } } else { - groupValue = - _normalizeValue(widget.taskItem.operationalValues[0].minValue); + if (widget.functionValue != null) { + groupValue = _normalizeValue(widget.functionValue); + } else { + groupValue = + _normalizeValue(widget.taskItem.operationalValues[0].minValue); + } } setState(() {}); @@ -68,14 +77,6 @@ class _AlertDialogSliderStepsState extends State { ); } - double _normalizeValue(dynamic value) { - if (((widget.taskItem.code == "temp_set" && value > 199) || - widget.taskItem.code == "temp_current")) { - return (value) / 10; - } - return value.toDouble(); - } - int _comparatorToIndex(String? comparator) { switch (comparator) { case "<": @@ -216,7 +217,7 @@ class _AlertDialogSliderStepsState extends State { : null, onChanged: (value) { setState(() { - groupValue = normalizeValue(value); + groupValue = normalizeToDoubleValue(value); }); context.read().add(SelectedValueEvent( value: _deNormalizeValue(groupValue), @@ -237,8 +238,16 @@ class _AlertDialogSliderStepsState extends State { ); } - double normalizeValue(double value) { - return double.parse(value.toStringAsFixed(1)); + double _normalizeValue(dynamic value) { + if ((widget.taskItem.code == "temp_set" && value > 199) || + (widget.taskItem.code == "temp_current" && value >= -99.0)) { + return (value) / 10; + } + return value.toDouble(); + } + + double? normalizeToDoubleValue(double value) { + return double.tryParse(value.toStringAsFixed(1)); } double _deNormalizeValue(double? value) { diff --git a/lib/features/scene/widgets/alert_dialogs/alert_dialog_temperature_body.dart b/lib/features/scene/widgets/alert_dialogs/alert_dialog_temperature_body.dart index 7a5429b..7e80b48 100644 --- a/lib/features/scene/widgets/alert_dialogs/alert_dialog_temperature_body.dart +++ b/lib/features/scene/widgets/alert_dialogs/alert_dialog_temperature_body.dart @@ -50,10 +50,10 @@ class _AlertDialogTemperatureBodyState }); } - // context.read().add(SelectedValueEvent( - // value: temperature * 10, - // code: widget.taskItem.code, - // )); + context.read().add(SelectedValueEvent( + value: temperature * 10, + code: widget.taskItem.code, + )); } int _normalizeTemperature(dynamic value) { diff --git a/lib/features/scene/widgets/effective_period_setting/effective_period_bottom_sheet.dart b/lib/features/scene/widgets/effective_period_setting/effective_period_bottom_sheet.dart index 68f829e..784fb4b 100644 --- a/lib/features/scene/widgets/effective_period_setting/effective_period_bottom_sheet.dart +++ b/lib/features/scene/widgets/effective_period_setting/effective_period_bottom_sheet.dart @@ -19,18 +19,8 @@ class EffectPeriodBottomSheetContent extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - // Expanded( - // child: TextButton( - // onPressed: () => Navigator.pop(context), - // child: BodySmall( - // text: 'Save', - // style: - // context.bodySmall.copyWith(color: ColorsManager.primaryColorWithOpacity), - // )), - // ), const Spacer(), Expanded( - // flex: 2, child: BodyMedium( text: 'Effective Period', fontColor: ColorsManager.primaryColorWithOpacity, diff --git a/lib/features/scene/widgets/effective_period_setting/repeat_days.dart b/lib/features/scene/widgets/effective_period_setting/repeat_days.dart index 9f40165..d3e24d5 100644 --- a/lib/features/scene/widgets/effective_period_setting/repeat_days.dart +++ b/lib/features/scene/widgets/effective_period_setting/repeat_days.dart @@ -4,6 +4,9 @@ import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_b import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_event.dart'; import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_state.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/utils/context_extension.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class RepeatDays extends StatelessWidget { const RepeatDays({super.key}); @@ -27,44 +30,63 @@ class RepeatDays extends StatelessWidget { const SizedBox(width: 8), BlocBuilder( builder: (context, state) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: daysMap.entries.map((entry) { - final day = entry.key; - final abbreviation = entry.value; - final dayIndex = _getDayIndex(day); - final isSelected = state.selectedDaysBinary[dayIndex] == '1'; - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 3.0), - child: GestureDetector( - onTap: () { - context.read().add(ToggleDay(day)); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: - isSelected ? Colors.grey : Colors.grey.shade300, - width: 1, - ), - ), - child: CircleAvatar( - radius: 15, - backgroundColor: Colors.white, - child: Text( - abbreviation, - style: TextStyle( - fontSize: 16, - color: - isSelected ? Colors.grey : Colors.grey.shade300, + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: daysMap.entries.map((entry) { + final day = entry.key; + final abbreviation = entry.value; + final dayIndex = _getDayIndex(day); + final isSelected = + state.selectedDaysBinary[dayIndex] == '1'; + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 3.0), + child: GestureDetector( + onTap: () { + context.read().add(ToggleDay(day)); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: isSelected + ? Colors.grey + : Colors.grey.shade300, + width: 1, + ), + ), + child: CircleAvatar( + radius: 15, + backgroundColor: Colors.white, + child: Text( + abbreviation, + style: TextStyle( + fontSize: 16, + color: isSelected + ? Colors.grey + : Colors.grey.shade300, + ), + ), ), ), ), - ), + ); + }).toList(), + ), + const SizedBox( + height: 8, + ), + if (state.selectedDaysBinary == '0000000') + BodySmall( + text: 'At least one day must be selected', + style: + context.bodyMedium.copyWith(color: ColorsManager.red), ), - ); - }).toList(), + ], ); }, ),