From 50b455b4ae3ce8b0b7f62467cc1f5dc9097448ce Mon Sep 17 00:00:00 2001 From: ashrafzarkanisala Date: Sun, 28 Jul 2024 05:04:57 +0300 Subject: [PATCH] push dialog changes in values --- .../bloc/create_scene/create_scene_bloc.dart | 1 + .../smart_scene_select_dart_bloc.dart | 30 ++ .../smart_scene_select_dart_event.dart | 21 ++ .../smart_scene_select_dart_state.dart | 19 ++ .../scene/helper/scene_logic_helper.dart | 14 +- .../scene/model/create_scene_model.dart | 5 +- .../scene/model/smart_scene_enable.dart | 23 ++ .../scene/view/device_functions_view.dart | 44 ++- .../view/smart_automation_select_route.dart | 70 +++++ .../scene/widgets/bottom_sheet_widget.dart | 4 +- .../smart_automation_list.dart | 260 ++++++++++++++++++ .../smart_enable_autoamtion.dart | 39 +++ .../smart_enable_tab_run.dart | 36 +++ .../smart_tab_run_list.dart | 92 +++++++ .../shared_widgets/default_scaffold.dart | 7 +- lib/my_app.dart | 2 + lib/navigation/router.dart | 7 + lib/navigation/routing_constants.dart | 4 +- 18 files changed, 645 insertions(+), 33 deletions(-) create mode 100644 lib/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart create mode 100644 lib/features/scene/bloc/smart_scene/smart_scene_select_dart_event.dart create mode 100644 lib/features/scene/bloc/smart_scene/smart_scene_select_dart_state.dart create mode 100644 lib/features/scene/model/smart_scene_enable.dart create mode 100644 lib/features/scene/view/smart_automation_select_route.dart create mode 100644 lib/features/scene/widgets/select_smart_scene/smart_automation_list.dart create mode 100644 lib/features/scene/widgets/select_smart_scene/smart_enable_autoamtion.dart create mode 100644 lib/features/scene/widgets/select_smart_scene/smart_enable_tab_run.dart create mode 100644 lib/features/scene/widgets/select_smart_scene/smart_tab_run_list.dart 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 0a19efb..60bfc17 100644 --- a/lib/features/scene/bloc/create_scene/create_scene_bloc.dart +++ b/lib/features/scene/bloc/create_scene/create_scene_bloc.dart @@ -315,6 +315,7 @@ class CreateSceneBloc extends Bloc automationTempTasksList.clear(); automationSelectedValues.clear(); automationComparatorValues.clear(); + effectiveTime = null; sceneType = CreateSceneEnum.none; conditionRule = 'or'; emit(const CreateSceneWithTasks(success: true)); diff --git a/lib/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart b/lib/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart new file mode 100644 index 0000000..daf9e75 --- /dev/null +++ b/lib/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart @@ -0,0 +1,30 @@ +import 'dart:async'; + +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/features/scene/model/smart_scene_enable.dart'; + +part 'smart_scene_select_dart_event.dart'; +part 'smart_scene_select_dart_state.dart'; + +class SmartSceneSelectBloc + extends Bloc { + SmartSceneSelectBloc() : super(SmartSceneSelectInitial()) { + on(_onSmartSceneEnable); + on(_smartSceneClear); + } + + SmartSceneEnable? smartSceneEnable; + + FutureOr _onSmartSceneEnable( + SmartSceneEnableEvent event, Emitter emit) { + smartSceneEnable = event.smartSceneEnable; + emit(SmartSceneSelected(smartSceneEnable: smartSceneEnable!)); + } + + FutureOr _smartSceneClear( + SmartSceneClearEvent event, Emitter emit) { + smartSceneEnable = null; + emit(SmartSceneSelectInitial()); + } +} \ No newline at end of file diff --git a/lib/features/scene/bloc/smart_scene/smart_scene_select_dart_event.dart b/lib/features/scene/bloc/smart_scene/smart_scene_select_dart_event.dart new file mode 100644 index 0000000..ecdf30a --- /dev/null +++ b/lib/features/scene/bloc/smart_scene/smart_scene_select_dart_event.dart @@ -0,0 +1,21 @@ +part of 'smart_scene_select_dart_bloc.dart'; + +sealed class SmartSceneSelectEvent extends Equatable { + const SmartSceneSelectEvent(); + + @override + List get props => []; +} + +class SmartSceneEnableEvent extends SmartSceneSelectEvent { + final SmartSceneEnable smartSceneEnable; + + const SmartSceneEnableEvent(this.smartSceneEnable); + + @override + List get props => [smartSceneEnable]; +} + +class SmartSceneClearEvent extends SmartSceneSelectEvent { + const SmartSceneClearEvent(); +} diff --git a/lib/features/scene/bloc/smart_scene/smart_scene_select_dart_state.dart b/lib/features/scene/bloc/smart_scene/smart_scene_select_dart_state.dart new file mode 100644 index 0000000..d29b748 --- /dev/null +++ b/lib/features/scene/bloc/smart_scene/smart_scene_select_dart_state.dart @@ -0,0 +1,19 @@ +part of 'smart_scene_select_dart_bloc.dart'; + +sealed class SmartSceneSelectState extends Equatable { + const SmartSceneSelectState(); + + @override + List get props => []; +} + +final class SmartSceneSelectInitial extends SmartSceneSelectState {} + +class SmartSceneSelected extends SmartSceneSelectState { + final SmartSceneEnable smartSceneEnable; + + const SmartSceneSelected({required this.smartSceneEnable}); + + @override + List get props => [smartSceneEnable]; +} diff --git a/lib/features/scene/helper/scene_logic_helper.dart b/lib/features/scene/helper/scene_logic_helper.dart index 5fbe39c..328e089 100644 --- a/lib/features/scene/helper/scene_logic_helper.dart +++ b/lib/features/scene/helper/scene_logic_helper.dart @@ -2,6 +2,7 @@ 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/scene/bloc/create_scene/create_scene_bloc.dart'; +import 'package:syncrow_app/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart'; import 'package:syncrow_app/features/scene/enum/operation_dialog_type.dart'; import 'package:syncrow_app/features/scene/model/create_automation_model.dart'; import 'package:syncrow_app/features/scene/model/create_scene_model.dart'; @@ -29,6 +30,7 @@ mixin SceneLogicHelper { required List conditions, }) { final sceneBloc = context.read(); + final smartSceneBloc = context.read(); if (isAutomation) { // Handle Automation Creation @@ -89,7 +91,11 @@ mixin SceneLogicHelper { ), ); }, - ), + )..add(CreateSceneAction( + entityId: smartSceneBloc.smartSceneEnable?.entityId ?? '', + actionExecutor: + smartSceneBloc.smartSceneEnable?.actionExecutor ?? '', + executorProperty: null)), ); sceneBloc.add(CreateSceneWithTasksEvent( createSceneModel: null, @@ -140,7 +146,11 @@ mixin SceneLogicHelper { ), ); }, - ), + )..add(CreateSceneAction( + entityId: smartSceneBloc.smartSceneEnable?.entityId ?? '', + actionExecutor: + smartSceneBloc.smartSceneEnable?.actionExecutor ?? '', + executorProperty: null)), ); sceneBloc.add(CreateSceneWithTasksEvent( createSceneModel: createSceneModel, diff --git a/lib/features/scene/model/create_scene_model.dart b/lib/features/scene/model/create_scene_model.dart index ca7919a..0d19345 100644 --- a/lib/features/scene/model/create_scene_model.dart +++ b/lib/features/scene/model/create_scene_model.dart @@ -81,7 +81,7 @@ class CreateSceneModel { class CreateSceneAction { String entityId; String actionExecutor; - CreateSceneExecutorProperty executorProperty; + CreateSceneExecutorProperty? executorProperty; CreateSceneAction({ required this.entityId, @@ -105,7 +105,8 @@ class CreateSceneAction { return { 'entityId': entityId, 'actionExecutor': actionExecutor, - 'executorProperty': executorProperty.toMap(actionExecutor), + if (executorProperty != null) + 'executorProperty': executorProperty?.toMap(actionExecutor), }; } diff --git a/lib/features/scene/model/smart_scene_enable.dart b/lib/features/scene/model/smart_scene_enable.dart new file mode 100644 index 0000000..c855925 --- /dev/null +++ b/lib/features/scene/model/smart_scene_enable.dart @@ -0,0 +1,23 @@ +class SmartSceneEnable { + final String entityId; + final String actionExecutor; + + SmartSceneEnable({ + required this.entityId, + required this.actionExecutor, + }); + + factory SmartSceneEnable.fromJson(Map json) { + return SmartSceneEnable( + entityId: json['entityId'], + actionExecutor: json['actionExecutor'], + ); + } + + Map toJson() { + return { + 'entityId': entityId, + 'actionExecutor': actionExecutor, + }; + } +} diff --git a/lib/features/scene/view/device_functions_view.dart b/lib/features/scene/view/device_functions_view.dart index ddb9090..bb9c48f 100644 --- a/lib/features/scene/view/device_functions_view.dart +++ b/lib/features/scene/view/device_functions_view.dart @@ -65,32 +65,28 @@ class DeviceFunctionsView extends StatelessWidget ], leading: TextButton( onPressed: () { - // if (isAutomation) { - final automationSelectedValue = - context.read().automationSelectedValues; - for (var element in device.functions) { - if (automationSelectedValue.containsKey(element.code)) { - context.read().add(RemoveTempTaskByIdEvent( - code: element.code!, isAutomation: true)); - context.read().add( - RemoveFromSelectedValueById( - code: element.code!, isAutomation: true)); - } + final automationSelectedValue = + context.read().automationSelectedValues; + for (var element in device.functions) { + if (automationSelectedValue.containsKey(element.code)) { + context.read().add(RemoveTempTaskByIdEvent( + code: element.code!, isAutomation: true)); + context.read().add(RemoveFromSelectedValueById( + code: element.code!, isAutomation: true)); } - // } else { - final selectedValue = - context.read().selectedValues; - for (var element in device.functions) { - if (selectedValue.containsKey(element.code)) { - context - .read() - .add(RemoveTempTaskByIdEvent(code: element.code!)); - context - .read() - .add(RemoveFromSelectedValueById(code: element.code!)); - } + } + final selectedValue = + context.read().selectedValues; + for (var element in device.functions) { + if (selectedValue.containsKey(element.code)) { + context + .read() + .add(RemoveTempTaskByIdEvent(code: element.code!)); + context + .read() + .add(RemoveFromSelectedValueById(code: element.code!)); } - // } + } Navigator.pop(context); }, diff --git a/lib/features/scene/view/smart_automation_select_route.dart b/lib/features/scene/view/smart_automation_select_route.dart new file mode 100644 index 0000000..6b059ef --- /dev/null +++ b/lib/features/scene/view/smart_automation_select_route.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart'; +import 'package:syncrow_app/features/scene/widgets/select_smart_scene/smart_enable_autoamtion.dart'; +import 'package:syncrow_app/features/scene/widgets/select_smart_scene/smart_enable_tab_run.dart'; +import 'package:syncrow_app/features/shared_widgets/default_container.dart'; +import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/navigation/navigate_to_route.dart'; +import 'package:syncrow_app/navigation/routing_constants.dart'; +import 'package:syncrow_app/utils/context_extension.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SmartAutomationSelectView extends StatelessWidget { + const SmartAutomationSelectView({super.key}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: "Select Smart Scene", + padding: const EdgeInsets.only(top: 24), + leading: IconButton( + onPressed: () { + navigateToRoute(context, Routes.sceneTasksRoute); + }, + icon: const Icon( + Icons.arrow_back_ios, + )), + height: 260, + child: DefaultContainer( + width: double.infinity, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SceneListTile( + assetPath: Assets.handClickIcon, + titleString: "Tap To Run", + subtitleString: '', + trailingWidget: const Icon( + Icons.arrow_forward_ios_rounded, + color: ColorsManager.greyColor, + ), + onPressed: () { + context.customBottomSheet( + child: const SmartEnableTabRun(), + ); + }, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SceneListTile( + assetPath: Assets.refreshIcon, + titleString: "Automation", + subtitleString: '', + trailingWidget: const Icon( + Icons.arrow_forward_ios_rounded, + color: ColorsManager.greyColor, + ), + onPressed: () { + context.customBottomSheet( + child: const SmartEnableAutomation(), + ); + }, + ), + ], + ), + ), + ); + } +} diff --git a/lib/features/scene/widgets/bottom_sheet_widget.dart b/lib/features/scene/widgets/bottom_sheet_widget.dart index 0efea4d..518ef86 100644 --- a/lib/features/scene/widgets/bottom_sheet_widget.dart +++ b/lib/features/scene/widgets/bottom_sheet_widget.dart @@ -67,7 +67,9 @@ class CustomBottomSheetWidget extends StatelessWidget { size: 16, color: ColorsManager.greyColor, ), - onPressed: () {}, + onPressed: () { + Navigator.pushNamed(context, Routes.smartAutomationSelectRoute); + }, ), SceneListTile( assetPath: Assets.delay, diff --git a/lib/features/scene/widgets/select_smart_scene/smart_automation_list.dart b/lib/features/scene/widgets/select_smart_scene/smart_automation_list.dart new file mode 100644 index 0000000..962645f --- /dev/null +++ b/lib/features/scene/widgets/select_smart_scene/smart_automation_list.dart @@ -0,0 +1,260 @@ +import 'dart:math'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart'; +import 'package:syncrow_app/features/scene/model/scene_static_function.dart'; +import 'package:syncrow_app/features/scene/model/scenes_model.dart'; +import 'package:syncrow_app/features/scene/model/smart_scene_enable.dart'; +import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/context_extension.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SmartSceneSelectAutomationList extends StatefulWidget { + const SmartSceneSelectAutomationList({ + super.key, + required this.automationList, + }); + + final List automationList; + + @override + State createState() => + _SmartSceneSelectAutomationListState(); +} + +class _SmartSceneSelectAutomationListState + extends State { + final List colorList = _generateDarkColors(100); + + static List _generateDarkColors(int count) { + final random = Random(); + final colors = []; + + while (colors.length < count) { + final color = + Color((random.nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0); + if (_isDark(color)) { + colors.add(color); + } + } + return colors; + } + + static bool _isDark(Color color) { + final brightness = + ((color.red * 299) + (color.green * 587) + (color.blue * 114)) / 1000; + return brightness < 128; + } + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: BodyMedium( + text: 'Automation', + style: context.bodyMedium.copyWith( + color: ColorsManager.primaryColorWithOpacity, + fontWeight: FontWeight.bold), + ), + ), + const Divider( + color: ColorsManager.dividerColor, + ), + Expanded( + child: BlocBuilder( + builder: (context, state) { + final smartSceneEnable = ((state is SmartSceneSelected)) + ? state.smartSceneEnable + : context.read().smartSceneEnable; + + return ListView.builder( + shrinkWrap: true, + itemCount: widget.automationList.length, + itemBuilder: (context, index) { + final automation = widget.automationList[index]; + final isSelected = + smartSceneEnable?.entityId == automation.id; + final descriptionSelected = isSelected + ? (smartSceneEnable?.actionExecutor == 'rule_enable' + ? 'Enable' + : 'Disable') + : automation.status == 'enable' + ? 'Enable' + : 'Disable'; + + return SceneListTile( + padding: const EdgeInsets.symmetric(horizontal: 10), + leadingWidget: CircleAvatar( + backgroundColor: colorList[index % colorList.length], + radius: 15, + child: Text( + index.toString(), + style: context.bodyMedium.copyWith(color: Colors.white), + ), + ), + titleString: automation.name, + trailingWidget: TextButton.icon( + iconAlignment: IconAlignment.end, + onPressed: () { + context.customAlertDialog( + alertBody: EnableDisableAutomationDialog( + automationId: automation.id, + descriptionSelected: descriptionSelected, + ), + title: automation.name, + onConfirm: () { + Navigator.pop(context); + }, + onDismiss: () { + context + .read() + .add(const SmartSceneClearEvent()); + Navigator.pop(context); + }, + ); + }, + label: BodyMedium( + text: _capitalizeFirst(descriptionSelected), + style: context.bodyMedium + .copyWith(color: ColorsManager.greyColor), + ), + icon: const Icon( + Icons.arrow_forward_ios_rounded, + color: ColorsManager.greyColor, + size: 14, + ), + style: const ButtonStyle( + padding: WidgetStatePropertyAll(EdgeInsets.zero), + ), + ), + onPressed: () { + context.customAlertDialog( + alertBody: EnableDisableAutomationDialog( + automationId: automation.id, + descriptionSelected: descriptionSelected, + ), + title: automation.name, + onConfirm: () { + Navigator.pop(context); + }, + onDismiss: () { + context + .read() + .add(const SmartSceneClearEvent()); + Navigator.pop(context); + }, + ); + }, + ); + }, + ); + }, + ), + ), + ], + ); + } + + String _capitalizeFirst(String description) { + if (description.isEmpty) return description; + return '${description[0].toUpperCase()}${description.substring(1)}'; + } +} + +class EnableDisableAutomationDialog extends StatefulWidget { + const EnableDisableAutomationDialog({ + super.key, + required this.automationId, + required this.descriptionSelected, + }); + + final String automationId; + final String descriptionSelected; + + @override + State createState() => + _EnableDisableAutomationDialogState(); +} + +class _EnableDisableAutomationDialogState + extends State { + String? groupValue; + final List values = [ + SceneOperationalValue( + icon: Assets.assetsAcPower, + description: 'Enable', + value: 'rule_enable', + ), + SceneOperationalValue( + icon: Assets.assetsAcPowerOFF, + description: 'Disable', + value: 'rule_disable', + ), + ]; + + @override + void initState() { + super.initState(); + groupValue = + widget.descriptionSelected == 'Enable' ? 'rule_enable' : 'rule_disable'; + } + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + ...values.map( + (operation) => SceneListTile( + iconsSize: 25, + minLeadingWidth: 15, + padding: const EdgeInsets.symmetric(horizontal: 16), + assetPath: operation.icon, + assetHeaderValue: operation.iconValue, + titleString: operation.description.toString(), + textAlign: TextAlign.start, + trailingWidget: Radio( + value: operation.value, + groupValue: groupValue, + onChanged: (value) { + setState(() { + groupValue = value; + }); + context + .read() + .add(SmartSceneEnableEvent( + SmartSceneEnable( + entityId: widget.automationId, + actionExecutor: value!, + ), + )); + }, + ), + onPressed: () { + setState(() { + groupValue = operation.value; + }); + context + .read() + .add(SmartSceneEnableEvent( + SmartSceneEnable( + entityId: widget.automationId, + actionExecutor: operation.value, + ), + )); + }, + ), + ), + ], + ); + }, + ); + } +} diff --git a/lib/features/scene/widgets/select_smart_scene/smart_enable_autoamtion.dart b/lib/features/scene/widgets/select_smart_scene/smart_enable_autoamtion.dart new file mode 100644 index 0000000..d4684f5 --- /dev/null +++ b/lib/features/scene/widgets/select_smart_scene/smart_enable_autoamtion.dart @@ -0,0 +1,39 @@ +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/scene/bloc/scene_bloc/scene_bloc.dart'; +import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_event.dart'; + +import 'package:syncrow_app/features/scene/widgets/select_smart_scene/smart_automation_list.dart'; +import 'package:syncrow_app/features/shared_widgets/default_container.dart'; + +import 'package:syncrow_app/utils/context_extension.dart'; + +class SmartEnableAutomation extends StatelessWidget { + const SmartEnableAutomation({super.key}); + + @override + Widget build(BuildContext context) { + return DefaultContainer( + height: context.height * 0.5, + width: double.infinity, + child: BlocBuilder( + bloc: context.read() + ..add( + LoadAutomation(HomeCubit.getInstance().selectedSpace?.id ?? '')), + builder: (context, state) { + if (state is SceneLoading) { + return const Align( + alignment: Alignment.topCenter, + child: LinearProgressIndicator()); + } + if (state is SceneLoaded) { + return SmartSceneSelectAutomationList( + automationList: state.automationList); + } + return const SizedBox.shrink(); + }, + ), + ); + } +} 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 new file mode 100644 index 0000000..37a5e7c --- /dev/null +++ b/lib/features/scene/widgets/select_smart_scene/smart_enable_tab_run.dart @@ -0,0 +1,36 @@ +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/scene/bloc/scene_bloc/scene_bloc.dart'; +import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_event.dart'; +import 'package:syncrow_app/features/scene/widgets/select_smart_scene/smart_tab_run_list.dart'; +import 'package:syncrow_app/features/shared_widgets/default_container.dart'; +import 'package:syncrow_app/utils/context_extension.dart'; + +class SmartEnableTabRun extends StatelessWidget { + const SmartEnableTabRun({super.key}); + + @override + Widget build(BuildContext context) { + return DefaultContainer( + height: context.height * 0.5, + width: double.infinity, + child: BlocBuilder( + bloc: context.read() + ..add(LoadScenes(HomeCubit.getInstance().selectedSpace?.id ?? '')), + builder: (context, state) { + if (state is SceneLoading) { + return const Align( + alignment: Alignment.topCenter, + child: LinearProgressIndicator()); + } + if (state is SceneLoaded) { + return SmartSceneSelectTabToRunList(scenes: state.scenes); + } + return const SizedBox.shrink(); + }, + ), + ); + } +} + diff --git a/lib/features/scene/widgets/select_smart_scene/smart_tab_run_list.dart b/lib/features/scene/widgets/select_smart_scene/smart_tab_run_list.dart new file mode 100644 index 0000000..6fbae23 --- /dev/null +++ b/lib/features/scene/widgets/select_smart_scene/smart_tab_run_list.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart'; +import 'package:syncrow_app/features/scene/model/scenes_model.dart'; +import 'package:syncrow_app/features/scene/model/smart_scene_enable.dart'; +import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/context_extension.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SmartSceneSelectTabToRunList extends StatefulWidget { + const SmartSceneSelectTabToRunList({ + super.key, + required this.scenes, + }); + final List scenes; + + @override + State createState() => + _SmartSceneSelectTabToRunListState(); +} + +class _SmartSceneSelectTabToRunListState + extends State { + String groupValue = ''; + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: BodyMedium( + text: 'Tab To Run', + style: context.bodyMedium.copyWith( + color: ColorsManager.primaryColorWithOpacity, + fontWeight: FontWeight.bold), + ), + ), + const Divider( + color: ColorsManager.dividerColor, + ), + Expanded( + child: ListView.builder( + shrinkWrap: true, + itemCount: widget.scenes.length, + itemBuilder: (context, index) { + final scene = widget.scenes[index]; + return SceneListTile( + padding: const EdgeInsets.symmetric(horizontal: 10), + leadingWidget: Image.asset( + height: 32, + width: 32, + Assets.assetsIconsLogo, + fit: BoxFit.fill, + ), + titleString: scene.name, + trailingWidget: Radio( + value: scene.id, + groupValue: groupValue, + onChanged: (String? value) { + if (value != null) { + setState(() { + groupValue = value; + }); + context + .read() + .add(SmartSceneEnableEvent(SmartSceneEnable( + entityId: scene.id, + actionExecutor: 'rule_enable', + ))); + } + }), + onPressed: () { + setState(() { + groupValue = scene.id; + }); + context + .read() + .add(SmartSceneEnableEvent(SmartSceneEnable( + entityId: scene.id, + actionExecutor: 'rule_enable', + ))); + }, + ); + }), + ), + ], + ); + } +} diff --git a/lib/features/shared_widgets/default_scaffold.dart b/lib/features/shared_widgets/default_scaffold.dart index 080fbef..a88e828 100644 --- a/lib/features/shared_widgets/default_scaffold.dart +++ b/lib/features/shared_widgets/default_scaffold.dart @@ -17,6 +17,7 @@ class DefaultScaffold extends StatelessWidget { this.padding, this.leading, this.leadingWidth, + this.height, }); final Widget child; @@ -27,6 +28,7 @@ class DefaultScaffold extends StatelessWidget { final EdgeInsetsGeometry? padding; final Widget? leading; final double? leadingWidth; + final double? height; @override Widget build(BuildContext context) { return AnnotatedRegion( @@ -54,8 +56,9 @@ class DefaultScaffold extends StatelessWidget { ), body: Container( width: MediaQuery.sizeOf(context).width, - height: MediaQuery.sizeOf(context).height, - padding: padding ?? const EdgeInsets.symmetric(horizontal: Constants.defaultPadding), + height: height ?? MediaQuery.sizeOf(context).height, + padding: padding ?? + const EdgeInsets.symmetric(horizontal: Constants.defaultPadding), decoration: const BoxDecoration( image: DecorationImage( image: AssetImage( diff --git a/lib/my_app.dart b/lib/my_app.dart index a49fec7..0a253bf 100644 --- a/lib/my_app.dart +++ b/lib/my_app.dart @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart'; import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_bloc.dart'; import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart'; +import 'package:syncrow_app/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart'; import 'package:syncrow_app/navigation/navigation_service.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; @@ -28,6 +29,7 @@ class MyApp extends StatelessWidget { BlocProvider(create: (context) => CreateSceneBloc()), BlocProvider(create: (context) => SceneBloc()), BlocProvider(create: (context) => ProfileBloc()), + BlocProvider(create: (context) => SmartSceneSelectBloc()), ], child: MaterialApp( diff --git a/lib/navigation/router.dart b/lib/navigation/router.dart index 8bc2839..990b7fb 100644 --- a/lib/navigation/router.dart +++ b/lib/navigation/router.dart @@ -18,6 +18,7 @@ import 'package:syncrow_app/features/scene/view/scene_auto_settings.dart'; import 'package:syncrow_app/features/scene/view/scene_tasks_view.dart'; import 'package:syncrow_app/features/scene/view/scene_rooms_tabbar.dart'; import 'package:syncrow_app/features/scene/view/scene_view.dart'; +import 'package:syncrow_app/features/scene/view/smart_automation_select_route.dart'; import 'package:syncrow_app/features/splash/view/splash_view.dart'; import 'routing_constants.dart'; @@ -101,6 +102,12 @@ class Router { builder: (_) => const SceneAutoSettings(), settings: settings, ); + + case Routes.smartAutomationSelectRoute: + return MaterialPageRoute( + builder: (_) => const SmartAutomationSelectView(), + settings: settings, + ); default: return MaterialPageRoute( builder: (_) => Scaffold( diff --git a/lib/navigation/routing_constants.dart b/lib/navigation/routing_constants.dart index 1d2d363..b64849f 100644 --- a/lib/navigation/routing_constants.dart +++ b/lib/navigation/routing_constants.dart @@ -20,6 +20,6 @@ class Routes { static const String sceneTasksRoute = '/scene-tasks'; static const String sceneControlDevicesRoute = '/scene-control-devices'; static const String deviceFunctionsRoute = '/device-functions'; - static const String sceneAutoSettingsRoute = - '/scene-automation-settings'; + static const String sceneAutoSettingsRoute = '/scene-automation-settings'; + static const String smartAutomationSelectRoute = '/smart-automation-select'; }