mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-15 17:47:53 +00:00
push add delay device
This commit is contained in:
@ -277,6 +277,7 @@ SOS
|
|||||||
ThreeGangCountdown3Function(
|
ThreeGangCountdown3Function(
|
||||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||||
];
|
];
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -25,23 +25,23 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _onAddToIfContainer(AddToIfContainer event, Emitter<RoutineState> emit) {
|
void _onAddToIfContainer(AddToIfContainer event, Emitter<RoutineState> emit) {
|
||||||
// if (!_isDuplicate(state.ifItems, event.item)) {
|
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems)
|
||||||
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems)..add(event.item);
|
..add(event.item);
|
||||||
isTabToRun = event.isTabToRun;
|
isTabToRun = event.isTabToRun;
|
||||||
emit(state.copyWith(ifItems: updatedIfItems));
|
emit(state.copyWith(ifItems: updatedIfItems));
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onAddToThenContainer(AddToThenContainer event, Emitter<RoutineState> emit) {
|
void _onAddToThenContainer(
|
||||||
// if (!_isDuplicate(state.thenItems, event.item)) {
|
AddToThenContainer event, Emitter<RoutineState> emit) {
|
||||||
final updatedThenItems = List<Map<String, dynamic>>.from(state.thenItems)..add(event.item);
|
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(
|
||||||
debugPrint(event.uniqueCustomId.toString());
|
AddFunctionToRoutine event, Emitter<RoutineState> emit) {
|
||||||
debugPrint(event.functions.toString());
|
debugPrint('Adding functions to routine: ${event.functions}');
|
||||||
|
debugPrint('Unique Custom ID: ${event.uniqueCustomId}');
|
||||||
final currentSelectedFunctions =
|
final currentSelectedFunctions =
|
||||||
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||||
|
|
||||||
@ -52,6 +52,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
|
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
|
||||||
|
debugPrint('Updated selected functions: $currentSelectedFunctions');
|
||||||
}
|
}
|
||||||
|
|
||||||
// void _onRemoveFunction(RemoveFunction event, Emitter<RoutineState> emit) {
|
// void _onRemoveFunction(RemoveFunction event, Emitter<RoutineState> emit) {
|
||||||
@ -66,14 +67,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
// emit(state.copyWith(selectedFunctions: []));
|
// emit(state.copyWith(selectedFunctions: []));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// bool _isDuplicate(
|
Future<void> _onLoadScenes(
|
||||||
// List<Map<String, dynamic>> items, Map<String, dynamic> newItem) {
|
LoadScenes event, Emitter<RoutineState> emit) async {
|
||||||
// return items.any((item) =>
|
|
||||||
// item['imagePath'] == newItem['imagePath'] &&
|
|
||||||
// item['title'] == newItem['title']);
|
|
||||||
// }
|
|
||||||
|
|
||||||
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 {
|
||||||
@ -90,7 +85,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 {
|
||||||
|
@ -49,7 +49,7 @@ class AddFunctionToRoutine extends RoutineEvent {
|
|||||||
final String uniqueCustomId;
|
final String uniqueCustomId;
|
||||||
const AddFunctionToRoutine(this.functions, this.uniqueCustomId);
|
const AddFunctionToRoutine(this.functions, this.uniqueCustomId);
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [functions];
|
List<Object> get props => [functions, uniqueCustomId];
|
||||||
}
|
}
|
||||||
|
|
||||||
class RemoveFunction extends RoutineEvent {
|
class RemoveFunction extends RoutineEvent {
|
||||||
|
76
lib/pages/routiens/helper/delay_helper.dart
Normal file
76
lib/pages/routiens/helper/delay_helper.dart
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/bloc/functions_bloc/functions_bloc_bloc.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_footer.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
|
class DelayHelper {
|
||||||
|
static Future<Map<String, dynamic>?> showDelayPickerDialog(
|
||||||
|
BuildContext context, String uniqueCustomId) async {
|
||||||
|
int hours = 0;
|
||||||
|
int minutes = 0;
|
||||||
|
|
||||||
|
return showDialog<Map<String, dynamic>?>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
content: Container(
|
||||||
|
width: 600,
|
||||||
|
height: 300,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const DialogHeader('Select Delay Duration'),
|
||||||
|
Expanded(
|
||||||
|
child: CupertinoTimerPicker(
|
||||||
|
mode: CupertinoTimerPickerMode.hm,
|
||||||
|
initialTimerDuration:
|
||||||
|
Duration(hours: hours, minutes: minutes),
|
||||||
|
onTimerDurationChanged: (Duration newDuration) {
|
||||||
|
hours = newDuration.inHours;
|
||||||
|
minutes = newDuration.inMinutes % 60;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DialogFooter(
|
||||||
|
onCancel: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
onConfirm: () {
|
||||||
|
int totalSeconds = (hours * 3600) + (minutes * 60);
|
||||||
|
context.read<RoutineBloc>().add(AddFunctionToRoutine(
|
||||||
|
[
|
||||||
|
DeviceFunctionData(
|
||||||
|
entityId: 'delay',
|
||||||
|
functionCode: 'delay',
|
||||||
|
operationName: 'Delay',
|
||||||
|
value: totalSeconds,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
uniqueCustomId,
|
||||||
|
));
|
||||||
|
|
||||||
|
Navigator.pop(context, {
|
||||||
|
'deviceId': 'delay',
|
||||||
|
'value': totalSeconds,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
isConfirmEnabled: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
28
lib/pages/routiens/models/delay/delay_fucntions.dart
Normal file
28
lib/pages/routiens/models/delay/delay_fucntions.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
|
||||||
|
class DelayFunction extends BaseSwitchFunction {
|
||||||
|
DelayFunction({required super.deviceId, required super.deviceName})
|
||||||
|
: super(
|
||||||
|
code: 'delay',
|
||||||
|
operationName: 'Delay',
|
||||||
|
icon: Assets.delay,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<SwitchOperationalValue> getOperationalValues() => [
|
||||||
|
SwitchOperationalValue(
|
||||||
|
icon: '',
|
||||||
|
description: "Duration in seconds",
|
||||||
|
value: 0.0,
|
||||||
|
minValue: 0,
|
||||||
|
maxValue: 43200,
|
||||||
|
stepValue: 1,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
int convertToSeconds(int hours, int minutes) {
|
||||||
|
return (hours * 3600) + (minutes * 60);
|
||||||
|
}
|
||||||
|
}
|
@ -91,6 +91,7 @@ class ConditionsRoutinesDevicesView extends StatelessWidget {
|
|||||||
'deviceId': 'delay',
|
'deviceId': 'delay',
|
||||||
'type': 'action',
|
'type': 'action',
|
||||||
'name': 'Delay the action',
|
'name': 'Delay the action',
|
||||||
|
'uniqueCustomId': '',
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -9,7 +9,11 @@ class DialogHeader extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
Text(
|
Text(
|
||||||
title,
|
title,
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
|
@ -10,38 +10,44 @@ class DraggableCard extends StatelessWidget {
|
|||||||
final String imagePath;
|
final String imagePath;
|
||||||
final String title;
|
final String title;
|
||||||
final Map<String, dynamic> deviceData;
|
final Map<String, dynamic> deviceData;
|
||||||
|
final EdgeInsetsGeometry? padding;
|
||||||
|
|
||||||
const DraggableCard({
|
const DraggableCard({
|
||||||
super.key,
|
super.key,
|
||||||
required this.imagePath,
|
required this.imagePath,
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.deviceData,
|
required this.deviceData,
|
||||||
|
this.padding,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final deviceFunctions = state.selectedFunctions[deviceData['uniqueCustomId']] ?? [];
|
final deviceFunctions =
|
||||||
|
state.selectedFunctions[deviceData['uniqueCustomId']] ?? [];
|
||||||
|
|
||||||
return Draggable<Map<String, dynamic>>(
|
return Draggable<Map<String, dynamic>>(
|
||||||
data: deviceData,
|
data: deviceData,
|
||||||
feedback: Transform.rotate(
|
feedback: Transform.rotate(
|
||||||
angle: -0.1,
|
angle: -0.1,
|
||||||
child: _buildCardContent(context, deviceFunctions),
|
child:
|
||||||
|
_buildCardContent(context, deviceFunctions, padding: padding),
|
||||||
),
|
),
|
||||||
childWhenDragging: _buildGreyContainer(),
|
childWhenDragging: _buildGreyContainer(),
|
||||||
child: _buildCardContent(context, deviceFunctions),
|
child: _buildCardContent(context, deviceFunctions, padding: padding),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCardContent(BuildContext context, List<DeviceFunctionData> deviceFunctions) {
|
Widget _buildCardContent(
|
||||||
|
BuildContext context, List<DeviceFunctionData> deviceFunctions,
|
||||||
|
{EdgeInsetsGeometry? padding}) {
|
||||||
return Card(
|
return Card(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.whiteColors,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: padding ?? const EdgeInsets.all(16),
|
||||||
width: 110,
|
width: 110,
|
||||||
height: deviceFunctions.isEmpty ? 123 : null,
|
height: deviceFunctions.isEmpty ? 123 : null,
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -3,7 +3,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_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/dragable_card.dart';
|
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
|
||||||
|
|
||||||
class RoutineDevices extends StatelessWidget {
|
class RoutineDevices extends StatelessWidget {
|
||||||
const RoutineDevices({super.key});
|
const RoutineDevices({super.key});
|
||||||
@ -41,6 +40,7 @@ class RoutineDevices extends StatelessWidget {
|
|||||||
'deviceId': device.uuid,
|
'deviceId': device.uuid,
|
||||||
'productType': device.productType,
|
'productType': device.productType,
|
||||||
'functions': device.functions,
|
'functions': device.functions,
|
||||||
|
'uniqueCustomId': '',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
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/helper/delay_helper.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/constants/assets.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class ThenContainer extends StatelessWidget {
|
class ThenContainer extends StatelessWidget {
|
||||||
@ -36,6 +38,8 @@ class ThenContainer extends StatelessWidget {
|
|||||||
imagePath: item['imagePath']!,
|
imagePath: item['imagePath']!,
|
||||||
title: item['title']!,
|
title: item['title']!,
|
||||||
deviceData: item,
|
deviceData: item,
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 4, vertical: 8),
|
||||||
))
|
))
|
||||||
.toList(),
|
.toList(),
|
||||||
),
|
),
|
||||||
@ -47,26 +51,32 @@ class ThenContainer extends StatelessWidget {
|
|||||||
onWillAccept: (data) => data != null,
|
onWillAccept: (data) => data != null,
|
||||||
onAccept: (data) async {
|
onAccept: (data) async {
|
||||||
final uniqueCustomId = const Uuid().v4();
|
final uniqueCustomId = const Uuid().v4();
|
||||||
data['uniqueCustomId'] = uniqueCustomId;
|
|
||||||
final result =
|
|
||||||
await DeviceDialogHelper.showDeviceDialog(context, data);
|
|
||||||
// if (result != null) {
|
|
||||||
// for (var function in routineBloc.state.selectedFunctions) {
|
|
||||||
// routineBloc.add(AddToThenContainer(
|
|
||||||
// {
|
|
||||||
// 'item': function,
|
|
||||||
// 'imagePath': data['imagePath'],
|
|
||||||
// 'title': data['name'],
|
|
||||||
|
|
||||||
// }
|
final mutableData = Map<String, dynamic>.from(data);
|
||||||
// ));
|
mutableData['uniqueCustomId'] = uniqueCustomId;
|
||||||
// }
|
|
||||||
// }
|
if (mutableData['deviceId'] == 'delay') {
|
||||||
|
final result = await DelayHelper.showDelayPickerDialog(
|
||||||
|
context, mutableData['uniqueCustomId']);
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
context.read<RoutineBloc>().add(AddToThenContainer({
|
||||||
|
...mutableData,
|
||||||
|
'imagePath': Assets.delay,
|
||||||
|
'title': 'Delay',
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final result =
|
||||||
|
await DeviceDialogHelper.showDeviceDialog(context, mutableData);
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context.read<RoutineBloc>().add(AddToThenContainer(data));
|
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
||||||
} else if (!['AC', '1G', '2G', '3G']
|
} else if (!['AC', '1G', '2G', '3G']
|
||||||
.contains(data['productType'])) {
|
.contains(mutableData['productType'])) {
|
||||||
context.read<RoutineBloc>().add(AddToThenContainer(data));
|
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user