mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
working on automation
This commit is contained in:
@ -14,8 +14,8 @@ part 'routine_state.dart';
|
|||||||
const spaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
|
const spaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
|
||||||
|
|
||||||
class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||||
bool isAutomation = false;
|
// bool isAutomation = false;
|
||||||
bool isTabToRun = false;
|
// bool isTabToRun = false;
|
||||||
|
|
||||||
RoutineBloc() : super(const RoutineState()) {
|
RoutineBloc() : super(const RoutineState()) {
|
||||||
on<AddToIfContainer>(_onAddToIfContainer);
|
on<AddToIfContainer>(_onAddToIfContainer);
|
||||||
@ -27,28 +27,32 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
on<AddSelectedIcon>(_onAddSelectedIcon);
|
on<AddSelectedIcon>(_onAddSelectedIcon);
|
||||||
on<CreateSceneEvent>(_onCreateScene);
|
on<CreateSceneEvent>(_onCreateScene);
|
||||||
on<RemoveDragCard>(_onRemoveDragCard);
|
on<RemoveDragCard>(_onRemoveDragCard);
|
||||||
|
on<ChangeAutomationOperator>(_changeOperatorOperator);
|
||||||
// on<RemoveFunction>(_onRemoveFunction);
|
// on<RemoveFunction>(_onRemoveFunction);
|
||||||
// on<ClearFunctions>(_onClearFunctions);
|
// on<ClearFunctions>(_onClearFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onAddToIfContainer(AddToIfContainer event, Emitter<RoutineState> emit) {
|
void _onAddToIfContainer(AddToIfContainer event, Emitter<RoutineState> emit) {
|
||||||
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems)..add(event.item);
|
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems)
|
||||||
|
..add(event.item);
|
||||||
if (event.isTabToRun) {
|
if (event.isTabToRun) {
|
||||||
isTabToRun = true;
|
emit(state.copyWith(
|
||||||
isAutomation = false;
|
ifItems: updatedIfItems, isTabToRun: true, isAutomation: false));
|
||||||
} else {
|
} else {
|
||||||
isTabToRun = false;
|
emit(state.copyWith(
|
||||||
isAutomation = true;
|
ifItems: updatedIfItems, isTabToRun: false, isAutomation: true));
|
||||||
}
|
}
|
||||||
emit(state.copyWith(ifItems: updatedIfItems));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onAddToThenContainer(AddToThenContainer event, Emitter<RoutineState> emit) {
|
void _onAddToThenContainer(
|
||||||
final updatedThenItems = List<Map<String, dynamic>>.from(state.thenItems)..add(event.item);
|
AddToThenContainer event, Emitter<RoutineState> emit) {
|
||||||
|
final updatedThenItems = List<Map<String, dynamic>>.from(state.thenItems)
|
||||||
|
..add(event.item);
|
||||||
emit(state.copyWith(thenItems: updatedThenItems));
|
emit(state.copyWith(thenItems: updatedThenItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onAddFunctionsToRoutine(AddFunctionToRoutine event, Emitter<RoutineState> emit) {
|
void _onAddFunctionsToRoutine(
|
||||||
|
AddFunctionToRoutine event, Emitter<RoutineState> emit) {
|
||||||
try {
|
try {
|
||||||
if (event.functions.isEmpty) return;
|
if (event.functions.isEmpty) return;
|
||||||
|
|
||||||
@ -57,9 +61,11 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
|
|
||||||
if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) {
|
if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) {
|
||||||
currentSelectedFunctions[event.uniqueCustomId] =
|
currentSelectedFunctions[event.uniqueCustomId] =
|
||||||
List.from(currentSelectedFunctions[event.uniqueCustomId]!)..addAll(event.functions);
|
List.from(currentSelectedFunctions[event.uniqueCustomId]!)
|
||||||
|
..addAll(event.functions);
|
||||||
} else {
|
} else {
|
||||||
currentSelectedFunctions[event.uniqueCustomId] = List.from(event.functions);
|
currentSelectedFunctions[event.uniqueCustomId] =
|
||||||
|
List.from(event.functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
|
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
|
||||||
@ -68,7 +74,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onLoadScenes(LoadScenes event, Emitter<RoutineState> emit) async {
|
Future<void> _onLoadScenes(
|
||||||
|
LoadScenes event, Emitter<RoutineState> emit) async {
|
||||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -87,7 +94,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onLoadAutomation(LoadAutomation event, Emitter<RoutineState> emit) async {
|
Future<void> _onLoadAutomation(
|
||||||
|
LoadAutomation event, Emitter<RoutineState> emit) async {
|
||||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -106,13 +114,15 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onSearchRoutines(SearchRoutines event, Emitter<RoutineState> emit) async {
|
FutureOr<void> _onSearchRoutines(
|
||||||
|
SearchRoutines event, Emitter<RoutineState> emit) async {
|
||||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
emit(state.copyWith(searchText: event.query));
|
emit(state.copyWith(searchText: event.query));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onAddSelectedIcon(AddSelectedIcon event, Emitter<RoutineState> emit) {
|
FutureOr<void> _onAddSelectedIcon(
|
||||||
|
AddSelectedIcon event, Emitter<RoutineState> emit) {
|
||||||
emit(state.copyWith(selectedIcon: event.icon));
|
emit(state.copyWith(selectedIcon: event.icon));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +131,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
return actions.first['deviceId'] == 'delay';
|
return actions.first['deviceId'] == 'delay';
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onCreateScene(CreateSceneEvent event, Emitter<RoutineState> emit) async {
|
Future<void> _onCreateScene(
|
||||||
|
CreateSceneEvent event, Emitter<RoutineState> emit) async {
|
||||||
try {
|
try {
|
||||||
// Check if first action is delay
|
// Check if first action is delay
|
||||||
if (_isFirstActionDelay(state.thenItems)) {
|
if (_isFirstActionDelay(state.thenItems)) {
|
||||||
@ -136,7 +147,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
|
|
||||||
final actions = state.thenItems
|
final actions = state.thenItems
|
||||||
.map((item) {
|
.map((item) {
|
||||||
final functions = state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
final functions =
|
||||||
|
state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||||
if (functions.isEmpty) return null;
|
if (functions.isEmpty) return null;
|
||||||
|
|
||||||
final function = functions.first;
|
final function = functions.first;
|
||||||
@ -191,7 +203,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onRemoveDragCard(RemoveDragCard event, Emitter<RoutineState> emit) {
|
FutureOr<void> _onRemoveDragCard(
|
||||||
|
RemoveDragCard event, Emitter<RoutineState> emit) {
|
||||||
if (event.isFromThen) {
|
if (event.isFromThen) {
|
||||||
/// remove element from thenItems at specific index
|
/// remove element from thenItems at specific index
|
||||||
final thenItems = List<Map<String, dynamic>>.from(state.thenItems);
|
final thenItems = List<Map<String, dynamic>>.from(state.thenItems);
|
||||||
@ -203,4 +216,11 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
emit(state.copyWith(ifItems: ifItems));
|
emit(state.copyWith(ifItems: ifItems));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FutureOr<void> _changeOperatorOperator(
|
||||||
|
ChangeAutomationOperator event, Emitter<RoutineState> emit) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
selectedAutomationOperator: event.operator,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,4 +87,11 @@ class RemoveDragCard extends RoutineEvent {
|
|||||||
List<Object> get props => [index];
|
List<Object> get props => [index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ChangeAutomationOperator extends RoutineEvent {
|
||||||
|
final String operator;
|
||||||
|
const ChangeAutomationOperator({required this.operator});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [operator];
|
||||||
|
}
|
||||||
|
|
||||||
class ClearFunctions extends RoutineEvent {}
|
class ClearFunctions extends RoutineEvent {}
|
||||||
|
@ -14,21 +14,28 @@ class RoutineState extends Equatable {
|
|||||||
final String? routineName;
|
final String? routineName;
|
||||||
final String? selectedIcon;
|
final String? selectedIcon;
|
||||||
final String? searchText;
|
final String? searchText;
|
||||||
|
final bool isTabToRun;
|
||||||
|
final bool isAutomation;
|
||||||
|
final String selectedAutomationOperator;
|
||||||
|
|
||||||
const RoutineState(
|
const RoutineState({
|
||||||
{this.ifItems = const [],
|
this.ifItems = const [],
|
||||||
this.thenItems = const [],
|
this.thenItems = const [],
|
||||||
this.availableCards = const [],
|
this.availableCards = const [],
|
||||||
this.scenes = const [],
|
this.scenes = const [],
|
||||||
this.automations = const [],
|
this.automations = const [],
|
||||||
this.selectedFunctions = const {},
|
this.selectedFunctions = const {},
|
||||||
this.isLoading = false,
|
this.isLoading = false,
|
||||||
this.errorMessage,
|
this.errorMessage,
|
||||||
this.routineName,
|
this.routineName,
|
||||||
this.selectedIcon,
|
this.selectedIcon,
|
||||||
this.loadScenesErrorMessage,
|
this.loadScenesErrorMessage,
|
||||||
this.loadAutomationErrorMessage,
|
this.loadAutomationErrorMessage,
|
||||||
this.searchText});
|
this.searchText,
|
||||||
|
this.isTabToRun = false,
|
||||||
|
this.isAutomation = false,
|
||||||
|
this.selectedAutomationOperator = 'or',
|
||||||
|
});
|
||||||
|
|
||||||
RoutineState copyWith(
|
RoutineState copyWith(
|
||||||
{List<Map<String, dynamic>>? ifItems,
|
{List<Map<String, dynamic>>? ifItems,
|
||||||
@ -42,7 +49,10 @@ class RoutineState extends Equatable {
|
|||||||
String? selectedIcon,
|
String? selectedIcon,
|
||||||
String? loadAutomationErrorMessage,
|
String? loadAutomationErrorMessage,
|
||||||
String? loadScenesErrorMessage,
|
String? loadScenesErrorMessage,
|
||||||
String? searchText}) {
|
String? searchText,
|
||||||
|
bool? isTabToRun,
|
||||||
|
bool? isAutomation,
|
||||||
|
String? selectedAutomationOperator}) {
|
||||||
return RoutineState(
|
return RoutineState(
|
||||||
ifItems: ifItems ?? this.ifItems,
|
ifItems: ifItems ?? this.ifItems,
|
||||||
thenItems: thenItems ?? this.thenItems,
|
thenItems: thenItems ?? this.thenItems,
|
||||||
@ -53,9 +63,15 @@ class RoutineState extends Equatable {
|
|||||||
errorMessage: errorMessage ?? this.errorMessage,
|
errorMessage: errorMessage ?? this.errorMessage,
|
||||||
routineName: routineName ?? this.routineName,
|
routineName: routineName ?? this.routineName,
|
||||||
selectedIcon: selectedIcon ?? this.selectedIcon,
|
selectedIcon: selectedIcon ?? this.selectedIcon,
|
||||||
loadScenesErrorMessage: loadScenesErrorMessage ?? this.loadScenesErrorMessage,
|
loadScenesErrorMessage:
|
||||||
loadAutomationErrorMessage: loadAutomationErrorMessage ?? this.loadAutomationErrorMessage,
|
loadScenesErrorMessage ?? this.loadScenesErrorMessage,
|
||||||
searchText: searchText ?? this.searchText);
|
loadAutomationErrorMessage:
|
||||||
|
loadAutomationErrorMessage ?? this.loadAutomationErrorMessage,
|
||||||
|
searchText: searchText ?? this.searchText,
|
||||||
|
isTabToRun: isTabToRun ?? this.isTabToRun,
|
||||||
|
isAutomation: isAutomation ?? this.isAutomation,
|
||||||
|
selectedAutomationOperator:
|
||||||
|
selectedAutomationOperator ?? this.selectedAutomationOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -71,6 +87,9 @@ class RoutineState extends Equatable {
|
|||||||
selectedIcon,
|
selectedIcon,
|
||||||
loadScenesErrorMessage,
|
loadScenesErrorMessage,
|
||||||
loadAutomationErrorMessage,
|
loadAutomationErrorMessage,
|
||||||
searchText
|
searchText,
|
||||||
|
isTabToRun,
|
||||||
|
isAutomation,
|
||||||
|
selectedAutomationOperator
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ class SaveRoutineHelper {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
if (context.read<RoutineBloc>().isTabToRun)
|
if (state.isTabToRun)
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: SvgPicture.asset(
|
leading: SvgPicture.asset(
|
||||||
Assets.tabToRun,
|
Assets.tabToRun,
|
||||||
|
@ -3,7 +3,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/helper/dialog_helper/device_dialog_helper.dart';
|
import 'package:syncrow_web/pages/routiens/helper/dialog_helper/device_dialog_helper.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class IfContainer extends StatelessWidget {
|
class IfContainer extends StatelessWidget {
|
||||||
@ -21,11 +23,19 @@ class IfContainer extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text('IF',
|
Row(
|
||||||
style:
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
children: [
|
||||||
|
const Text('IF',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18, fontWeight: FontWeight.bold)),
|
||||||
|
if (state.isAutomation)
|
||||||
|
AutomationOperatorSelector(
|
||||||
|
selectedOperator: state.selectedAutomationOperator),
|
||||||
|
],
|
||||||
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
if (context.read<RoutineBloc>().isTabToRun)
|
if (state.isTabToRun)
|
||||||
const Row(
|
const Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
@ -36,7 +46,7 @@ class IfContainer extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (!context.read<RoutineBloc>().isTabToRun)
|
if (!state.isTabToRun)
|
||||||
Wrap(
|
Wrap(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
runSpacing: 8,
|
runSpacing: 8,
|
||||||
@ -64,35 +74,12 @@ class IfContainer extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
onWillAccept: (data) => data != null,
|
onWillAccept: (data) => data != null,
|
||||||
onAccept: (data) async {
|
onAccept: (data) async {
|
||||||
// final uniqueCustomId = const Uuid().v4();
|
|
||||||
|
|
||||||
// final mutableData = Map<String, dynamic>.from(data);
|
|
||||||
// mutableData['uniqueCustomId'] = uniqueCustomId;
|
|
||||||
|
|
||||||
// if (!context.read<RoutineBloc>().isTabToRun) {
|
|
||||||
// if (data['deviceId'] == 'tab_to_run') {
|
|
||||||
// context.read<RoutineBloc>().add(AddToIfContainer(data, true));
|
|
||||||
// } else {
|
|
||||||
// final result =
|
|
||||||
// await DeviceDialogHelper.showDeviceDialog(context, mutableData);
|
|
||||||
// if (result != null) {
|
|
||||||
// context
|
|
||||||
// .read<RoutineBloc>()
|
|
||||||
// .add(AddToIfContainer(mutableData, false));
|
|
||||||
// } else if (!['AC', '1G', '2G', '3G']
|
|
||||||
// .contains(data['productType'])) {
|
|
||||||
// context
|
|
||||||
// .read<RoutineBloc>()
|
|
||||||
// .add(AddToIfContainer(mutableData, false));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
final uniqueCustomId = const Uuid().v4();
|
final uniqueCustomId = const Uuid().v4();
|
||||||
|
|
||||||
final mutableData = Map<String, dynamic>.from(data);
|
final mutableData = Map<String, dynamic>.from(data);
|
||||||
mutableData['uniqueCustomId'] = uniqueCustomId;
|
mutableData['uniqueCustomId'] = uniqueCustomId;
|
||||||
|
|
||||||
if (!context.read<RoutineBloc>().isTabToRun) {
|
if (!state.isTabToRun) {
|
||||||
if (mutableData['deviceId'] == 'tab_to_run') {
|
if (mutableData['deviceId'] == 'tab_to_run') {
|
||||||
context
|
context
|
||||||
.read<RoutineBloc>()
|
.read<RoutineBloc>()
|
||||||
@ -119,3 +106,77 @@ class IfContainer extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AutomationOperatorSelector extends StatelessWidget {
|
||||||
|
const AutomationOperatorSelector({
|
||||||
|
super.key,
|
||||||
|
required this.selectedOperator,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String selectedOperator;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: ColorsManager.dividerColor),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
backgroundColor: selectedOperator == 'and'
|
||||||
|
? ColorsManager.dialogBlueTitle
|
||||||
|
: ColorsManager.whiteColors,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'All condition is met',
|
||||||
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: selectedOperator == 'and'
|
||||||
|
? ColorsManager.whiteColors
|
||||||
|
: ColorsManager.blackColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(const ChangeAutomationOperator(operator: 'and'));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 3,
|
||||||
|
height: 24,
|
||||||
|
color: ColorsManager.dividerColor,
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
backgroundColor: selectedOperator == 'or'
|
||||||
|
? ColorsManager.dialogBlueTitle
|
||||||
|
: ColorsManager.whiteColors,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'Any condition is met',
|
||||||
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: selectedOperator == 'or'
|
||||||
|
? ColorsManager.whiteColors
|
||||||
|
: ColorsManager.blackColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(const ChangeAutomationOperator(operator: 'or'));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
|
||||||
|
class AutomationDialog extends StatefulWidget {
|
||||||
|
final String automationName;
|
||||||
|
final String automationId;
|
||||||
|
|
||||||
|
const AutomationDialog({
|
||||||
|
Key? key,
|
||||||
|
required this.automationName,
|
||||||
|
required this.automationId,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AutomationDialogState createState() => _AutomationDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AutomationDialogState extends State<AutomationDialog> {
|
||||||
|
bool _isEnabled = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Dialog(
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||||
|
child: Container(
|
||||||
|
width: 400,
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
DialogHeader(widget.automationName),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
ListTile(
|
||||||
|
leading: SvgPicture.asset(Assets.acPower, width: 24, height: 24),
|
||||||
|
title: const Text('Enable'),
|
||||||
|
trailing: Radio<bool>(
|
||||||
|
value: true,
|
||||||
|
groupValue: _isEnabled,
|
||||||
|
onChanged: (bool? value) {
|
||||||
|
setState(() {
|
||||||
|
_isEnabled = value!;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading:
|
||||||
|
SvgPicture.asset(Assets.acPowerOff, width: 24, height: 24),
|
||||||
|
title: const Text('Disable'),
|
||||||
|
trailing: Radio<bool>(
|
||||||
|
value: false,
|
||||||
|
groupValue: _isEnabled,
|
||||||
|
onChanged: (bool? value) {
|
||||||
|
setState(() {
|
||||||
|
_isEnabled = value!;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
DialogFooter(
|
||||||
|
onConfirm: () {
|
||||||
|
context.read<RoutineBloc>().add(
|
||||||
|
AddFunctionToRoutine(
|
||||||
|
[
|
||||||
|
DeviceFunctionData(
|
||||||
|
entityId: widget.automationId,
|
||||||
|
functionCode: '',
|
||||||
|
value: _isEnabled,
|
||||||
|
operationName: 'Automation',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
widget.automationId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
Navigator.of(context).pop(true);
|
||||||
|
},
|
||||||
|
onCancel: () => Navigator.of(context).pop(false),
|
||||||
|
isConfirmEnabled: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,7 @@ class SettingHelper {
|
|||||||
return showDialog<String>(
|
return showDialog<String>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
final isAutomation = context.read<RoutineBloc>().isAutomation;
|
final isAutomation = context.read<RoutineBloc>().state.isAutomation;
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (_) =>
|
create: (_) =>
|
||||||
SettingBloc()..add(InitialEvent(selectedIcon: iconId ?? '')),
|
SettingBloc()..add(InitialEvent(selectedIcon: iconId ?? '')),
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/automation_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/delay_dialog.dart';
|
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/delay_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/helper/dialog_helper/device_dialog_helper.dart';
|
import 'package:syncrow_web/pages/routiens/helper/dialog_helper/device_dialog_helper.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||||
@ -54,13 +55,48 @@ class ThenContainer extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onWillAccept: (data) => data != null,
|
onWillAcceptWithDetails: (data) {
|
||||||
|
if (data == null) return false;
|
||||||
|
|
||||||
|
if (state.isTabToRun) {
|
||||||
|
return data.data['type'] == 'automation';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.isAutomation) {
|
||||||
|
return data.data['type'] == 'scene' ||
|
||||||
|
data.data['type'] == 'automation';
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.data['deviceId'] != null;
|
||||||
|
},
|
||||||
onAccept: (data) async {
|
onAccept: (data) async {
|
||||||
final uniqueCustomId = const Uuid().v4();
|
final uniqueCustomId = const Uuid().v4();
|
||||||
|
|
||||||
final mutableData = Map<String, dynamic>.from(data);
|
final mutableData = Map<String, dynamic>.from(data);
|
||||||
mutableData['uniqueCustomId'] = uniqueCustomId;
|
mutableData['uniqueCustomId'] = uniqueCustomId;
|
||||||
|
|
||||||
|
if (mutableData['type'] == 'scene') {
|
||||||
|
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mutableData['type'] == 'automation') {
|
||||||
|
final result = await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) => AutomationDialog(
|
||||||
|
automationName: mutableData['name'] ?? 'Automation',
|
||||||
|
automationId: mutableData['deviceId'] ?? '',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(AddToThenContainer(mutableData));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mutableData['deviceId'] == 'delay') {
|
if (mutableData['deviceId'] == 'delay') {
|
||||||
final result = await DelayHelper.showDelayPickerDialog(
|
final result = await DelayHelper.showDelayPickerDialog(
|
||||||
context, mutableData['uniqueCustomId']);
|
context, mutableData['uniqueCustomId']);
|
||||||
|
Reference in New Issue
Block a user