mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
@ -18,13 +18,13 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider(
|
|
||||||
create: (context) => DeviceManagementBloc()..add(FetchDevices()),
|
|
||||||
),
|
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) =>
|
create: (context) =>
|
||||||
SwitchTabsBloc()..add(const TriggerSwitchTabsEvent(false)),
|
SwitchTabsBloc()..add(const TriggerSwitchTabsEvent(false)),
|
||||||
),
|
),
|
||||||
|
BlocProvider(
|
||||||
|
create: (context) => DeviceManagementBloc()..add(FetchDevices()),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
child: WebScaffold(
|
child: WebScaffold(
|
||||||
appBarTitle: FittedBox(
|
appBarTitle: FittedBox(
|
||||||
@ -101,12 +101,11 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
builder: (context, deviceState) {
|
builder: (context, deviceState) {
|
||||||
if (deviceState is DeviceManagementLoading) {
|
if (deviceState is DeviceManagementLoading) {
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
} else if (deviceState is DeviceManagementLoaded ||
|
} else if (deviceState is DeviceManagementLoaded) {
|
||||||
deviceState is DeviceManagementFiltered) {
|
return DeviceManagementBody(devices: deviceState.devices);
|
||||||
final devices = (deviceState as dynamic).devices ??
|
} else if (deviceState is DeviceManagementFiltered) {
|
||||||
(deviceState as DeviceManagementFiltered).filteredDevices;
|
return DeviceManagementBody(
|
||||||
|
devices: deviceState.filteredDevices);
|
||||||
return DeviceManagementBody(devices: devices);
|
|
||||||
} else {
|
} else {
|
||||||
return const Center(child: Text('Error fetching Devices'));
|
return const Center(child: Text('Error fetching Devices'));
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,6 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
|
|||||||
final TextEditingController unitNameController = TextEditingController();
|
final TextEditingController unitNameController = TextEditingController();
|
||||||
final TextEditingController productNameController = TextEditingController();
|
final TextEditingController productNameController = TextEditingController();
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
communityController.dispose();
|
|
||||||
unitNameController.dispose();
|
|
||||||
productNameController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return isExtraLargeScreenSize(context)
|
return isExtraLargeScreenSize(context)
|
||||||
|
@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_automation_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_scene_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_scene_model.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/models/routine_details_model.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
||||||
import 'package:syncrow_web/services/routines_api.dart';
|
import 'package:syncrow_web/services/routines_api.dart';
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ part 'routine_event.dart';
|
|||||||
part 'routine_state.dart';
|
part 'routine_state.dart';
|
||||||
|
|
||||||
const spaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
|
const spaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
|
||||||
|
const communityId = 'aff21a57-2f91-4e5c-b99b-0182c3ab65a9';
|
||||||
|
|
||||||
class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||||
RoutineBloc() : super(const RoutineState()) {
|
RoutineBloc() : super(const RoutineState()) {
|
||||||
@ -30,6 +32,11 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
on<CreateAutomationEvent>(_onCreateAutomation);
|
on<CreateAutomationEvent>(_onCreateAutomation);
|
||||||
on<SetRoutineName>(_onSetRoutineName);
|
on<SetRoutineName>(_onSetRoutineName);
|
||||||
on<ResetRoutineState>(_onResetRoutineState);
|
on<ResetRoutineState>(_onResetRoutineState);
|
||||||
|
on<GetSceneDetails>(_onGetSceneDetails);
|
||||||
|
on<GetAutomationDetails>(_onGetAutomationDetails);
|
||||||
|
// on<InitializeRoutineState>(_onInitializeRoutineState);
|
||||||
|
on<DeleteScene>(_deleteScene);
|
||||||
|
on<DeleteAutomation>(_deleteAutomation);
|
||||||
// on<RemoveFunction>(_onRemoveFunction);
|
// on<RemoveFunction>(_onRemoveFunction);
|
||||||
// on<ClearFunctions>(_onClearFunctions);
|
// on<ClearFunctions>(_onClearFunctions);
|
||||||
}
|
}
|
||||||
@ -38,8 +45,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems);
|
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems);
|
||||||
|
|
||||||
// Find the index of the item in teh current itemsList
|
// Find the index of the item in teh current itemsList
|
||||||
int index =
|
int index = updatedIfItems.indexWhere(
|
||||||
updatedIfItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
|
(map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
|
||||||
// Replace the map if the index is valid
|
// Replace the map if the index is valid
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
updatedIfItems[index] = event.item;
|
updatedIfItems[index] = event.item;
|
||||||
@ -48,18 +55,21 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (event.isTabToRun) {
|
if (event.isTabToRun) {
|
||||||
emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: true, isAutomation: false));
|
emit(state.copyWith(
|
||||||
|
ifItems: updatedIfItems, isTabToRun: true, isAutomation: false));
|
||||||
} else {
|
} else {
|
||||||
emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: false, isAutomation: true));
|
emit(state.copyWith(
|
||||||
|
ifItems: updatedIfItems, isTabToRun: false, isAutomation: true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onAddToThenContainer(AddToThenContainer event, Emitter<RoutineState> emit) {
|
void _onAddToThenContainer(
|
||||||
|
AddToThenContainer event, Emitter<RoutineState> emit) {
|
||||||
final currentItems = List<Map<String, dynamic>>.from(state.thenItems);
|
final currentItems = List<Map<String, dynamic>>.from(state.thenItems);
|
||||||
|
|
||||||
// Find the index of the item in teh current itemsList
|
// Find the index of the item in teh current itemsList
|
||||||
int index =
|
int index = currentItems.indexWhere(
|
||||||
currentItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
|
(map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
|
||||||
// Replace the map if the index is valid
|
// Replace the map if the index is valid
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
currentItems[index] = event.item;
|
currentItems[index] = event.item;
|
||||||
@ -70,22 +80,26 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
emit(state.copyWith(thenItems: currentItems));
|
emit(state.copyWith(thenItems: currentItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
List<DeviceFunctionData> selectedFunction = List<DeviceFunctionData>.from(event.functions);
|
List<DeviceFunctionData> selectedFunction =
|
||||||
|
List<DeviceFunctionData>.from(event.functions);
|
||||||
|
|
||||||
Map<String, List<DeviceFunctionData>> currentSelectedFunctions =
|
Map<String, List<DeviceFunctionData>> currentSelectedFunctions =
|
||||||
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||||
if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) {
|
if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) {
|
||||||
List<DeviceFunctionData> currentFunctions =
|
List<DeviceFunctionData> currentFunctions =
|
||||||
List<DeviceFunctionData>.from(currentSelectedFunctions[event.uniqueCustomId] ?? []);
|
List<DeviceFunctionData>.from(
|
||||||
|
currentSelectedFunctions[event.uniqueCustomId] ?? []);
|
||||||
|
|
||||||
List<String> functionCode = [];
|
List<String> functionCode = [];
|
||||||
for (int i = 0; i < selectedFunction.length; i++) {
|
for (int i = 0; i < selectedFunction.length; i++) {
|
||||||
for (int j = 0; j < currentFunctions.length; j++) {
|
for (int j = 0; j < currentFunctions.length; j++) {
|
||||||
if (selectedFunction[i].functionCode == currentFunctions[j].functionCode) {
|
if (selectedFunction[i].functionCode ==
|
||||||
|
currentFunctions[j].functionCode) {
|
||||||
currentFunctions[j] = selectedFunction[i];
|
currentFunctions[j] = selectedFunction[i];
|
||||||
if (!functionCode.contains(currentFunctions[j].functionCode)) {
|
if (!functionCode.contains(currentFunctions[j].functionCode)) {
|
||||||
functionCode.add(currentFunctions[j].functionCode);
|
functionCode.add(currentFunctions[j].functionCode);
|
||||||
@ -95,13 +109,15 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < functionCode.length; i++) {
|
for (int i = 0; i < functionCode.length; i++) {
|
||||||
selectedFunction.removeWhere((code) => code.functionCode == functionCode[i]);
|
selectedFunction
|
||||||
|
.removeWhere((code) => code.functionCode == functionCode[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentSelectedFunctions[event.uniqueCustomId] = List.from(currentFunctions)
|
currentSelectedFunctions[event.uniqueCustomId] =
|
||||||
..addAll(selectedFunction);
|
List.from(currentFunctions)..addAll(selectedFunction);
|
||||||
} 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));
|
||||||
@ -110,11 +126,13 @@ 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 {
|
||||||
final scenes = await SceneApi.getScenesByUnitId(event.unitId);
|
final scenes =
|
||||||
|
await SceneApi.getScenesByUnitId(event.unitId, event.communityId);
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
scenes: scenes,
|
scenes: scenes,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
@ -129,7 +147,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 {
|
||||||
@ -157,14 +176,16 @@ 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(isLoading: false, errorMessage: null));
|
emit(state.copyWith(isLoading: false, errorMessage: null));
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +194,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)) {
|
||||||
@ -233,7 +255,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
final result = await SceneApi.createScene(createSceneModel);
|
final result = await SceneApi.createScene(createSceneModel);
|
||||||
if (result['success']) {
|
if (result['success']) {
|
||||||
emit(_resetState());
|
emit(_resetState());
|
||||||
add(const LoadScenes(spaceId));
|
add(const LoadScenes(spaceId, communityId));
|
||||||
} else {
|
} else {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
@ -248,7 +270,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onCreateAutomation(CreateAutomationEvent event, Emitter<RoutineState> emit) async {
|
Future<void> _onCreateAutomation(
|
||||||
|
CreateAutomationEvent event, Emitter<RoutineState> emit) async {
|
||||||
try {
|
try {
|
||||||
if (state.routineName == null || state.routineName!.isEmpty) {
|
if (state.routineName == null || state.routineName!.isEmpty) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
@ -348,21 +371,34 @@ 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) {
|
||||||
final thenItems = List<Map<String, dynamic>>.from(state.thenItems);
|
final thenItems = List<Map<String, dynamic>>.from(state.thenItems);
|
||||||
final selectedFunctions = Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
final selectedFunctions =
|
||||||
|
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||||
|
|
||||||
thenItems.removeAt(event.index);
|
thenItems.removeAt(event.index);
|
||||||
selectedFunctions.remove(event.key);
|
selectedFunctions.remove(event.key);
|
||||||
emit(state.copyWith(thenItems: thenItems, selectedFunctions: selectedFunctions));
|
emit(state.copyWith(
|
||||||
|
thenItems: thenItems, selectedFunctions: selectedFunctions));
|
||||||
} else {
|
} else {
|
||||||
final ifItems = List<Map<String, dynamic>>.from(state.ifItems);
|
final ifItems = List<Map<String, dynamic>>.from(state.ifItems);
|
||||||
final selectedFunctions = Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
final selectedFunctions =
|
||||||
|
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||||
|
|
||||||
ifItems.removeAt(event.index);
|
ifItems.removeAt(event.index);
|
||||||
selectedFunctions.remove(event.key);
|
selectedFunctions.remove(event.key);
|
||||||
emit(state.copyWith(ifItems: ifItems, selectedFunctions: selectedFunctions));
|
if (ifItems.isEmpty && state.thenItems.isEmpty) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
ifItems: ifItems,
|
||||||
|
selectedFunctions: selectedFunctions,
|
||||||
|
isAutomation: false,
|
||||||
|
isTabToRun: false));
|
||||||
|
} else {
|
||||||
|
emit(state.copyWith(
|
||||||
|
ifItems: ifItems, selectedFunctions: selectedFunctions));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,14 +409,134 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onEffectiveTimeEvent(EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) {
|
FutureOr<void> _onEffectiveTimeEvent(
|
||||||
|
EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) {
|
||||||
emit(state.copyWith(effectiveTime: event.effectiveTime));
|
emit(state.copyWith(effectiveTime: event.effectiveTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onSetRoutineName(SetRoutineName event, Emitter<RoutineState> emit) {
|
FutureOr<void> _onSetRoutineName(
|
||||||
|
SetRoutineName event, Emitter<RoutineState> emit) {
|
||||||
emit(state.copyWith(routineName: event.name));
|
emit(state.copyWith(routineName: event.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _onGetSceneDetails(
|
||||||
|
GetSceneDetails event, Emitter<RoutineState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(state.copyWith(
|
||||||
|
isLoading: true,
|
||||||
|
isTabToRun: event.isTabToRun,
|
||||||
|
isUpdate: true,
|
||||||
|
sceneId: event.sceneId,
|
||||||
|
isAutomation: false));
|
||||||
|
final sceneDetails = await SceneApi.getSceneDetails(event.sceneId);
|
||||||
|
add(InitializeRoutineState(sceneDetails));
|
||||||
|
} catch (e) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
isLoading: false,
|
||||||
|
errorMessage: 'Failed to load scene details',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onGetAutomationDetails(
|
||||||
|
GetAutomationDetails event, Emitter<RoutineState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(state.copyWith(
|
||||||
|
isLoading: true,
|
||||||
|
isAutomation: event.isAutomation,
|
||||||
|
automationId: event.automationId,
|
||||||
|
isTabToRun: false,
|
||||||
|
isUpdate: true,
|
||||||
|
));
|
||||||
|
final automationDetails =
|
||||||
|
await SceneApi.getAutomationDetails(event.automationId);
|
||||||
|
add(InitializeRoutineState(automationDetails));
|
||||||
|
} catch (e) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
isLoading: false,
|
||||||
|
errorMessage: 'Failed to load automation details',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// void _onInitializeRoutineState(
|
||||||
|
// InitializeRoutineState event, Emitter<RoutineState> emit) {
|
||||||
|
// final routineDetails = event.routineDetails;
|
||||||
|
|
||||||
|
// // Convert actions to draggable cards for the THEN container
|
||||||
|
// final thenItems = routineDetails.actions.map((action) {
|
||||||
|
// final Map<String, dynamic> cardData = {
|
||||||
|
// 'entityId': action.entityId,
|
||||||
|
// 'uniqueCustomId': const Uuid().v4(),
|
||||||
|
// 'deviceId':
|
||||||
|
// action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
||||||
|
// 'title': action.actionExecutor == 'delay' ? 'Delay' : 'Device',
|
||||||
|
// // fix this
|
||||||
|
// 'imagePath':
|
||||||
|
// action.actionExecutor == 'delay' ? Assets.delay : Assets.logo,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Add functions to selectedFunctions
|
||||||
|
// if (action.executorProperty != null) {
|
||||||
|
// final functions = <DeviceFunctionData>[
|
||||||
|
// DeviceFunctionData(
|
||||||
|
// entityId: action.entityId,
|
||||||
|
// functionCode: action.executorProperty!.functionCode ?? '',
|
||||||
|
// value: action.executorProperty!.functionValue,
|
||||||
|
|
||||||
|
// /// fix this
|
||||||
|
// operationName: action.executorProperty?.functionCode ?? ''),
|
||||||
|
// ];
|
||||||
|
// state.selectedFunctions[cardData['uniqueCustomId']] = functions;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return cardData;
|
||||||
|
// }).toList();
|
||||||
|
|
||||||
|
// // Convert conditions to draggable cards for the IF container
|
||||||
|
// final ifItems = routineDetails.conditions?.map((condition) {
|
||||||
|
// final Map<String, dynamic> cardData = {
|
||||||
|
// 'entityId': condition.entityId,
|
||||||
|
// 'uniqueCustomId': const Uuid().v4(),
|
||||||
|
// 'deviceId': condition.entityId,
|
||||||
|
|
||||||
|
// /// fix this
|
||||||
|
// 'title': 'Device',
|
||||||
|
|
||||||
|
// /// fix this
|
||||||
|
// 'imagePath': Assets.logo,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Add functions to selectedFunctions
|
||||||
|
// final functions = <DeviceFunctionData>[
|
||||||
|
// DeviceFunctionData(
|
||||||
|
// entityId: condition.entityId,
|
||||||
|
// functionCode: condition.expr.statusCode,
|
||||||
|
// value: condition.expr.statusValue,
|
||||||
|
// condition: condition.expr.comparator,
|
||||||
|
// operationName: condition.expr.comparator,
|
||||||
|
// ),
|
||||||
|
// ];
|
||||||
|
// state.selectedFunctions[cardData['uniqueCustomId']] = functions;
|
||||||
|
|
||||||
|
// return cardData;
|
||||||
|
// }).toList() ??
|
||||||
|
// [];
|
||||||
|
|
||||||
|
// emit(state.copyWith(
|
||||||
|
// isLoading: false,
|
||||||
|
// routineName: routineDetails.name,
|
||||||
|
// selectedIcon: routineDetails.iconId,
|
||||||
|
// selectedAutomationOperator: routineDetails.decisionExpr,
|
||||||
|
// effectiveTime: routineDetails.effectiveTime,
|
||||||
|
// isAutomation: routineDetails.conditions != null,
|
||||||
|
// isTabToRun: routineDetails.conditions == null,
|
||||||
|
// thenItems: thenItems,
|
||||||
|
// ifItems: ifItems,
|
||||||
|
// selectedFunctions: Map.from(state.selectedFunctions),
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
|
|
||||||
RoutineState _resetState() {
|
RoutineState _resetState() {
|
||||||
return const RoutineState(
|
return const RoutineState(
|
||||||
ifItems: [],
|
ifItems: [],
|
||||||
@ -396,13 +552,44 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
selectedIcon: null,
|
selectedIcon: null,
|
||||||
isTabToRun: false,
|
isTabToRun: false,
|
||||||
isAutomation: false,
|
isAutomation: false,
|
||||||
selectedAutomationOperator: 'AND',
|
selectedAutomationOperator: 'or',
|
||||||
effectiveTime: null,
|
effectiveTime: null,
|
||||||
routineName: null,
|
routineName: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onResetRoutineState(ResetRoutineState event, Emitter<RoutineState> emit) {
|
FutureOr<void> _onResetRoutineState(
|
||||||
|
ResetRoutineState event, Emitter<RoutineState> emit) {
|
||||||
emit(_resetState());
|
emit(_resetState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FutureOr<void> _deleteScene(DeleteScene event, Emitter<RoutineState> emit) {
|
||||||
|
try {
|
||||||
|
// emit(state.copyWith(isLoading: true));
|
||||||
|
SceneApi.deleteScene(unitUuid: spaceId, sceneId: event.sceneId);
|
||||||
|
add(const LoadScenes(spaceId, communityId));
|
||||||
|
//emit(_resetState());
|
||||||
|
} catch (e) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
isLoading: false,
|
||||||
|
errorMessage: 'Failed to delete scene',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FutureOr<void> _deleteAutomation(
|
||||||
|
DeleteAutomation event, Emitter<RoutineState> emit) {
|
||||||
|
try {
|
||||||
|
//emit(state.copyWith(isLoading: true));
|
||||||
|
SceneApi.deleteAutomation(
|
||||||
|
unitUuid: spaceId, automationId: event.automationId);
|
||||||
|
add(const LoadAutomation(spaceId));
|
||||||
|
// emit(_resetState());
|
||||||
|
} catch (e) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
isLoading: false,
|
||||||
|
errorMessage: 'Failed to delete automation',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,12 @@ class AddToThenContainer extends RoutineEvent {
|
|||||||
|
|
||||||
class LoadScenes extends RoutineEvent {
|
class LoadScenes extends RoutineEvent {
|
||||||
final String unitId;
|
final String unitId;
|
||||||
|
final String communityId;
|
||||||
|
|
||||||
const LoadScenes(this.unitId);
|
const LoadScenes(this.unitId, this.communityId);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [unitId];
|
List<Object> get props => [unitId, communityId];
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoadAutomation extends RoutineEvent {
|
class LoadAutomation extends RoutineEvent {
|
||||||
@ -124,6 +125,55 @@ class SetRoutineName extends RoutineEvent {
|
|||||||
List<Object> get props => [name];
|
List<Object> get props => [name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GetSceneDetails extends RoutineEvent {
|
||||||
|
final String sceneId;
|
||||||
|
final bool isUpdate;
|
||||||
|
final bool isTabToRun;
|
||||||
|
const GetSceneDetails({
|
||||||
|
required this.sceneId,
|
||||||
|
required this.isUpdate,
|
||||||
|
required this.isTabToRun,
|
||||||
|
});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [sceneId];
|
||||||
|
}
|
||||||
|
|
||||||
|
class GetAutomationDetails extends RoutineEvent {
|
||||||
|
final String automationId;
|
||||||
|
final bool isUpdate;
|
||||||
|
final bool isAutomation;
|
||||||
|
const GetAutomationDetails({
|
||||||
|
required this.automationId,
|
||||||
|
this.isUpdate = false,
|
||||||
|
this.isAutomation = false,
|
||||||
|
});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [automationId];
|
||||||
|
}
|
||||||
|
|
||||||
|
class InitializeRoutineState extends RoutineEvent {
|
||||||
|
final RoutineDetailsModel routineDetails;
|
||||||
|
const InitializeRoutineState(this.routineDetails);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [routineDetails];
|
||||||
|
}
|
||||||
|
|
||||||
|
class DeleteScene extends RoutineEvent {
|
||||||
|
final String sceneId;
|
||||||
|
final String unitUuid;
|
||||||
|
const DeleteScene({required this.sceneId, required this.unitUuid});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [sceneId];
|
||||||
|
}
|
||||||
|
|
||||||
|
class DeleteAutomation extends RoutineEvent {
|
||||||
|
final String automationId;
|
||||||
|
final String unitUuid;
|
||||||
|
const DeleteAutomation({required this.automationId, required this.unitUuid});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [automationId];
|
||||||
|
}
|
||||||
|
|
||||||
class ResetRoutineState extends RoutineEvent {}
|
class ResetRoutineState extends RoutineEvent {}
|
||||||
|
|
||||||
class ClearFunctions extends RoutineEvent {}
|
class ClearFunctions extends RoutineEvent {}
|
||||||
|
@ -18,6 +18,9 @@ class RoutineState extends Equatable {
|
|||||||
final bool isAutomation;
|
final bool isAutomation;
|
||||||
final String selectedAutomationOperator;
|
final String selectedAutomationOperator;
|
||||||
final EffectiveTime? effectiveTime;
|
final EffectiveTime? effectiveTime;
|
||||||
|
final String? sceneId;
|
||||||
|
final String? automationId;
|
||||||
|
final bool? isUpdate;
|
||||||
|
|
||||||
const RoutineState({
|
const RoutineState({
|
||||||
this.ifItems = const [],
|
this.ifItems = const [],
|
||||||
@ -37,6 +40,9 @@ class RoutineState extends Equatable {
|
|||||||
this.isAutomation = false,
|
this.isAutomation = false,
|
||||||
this.selectedAutomationOperator = 'or',
|
this.selectedAutomationOperator = 'or',
|
||||||
this.effectiveTime,
|
this.effectiveTime,
|
||||||
|
this.sceneId,
|
||||||
|
this.automationId,
|
||||||
|
this.isUpdate,
|
||||||
});
|
});
|
||||||
|
|
||||||
RoutineState copyWith({
|
RoutineState copyWith({
|
||||||
@ -56,6 +62,9 @@ class RoutineState extends Equatable {
|
|||||||
bool? isAutomation,
|
bool? isAutomation,
|
||||||
String? selectedAutomationOperator,
|
String? selectedAutomationOperator,
|
||||||
EffectiveTime? effectiveTime,
|
EffectiveTime? effectiveTime,
|
||||||
|
String? sceneId,
|
||||||
|
String? automationId,
|
||||||
|
bool? isUpdate,
|
||||||
}) {
|
}) {
|
||||||
return RoutineState(
|
return RoutineState(
|
||||||
ifItems: ifItems ?? this.ifItems,
|
ifItems: ifItems ?? this.ifItems,
|
||||||
@ -77,6 +86,9 @@ class RoutineState extends Equatable {
|
|||||||
selectedAutomationOperator:
|
selectedAutomationOperator:
|
||||||
selectedAutomationOperator ?? this.selectedAutomationOperator,
|
selectedAutomationOperator ?? this.selectedAutomationOperator,
|
||||||
effectiveTime: effectiveTime ?? this.effectiveTime,
|
effectiveTime: effectiveTime ?? this.effectiveTime,
|
||||||
|
sceneId: sceneId ?? this.sceneId,
|
||||||
|
automationId: automationId ?? this.automationId,
|
||||||
|
isUpdate: isUpdate ?? this.isUpdate,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +109,9 @@ class RoutineState extends Equatable {
|
|||||||
isTabToRun,
|
isTabToRun,
|
||||||
isAutomation,
|
isAutomation,
|
||||||
selectedAutomationOperator,
|
selectedAutomationOperator,
|
||||||
effectiveTime
|
effectiveTime,
|
||||||
|
sceneId,
|
||||||
|
automationId,
|
||||||
|
isUpdate
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,9 @@ import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
|||||||
class DeviceDialogHelper {
|
class DeviceDialogHelper {
|
||||||
static Future<Map<String, dynamic>?> showDeviceDialog(
|
static Future<Map<String, dynamic>?> showDeviceDialog(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Map<String, dynamic> data,
|
Map<String, dynamic> data, {
|
||||||
) async {
|
required bool removeComparetors,
|
||||||
|
}) async {
|
||||||
final functions = data['functions'] as List<DeviceFunction>;
|
final functions = data['functions'] as List<DeviceFunction>;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -20,6 +21,7 @@ class DeviceDialogHelper {
|
|||||||
data['productType'],
|
data['productType'],
|
||||||
data,
|
data,
|
||||||
functions,
|
functions,
|
||||||
|
removeComparetors: removeComparetors,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
@ -33,34 +35,49 @@ class DeviceDialogHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>?> _getDialogForDeviceType(
|
static Future<Map<String, dynamic>?> _getDialogForDeviceType(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
String productType,
|
String productType,
|
||||||
Map<String, dynamic> data,
|
Map<String, dynamic> data,
|
||||||
List<DeviceFunction> functions,
|
List<DeviceFunction> functions,
|
||||||
) async {
|
{required bool removeComparetors}) async {
|
||||||
final routineBloc = context.read<RoutineBloc>();
|
final routineBloc = context.read<RoutineBloc>();
|
||||||
final deviceSelectedFunctions =
|
final deviceSelectedFunctions =
|
||||||
routineBloc.state.selectedFunctions[data['uniqueCustomId']] ?? [];
|
routineBloc.state.selectedFunctions[data['uniqueCustomId']] ?? [];
|
||||||
|
|
||||||
switch (productType) {
|
switch (productType) {
|
||||||
case 'AC':
|
case 'AC':
|
||||||
return ACHelper.showACFunctionsDialog(context, functions,
|
return ACHelper.showACFunctionsDialog(
|
||||||
data['device'], deviceSelectedFunctions, data['uniqueCustomId']);
|
context,
|
||||||
|
functions,
|
||||||
|
data['device'],
|
||||||
|
deviceSelectedFunctions,
|
||||||
|
data['uniqueCustomId'],
|
||||||
|
removeComparetors);
|
||||||
|
|
||||||
case '1G':
|
case '1G':
|
||||||
return OneGangSwitchHelper.showSwitchFunctionsDialog(context, functions,
|
return OneGangSwitchHelper.showSwitchFunctionsDialog(
|
||||||
data['device'], deviceSelectedFunctions, data['uniqueCustomId']);
|
context,
|
||||||
|
functions,
|
||||||
|
data['device'],
|
||||||
|
deviceSelectedFunctions,
|
||||||
|
data['uniqueCustomId'],
|
||||||
|
removeComparetors);
|
||||||
case '2G':
|
case '2G':
|
||||||
return TwoGangSwitchHelper.showSwitchFunctionsDialog(context, functions,
|
return TwoGangSwitchHelper.showSwitchFunctionsDialog(
|
||||||
data['device'], deviceSelectedFunctions, data['uniqueCustomId']);
|
context,
|
||||||
|
functions,
|
||||||
|
data['device'],
|
||||||
|
deviceSelectedFunctions,
|
||||||
|
data['uniqueCustomId'],
|
||||||
|
removeComparetors);
|
||||||
case '3G':
|
case '3G':
|
||||||
return ThreeGangSwitchHelper.showSwitchFunctionsDialog(
|
return ThreeGangSwitchHelper.showSwitchFunctionsDialog(
|
||||||
context,
|
context,
|
||||||
functions,
|
functions,
|
||||||
data['device'],
|
data['device'],
|
||||||
deviceSelectedFunctions,
|
deviceSelectedFunctions,
|
||||||
data['uniqueCustomId'],
|
data['uniqueCustomId'],
|
||||||
);
|
removeComparetors);
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@ import 'package:syncrow_web/utils/color_manager.dart';
|
|||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
|
||||||
class SaveRoutineHelper {
|
class SaveRoutineHelper {
|
||||||
static Future<void> showSaveRoutineDialog(BuildContext context) async {
|
static Future<bool?> showSaveRoutineDialog(BuildContext context) async {
|
||||||
return showDialog<void>(
|
return showDialog<bool?>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||||
@ -54,27 +54,23 @@ class SaveRoutineHelper {
|
|||||||
),
|
),
|
||||||
if (state.isAutomation)
|
if (state.isAutomation)
|
||||||
...state.ifItems.map((item) {
|
...state.ifItems.map((item) {
|
||||||
final functions = state.selectedFunctions[
|
final functions =
|
||||||
item['uniqueCustomId']] ??
|
state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||||
[];
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: SvgPicture.asset(
|
leading: SvgPicture.asset(
|
||||||
item['imagePath'],
|
item['imagePath'],
|
||||||
width: 22,
|
width: 22,
|
||||||
height: 22,
|
height: 22,
|
||||||
),
|
),
|
||||||
title: Text(item['title'],
|
title:
|
||||||
style: const TextStyle(fontSize: 14)),
|
Text(item['title'], style: const TextStyle(fontSize: 14)),
|
||||||
subtitle: Wrap(
|
subtitle: Wrap(
|
||||||
children: functions
|
children: functions
|
||||||
.map((f) => Text(
|
.map((f) => Text(
|
||||||
'${f.operationName}: ${f.value}, ',
|
'${f.operationName}: ${f.value}, ',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: ColorsManager
|
color: ColorsManager.grayColor, fontSize: 8),
|
||||||
.grayColor,
|
overflow: TextOverflow.ellipsis,
|
||||||
fontSize: 8),
|
|
||||||
overflow:
|
|
||||||
TextOverflow.ellipsis,
|
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
))
|
))
|
||||||
.toList(),
|
.toList(),
|
||||||
@ -99,25 +95,22 @@ class SaveRoutineHelper {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
...state.thenItems.map((item) {
|
...state.thenItems.map((item) {
|
||||||
final functions = state.selectedFunctions[
|
final functions =
|
||||||
item['uniqueCustomId']] ??
|
state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||||
[];
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: SvgPicture.asset(
|
leading: SvgPicture.asset(
|
||||||
item['imagePath'],
|
item['imagePath'],
|
||||||
width: 22,
|
width: 22,
|
||||||
height: 22,
|
height: 22,
|
||||||
),
|
),
|
||||||
title: Text(item['title'],
|
title:
|
||||||
style: const TextStyle(fontSize: 14)),
|
Text(item['title'], style: const TextStyle(fontSize: 14)),
|
||||||
subtitle: Wrap(
|
subtitle: Wrap(
|
||||||
children: functions
|
children: functions
|
||||||
.map((f) => Text(
|
.map((f) => Text(
|
||||||
'${f.operationName}: ${f.value}, ',
|
'${f.operationName}: ${f.value}, ',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color:
|
color: ColorsManager.grayColor, fontSize: 8),
|
||||||
ColorsManager.grayColor,
|
|
||||||
fontSize: 8),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
))
|
))
|
||||||
@ -140,19 +133,15 @@ class SaveRoutineHelper {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
DialogFooter(
|
DialogFooter(
|
||||||
onCancel: () => Navigator.pop(context),
|
onCancel: () => Navigator.pop(context, false),
|
||||||
onConfirm: () {
|
onConfirm: () {
|
||||||
if (state.isAutomation) {
|
if (state.isAutomation) {
|
||||||
context
|
context.read<RoutineBloc>().add(const CreateAutomationEvent());
|
||||||
.read<RoutineBloc>()
|
|
||||||
.add(const CreateAutomationEvent());
|
|
||||||
} else {
|
} else {
|
||||||
context
|
context.read<RoutineBloc>().add(const CreateSceneEvent());
|
||||||
.read<RoutineBloc>()
|
|
||||||
.add(const CreateSceneEvent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Navigator.pop(context);
|
Navigator.pop(context, true);
|
||||||
},
|
},
|
||||||
isConfirmEnabled: true,
|
isConfirmEnabled: true,
|
||||||
),
|
),
|
||||||
|
@ -1,177 +1,5 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_scene_model.dart';
|
|
||||||
|
|
||||||
// class CreateAutomationModel {
|
|
||||||
// String unitUuid;
|
|
||||||
// String automationName;
|
|
||||||
// String decisionExpr;
|
|
||||||
// EffectiveTime effectiveTime;
|
|
||||||
// List<CreateCondition> conditions;
|
|
||||||
// List<CreateSceneAction> actions;
|
|
||||||
|
|
||||||
// CreateAutomationModel({
|
|
||||||
// required this.unitUuid,
|
|
||||||
// required this.automationName,
|
|
||||||
// required this.decisionExpr,
|
|
||||||
// required this.effectiveTime,
|
|
||||||
// required this.conditions,
|
|
||||||
// required this.actions,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// CreateAutomationModel copyWith({
|
|
||||||
// String? unitUuid,
|
|
||||||
// String? automationName,
|
|
||||||
// String? decisionExpr,
|
|
||||||
// EffectiveTime? effectiveTime,
|
|
||||||
// List<CreateCondition>? conditions,
|
|
||||||
// List<CreateSceneAction>? actions,
|
|
||||||
// }) {
|
|
||||||
// return CreateAutomationModel(
|
|
||||||
// unitUuid: unitUuid ?? this.unitUuid,
|
|
||||||
// automationName: automationName ?? this.automationName,
|
|
||||||
// decisionExpr: decisionExpr ?? this.decisionExpr,
|
|
||||||
// effectiveTime: effectiveTime ?? this.effectiveTime,
|
|
||||||
// conditions: conditions ?? this.conditions,
|
|
||||||
// actions: actions ?? this.actions,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Map<String, dynamic> toMap([String? automationId]) {
|
|
||||||
// return {
|
|
||||||
// if (automationId == null) 'spaceUuid': unitUuid,
|
|
||||||
// 'automationName': automationName,
|
|
||||||
// 'decisionExpr': decisionExpr,
|
|
||||||
// 'effectiveTime': effectiveTime.toMap(),
|
|
||||||
// 'conditions': conditions.map((x) => x.toMap()).toList(),
|
|
||||||
// 'actions': actions.map((x) => x.toMap()).toList(),
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// factory CreateAutomationModel.fromMap(Map<String, dynamic> map) {
|
|
||||||
// return CreateAutomationModel(
|
|
||||||
// unitUuid: map['spaceUuid'] ?? '',
|
|
||||||
// automationName: map['automationName'] ?? '',
|
|
||||||
// decisionExpr: map['decisionExpr'] ?? '',
|
|
||||||
// effectiveTime: EffectiveTime.fromMap(map['effectiveTime']),
|
|
||||||
// conditions: List<CreateCondition>.from(
|
|
||||||
// map['conditions']?.map((x) => CreateCondition.fromMap(x))),
|
|
||||||
// actions: List<CreateSceneAction>.from(
|
|
||||||
// map['actions']?.map((x) => CreateSceneAction.fromMap(x))),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// String toJson([String? automationId]) => json.encode(toMap(automationId));
|
|
||||||
|
|
||||||
// factory CreateAutomationModel.fromJson(String source) =>
|
|
||||||
// CreateAutomationModel.fromMap(json.decode(source));
|
|
||||||
|
|
||||||
// @override
|
|
||||||
// String toString() {
|
|
||||||
// return 'CreateAutomationModel(unitUuid: $unitUuid, automationName: $automationName, decisionExpr: $decisionExpr, effectiveTime: $effectiveTime, conditions: $conditions, actions: $actions)';
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// class EffectiveTime {
|
|
||||||
// String start;
|
|
||||||
// String end;
|
|
||||||
// String loops;
|
|
||||||
|
|
||||||
// EffectiveTime({
|
|
||||||
// required this.start,
|
|
||||||
// required this.end,
|
|
||||||
// required this.loops,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Map<String, dynamic> toMap() {
|
|
||||||
// return {
|
|
||||||
// 'start': start,
|
|
||||||
// 'end': end,
|
|
||||||
// 'loops': loops,
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// factory EffectiveTime.fromMap(Map<String, dynamic> map) {
|
|
||||||
// return EffectiveTime(
|
|
||||||
// start: map['start'] ?? '',
|
|
||||||
// end: map['end'] ?? '',
|
|
||||||
// loops: map['loops'] ?? '',
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @override
|
|
||||||
// String toString() => 'EffectiveTime(start: $start, end: $end, loops: $loops)';
|
|
||||||
// }
|
|
||||||
|
|
||||||
// class CreateCondition {
|
|
||||||
// int code;
|
|
||||||
// String entityId;
|
|
||||||
// String entityType;
|
|
||||||
// ConditionExpr expr;
|
|
||||||
|
|
||||||
// CreateCondition({
|
|
||||||
// required this.code,
|
|
||||||
// required this.entityId,
|
|
||||||
// required this.entityType,
|
|
||||||
// required this.expr,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Map<String, dynamic> toMap() {
|
|
||||||
// return {
|
|
||||||
// 'code': code,
|
|
||||||
// 'entityId': entityId,
|
|
||||||
// 'entityType': entityType,
|
|
||||||
// 'expr': expr.toMap(),
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// factory CreateCondition.fromMap(Map<String, dynamic> map) {
|
|
||||||
// return CreateCondition(
|
|
||||||
// code: map['code'] ?? 0,
|
|
||||||
// entityId: map['entityId'] ?? '',
|
|
||||||
// entityType: map['entityType'] ?? '',
|
|
||||||
// expr: ConditionExpr.fromMap(map['expr']),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @override
|
|
||||||
// String toString() =>
|
|
||||||
// 'CreateCondition(code: $code, entityId: $entityId, entityType: $entityType, expr: $expr)';
|
|
||||||
// }
|
|
||||||
|
|
||||||
// class ConditionExpr {
|
|
||||||
// String statusCode;
|
|
||||||
// String comparator;
|
|
||||||
// dynamic statusValue;
|
|
||||||
|
|
||||||
// ConditionExpr({
|
|
||||||
// required this.statusCode,
|
|
||||||
// required this.comparator,
|
|
||||||
// required this.statusValue,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Map<String, dynamic> toMap() {
|
|
||||||
// return {
|
|
||||||
// 'statusCode': statusCode,
|
|
||||||
// 'comparator': comparator,
|
|
||||||
// 'statusValue': statusValue,
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// factory ConditionExpr.fromMap(Map<String, dynamic> map) {
|
|
||||||
// return ConditionExpr(
|
|
||||||
// statusCode: map['statusCode'] ?? '',
|
|
||||||
// comparator: map['comparator'] ?? '',
|
|
||||||
// statusValue: map['statusValue'],
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @override
|
|
||||||
// String toString() =>
|
|
||||||
// 'ConditionExpr(statusCode: $statusCode, comparator: $comparator, statusValue: $statusValue)';
|
|
||||||
// }
|
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
class CreateAutomationModel {
|
class CreateAutomationModel {
|
||||||
String spaceUuid;
|
String spaceUuid;
|
||||||
String automationName;
|
String automationName;
|
||||||
|
262
lib/pages/routiens/models/routine_details_model.dart
Normal file
262
lib/pages/routiens/models/routine_details_model.dart
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_scene_model.dart';
|
||||||
|
|
||||||
|
class RoutineDetailsModel {
|
||||||
|
final String spaceUuid;
|
||||||
|
final String name;
|
||||||
|
final String decisionExpr;
|
||||||
|
final List<RoutineAction> actions;
|
||||||
|
final String? iconId;
|
||||||
|
final bool? showInDevice;
|
||||||
|
final EffectiveTime? effectiveTime;
|
||||||
|
final List<RoutineCondition>? conditions;
|
||||||
|
final String? type;
|
||||||
|
|
||||||
|
RoutineDetailsModel({
|
||||||
|
required this.spaceUuid,
|
||||||
|
required this.name,
|
||||||
|
required this.decisionExpr,
|
||||||
|
required this.actions,
|
||||||
|
this.iconId,
|
||||||
|
this.showInDevice,
|
||||||
|
this.effectiveTime,
|
||||||
|
this.conditions,
|
||||||
|
this.type,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert to CreateSceneModel
|
||||||
|
CreateSceneModel toCreateSceneModel() {
|
||||||
|
return CreateSceneModel(
|
||||||
|
spaceUuid: spaceUuid,
|
||||||
|
iconId: iconId ?? '',
|
||||||
|
showInDevice: showInDevice ?? false,
|
||||||
|
sceneName: name,
|
||||||
|
decisionExpr: decisionExpr,
|
||||||
|
actions: actions.map((a) => a.toCreateSceneAction()).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to CreateAutomationModel
|
||||||
|
CreateAutomationModel toCreateAutomationModel() {
|
||||||
|
return CreateAutomationModel(
|
||||||
|
spaceUuid: spaceUuid,
|
||||||
|
automationName: name,
|
||||||
|
decisionExpr: decisionExpr,
|
||||||
|
effectiveTime:
|
||||||
|
effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''),
|
||||||
|
conditions: conditions?.map((c) => c.toCondition()).toList() ?? [],
|
||||||
|
actions: actions.map((a) => a.toAutomationAction()).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'spaceUuid': spaceUuid,
|
||||||
|
'name': name,
|
||||||
|
'decisionExpr': decisionExpr,
|
||||||
|
'actions': actions.map((x) => x.toMap()).toList(),
|
||||||
|
if (iconId != null) 'iconId': iconId,
|
||||||
|
if (showInDevice != null) 'showInDevice': showInDevice,
|
||||||
|
if (effectiveTime != null) 'effectiveTime': effectiveTime!.toMap(),
|
||||||
|
if (conditions != null)
|
||||||
|
'conditions': conditions!.map((x) => x.toMap()).toList(),
|
||||||
|
if (type != null) 'type': type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory RoutineDetailsModel.fromMap(Map<String, dynamic> map) {
|
||||||
|
return RoutineDetailsModel(
|
||||||
|
spaceUuid: map['spaceUuid'] ?? '',
|
||||||
|
name: map['name'] ?? '',
|
||||||
|
decisionExpr: map['decisionExpr'] ?? '',
|
||||||
|
actions: List<RoutineAction>.from(
|
||||||
|
map['actions']?.map((x) => RoutineAction.fromMap(x)) ?? [],
|
||||||
|
),
|
||||||
|
iconId: map['iconId'],
|
||||||
|
showInDevice: map['showInDevice'],
|
||||||
|
effectiveTime: map['effectiveTime'] != null
|
||||||
|
? EffectiveTime.fromMap(map['effectiveTime'])
|
||||||
|
: null,
|
||||||
|
conditions: map['conditions'] != null
|
||||||
|
? List<RoutineCondition>.from(
|
||||||
|
map['conditions'].map((x) => RoutineCondition.fromMap(x)))
|
||||||
|
: null,
|
||||||
|
type: map['type'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String toJson() => json.encode(toMap());
|
||||||
|
|
||||||
|
factory RoutineDetailsModel.fromJson(String source) =>
|
||||||
|
RoutineDetailsModel.fromMap(json.decode(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
class RoutineAction {
|
||||||
|
final String entityId;
|
||||||
|
final String actionExecutor;
|
||||||
|
final RoutineExecutorProperty? executorProperty;
|
||||||
|
|
||||||
|
RoutineAction({
|
||||||
|
required this.entityId,
|
||||||
|
required this.actionExecutor,
|
||||||
|
this.executorProperty,
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateSceneAction toCreateSceneAction() {
|
||||||
|
return CreateSceneAction(
|
||||||
|
entityId: entityId,
|
||||||
|
actionExecutor: actionExecutor,
|
||||||
|
executorProperty: executorProperty?.toCreateSceneExecutorProperty(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
AutomationAction toAutomationAction() {
|
||||||
|
return AutomationAction(
|
||||||
|
entityId: entityId,
|
||||||
|
actionExecutor: actionExecutor,
|
||||||
|
executorProperty: executorProperty?.toExecutorProperty(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'entityId': entityId,
|
||||||
|
'actionExecutor': actionExecutor,
|
||||||
|
if (executorProperty != null)
|
||||||
|
'executorProperty': executorProperty!.toMap(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory RoutineAction.fromMap(Map<String, dynamic> map) {
|
||||||
|
return RoutineAction(
|
||||||
|
entityId: map['entityId'] ?? '',
|
||||||
|
actionExecutor: map['actionExecutor'] ?? '',
|
||||||
|
executorProperty: map['executorProperty'] != null
|
||||||
|
? RoutineExecutorProperty.fromMap(map['executorProperty'])
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RoutineExecutorProperty {
|
||||||
|
final String? functionCode;
|
||||||
|
final dynamic functionValue;
|
||||||
|
final int? delaySeconds;
|
||||||
|
|
||||||
|
RoutineExecutorProperty({
|
||||||
|
this.functionCode,
|
||||||
|
this.functionValue,
|
||||||
|
this.delaySeconds,
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateSceneExecutorProperty toCreateSceneExecutorProperty() {
|
||||||
|
return CreateSceneExecutorProperty(
|
||||||
|
functionCode: functionCode ?? '',
|
||||||
|
functionValue: functionValue,
|
||||||
|
delaySeconds: delaySeconds ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExecutorProperty toExecutorProperty() {
|
||||||
|
return ExecutorProperty(
|
||||||
|
functionCode: functionCode,
|
||||||
|
functionValue: functionValue,
|
||||||
|
delaySeconds: delaySeconds,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
if (functionCode != null) 'functionCode': functionCode,
|
||||||
|
if (functionValue != null) 'functionValue': functionValue,
|
||||||
|
if (delaySeconds != null) 'delaySeconds': delaySeconds,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory RoutineExecutorProperty.fromMap(Map<String, dynamic> map) {
|
||||||
|
return RoutineExecutorProperty(
|
||||||
|
functionCode: map['functionCode'],
|
||||||
|
functionValue: map['functionValue'],
|
||||||
|
delaySeconds: map['delaySeconds']?.toInt(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RoutineCondition {
|
||||||
|
final int code;
|
||||||
|
final String entityId;
|
||||||
|
final String entityType;
|
||||||
|
final RoutineConditionExpr expr;
|
||||||
|
|
||||||
|
RoutineCondition({
|
||||||
|
required this.code,
|
||||||
|
required this.entityId,
|
||||||
|
required this.entityType,
|
||||||
|
required this.expr,
|
||||||
|
});
|
||||||
|
|
||||||
|
Condition toCondition() {
|
||||||
|
return Condition(
|
||||||
|
code: code,
|
||||||
|
entityId: entityId,
|
||||||
|
entityType: entityType,
|
||||||
|
expr: expr.toConditionExpr(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'code': code,
|
||||||
|
'entityId': entityId,
|
||||||
|
'entityType': entityType,
|
||||||
|
'expr': expr.toMap(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory RoutineCondition.fromMap(Map<String, dynamic> map) {
|
||||||
|
return RoutineCondition(
|
||||||
|
code: map['code']?.toInt() ?? 0,
|
||||||
|
entityId: map['entityId'] ?? '',
|
||||||
|
entityType: map['entityType'] ?? '',
|
||||||
|
expr: RoutineConditionExpr.fromMap(map['expr']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RoutineConditionExpr {
|
||||||
|
final String statusCode;
|
||||||
|
final String comparator;
|
||||||
|
final dynamic statusValue;
|
||||||
|
|
||||||
|
RoutineConditionExpr({
|
||||||
|
required this.statusCode,
|
||||||
|
required this.comparator,
|
||||||
|
required this.statusValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
ConditionExpr toConditionExpr() {
|
||||||
|
return ConditionExpr(
|
||||||
|
statusCode: statusCode,
|
||||||
|
comparator: comparator,
|
||||||
|
statusValue: statusValue,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'statusCode': statusCode,
|
||||||
|
'comparator': comparator,
|
||||||
|
'statusValue': statusValue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory RoutineConditionExpr.fromMap(Map<String, dynamic> map) {
|
||||||
|
return RoutineConditionExpr(
|
||||||
|
statusCode: map['statusCode'] ?? '',
|
||||||
|
comparator: map['comparator'] ?? '',
|
||||||
|
statusValue: map['statusValue'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,10 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
|
||||||
class ScenesModel {
|
class ScenesModel {
|
||||||
final String id;
|
final String id;
|
||||||
|
final String? sceneTuyaId;
|
||||||
final String name;
|
final String name;
|
||||||
final String status;
|
final String status;
|
||||||
final String type;
|
final String type;
|
||||||
@ -9,26 +12,43 @@ class ScenesModel {
|
|||||||
|
|
||||||
ScenesModel({
|
ScenesModel({
|
||||||
required this.id,
|
required this.id,
|
||||||
|
this.sceneTuyaId,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.status,
|
required this.status,
|
||||||
required this.type,
|
required this.type,
|
||||||
this.icon,
|
this.icon,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
factory ScenesModel.fromRawJson(String str) =>
|
||||||
|
ScenesModel.fromJson(json.decode(str));
|
||||||
|
|
||||||
|
String toRawJson() => json.encode(toJson());
|
||||||
|
|
||||||
|
Uint8List? get iconInBytes {
|
||||||
|
if (icon == null || icon?.isEmpty == true) return null;
|
||||||
|
try {
|
||||||
|
return base64Decode(icon!);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
factory ScenesModel.fromJson(Map<String, dynamic> json,
|
factory ScenesModel.fromJson(Map<String, dynamic> json,
|
||||||
{bool? isAutomation}) =>
|
{bool? isAutomation}) {
|
||||||
ScenesModel(
|
return ScenesModel(
|
||||||
id: json["id"],
|
id: json["id"] ?? json["uuid"] ?? '',
|
||||||
name: json["name"] ?? '',
|
sceneTuyaId: json["sceneTuyaId"] as String?,
|
||||||
status: json["status"] ?? '',
|
name: json["name"] ?? '',
|
||||||
type: json["type"] ?? '',
|
status: json["status"] ?? '',
|
||||||
icon: (isAutomation ?? false)
|
type: json["type"] ?? '',
|
||||||
? Assets.automation
|
icon:
|
||||||
: json["icon"] as String?,
|
isAutomation == true ? Assets.automation : (json["icon"] as String?),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
"id": id,
|
"id": id,
|
||||||
|
"sceneTuyaId": sceneTuyaId ?? '',
|
||||||
"name": name,
|
"name": name,
|
||||||
"status": status,
|
"status": status,
|
||||||
"type": type,
|
"type": type,
|
||||||
|
@ -6,8 +6,16 @@ import 'package:syncrow_web/pages/routiens/widgets/then_container.dart';
|
|||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
class CreateNewRoutineView extends StatelessWidget {
|
class CreateNewRoutineView extends StatelessWidget {
|
||||||
const CreateNewRoutineView({super.key});
|
final bool isUpdate;
|
||||||
|
final String? routineId;
|
||||||
|
final bool isScene;
|
||||||
|
|
||||||
|
const CreateNewRoutineView({
|
||||||
|
super.key,
|
||||||
|
this.isUpdate = false,
|
||||||
|
this.routineId,
|
||||||
|
this.isScene = true,
|
||||||
|
});
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
|
@ -1,7 +1,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/device_managment/all_devices/bloc/switch_tabs/switch_tabs_bloc.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/view/create_new_routine_view.dart';
|
import 'package:syncrow_web/pages/routiens/view/create_new_routine_view.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/widgets/main_routine_view/fetch_routine_scenes_automation.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/widgets/main_routine_view/routine_view_card.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
class RoutinesView extends StatelessWidget {
|
class RoutinesView extends StatelessWidget {
|
||||||
@ -23,49 +26,30 @@ class RoutinesView extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Create New Routines",
|
"Create New Routines",
|
||||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: ColorsManager.grayColor,
|
color: ColorsManager.grayColor,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
const SizedBox(
|
||||||
height: 200,
|
height: 10,
|
||||||
width: 150,
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
BlocProvider.of<SwitchTabsBloc>(context).add(
|
|
||||||
const CreateNewRoutineViewEvent(true),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Card(
|
|
||||||
elevation: 3,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
color: ColorsManager.whiteColors,
|
|
||||||
child: Center(
|
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: ColorsManager.graysColor,
|
|
||||||
borderRadius: BorderRadius.circular(120),
|
|
||||||
border: Border.all(
|
|
||||||
color: ColorsManager.greyColor,
|
|
||||||
width: 2.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
height: 70,
|
|
||||||
width: 70,
|
|
||||||
child: Icon(
|
|
||||||
Icons.add,
|
|
||||||
color: ColorsManager.dialogBlueTitle,
|
|
||||||
size: 40,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const Spacer(),
|
RoutineViewCard(
|
||||||
|
onTap: () {
|
||||||
|
BlocProvider.of<SwitchTabsBloc>(context).add(
|
||||||
|
const CreateNewRoutineViewEvent(true),
|
||||||
|
);
|
||||||
|
context.read<RoutineBloc>().add(
|
||||||
|
(ResetRoutineState()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
icon: Icons.add,
|
||||||
|
textString: '',
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 15,
|
||||||
|
),
|
||||||
|
const Expanded(child: FetchRoutineScenesAutomation()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
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:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
@ -81,7 +83,9 @@ class DraggableCard extends StatelessWidget {
|
|||||||
? SvgPicture.asset(
|
? SvgPicture.asset(
|
||||||
imagePath,
|
imagePath,
|
||||||
)
|
)
|
||||||
: Image.network(imagePath),
|
: Image.memory(
|
||||||
|
base64Decode(imagePath),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Padding(
|
Padding(
|
||||||
|
@ -26,8 +26,10 @@ class IfContainer extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
const Text('IF', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
const Text('IF',
|
||||||
if (state.isAutomation)
|
style: TextStyle(
|
||||||
|
fontSize: 18, fontWeight: FontWeight.bold)),
|
||||||
|
if (state.isAutomation && state.ifItems.isNotEmpty)
|
||||||
AutomationOperatorSelector(
|
AutomationOperatorSelector(
|
||||||
selectedOperator: state.selectedAutomationOperator),
|
selectedOperator: state.selectedAutomationOperator),
|
||||||
],
|
],
|
||||||
@ -53,33 +55,44 @@ class IfContainer extends StatelessWidget {
|
|||||||
(index) => GestureDetector(
|
(index) => GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (!state.isTabToRun) {
|
if (!state.isTabToRun) {
|
||||||
final result = await DeviceDialogHelper.showDeviceDialog(
|
final result = await DeviceDialogHelper
|
||||||
context, state.ifItems[index]);
|
.showDeviceDialog(
|
||||||
|
context, state.ifItems[index],
|
||||||
|
removeComparetors: false);
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context
|
context.read<RoutineBloc>().add(
|
||||||
.read<RoutineBloc>()
|
AddToIfContainer(
|
||||||
.add(AddToIfContainer(state.ifItems[index], false));
|
state.ifItems[index], false));
|
||||||
} else if (!['AC', '1G', '2G', '3G']
|
} else if (![
|
||||||
.contains(state.ifItems[index]['productType'])) {
|
'AC',
|
||||||
context
|
'1G',
|
||||||
.read<RoutineBloc>()
|
'2G',
|
||||||
.add(AddToIfContainer(state.ifItems[index], false));
|
'3G'
|
||||||
|
].contains(
|
||||||
|
state.ifItems[index]['productType'])) {
|
||||||
|
context.read<RoutineBloc>().add(
|
||||||
|
AddToIfContainer(
|
||||||
|
state.ifItems[index], false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: DraggableCard(
|
child: DraggableCard(
|
||||||
imagePath: state.ifItems[index]['imagePath'] ?? '',
|
imagePath:
|
||||||
|
state.ifItems[index]['imagePath'] ?? '',
|
||||||
title: state.ifItems[index]['title'] ?? '',
|
title: state.ifItems[index]['title'] ?? '',
|
||||||
deviceData: state.ifItems[index],
|
deviceData: state.ifItems[index],
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 8),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 4, vertical: 8),
|
||||||
isFromThen: false,
|
isFromThen: false,
|
||||||
isFromIf: true,
|
isFromIf: true,
|
||||||
onRemove: () {
|
onRemove: () {
|
||||||
context.read<RoutineBloc>().add(RemoveDragCard(
|
context.read<RoutineBloc>().add(
|
||||||
index: index,
|
RemoveDragCard(
|
||||||
isFromThen: false,
|
index: index,
|
||||||
key: state.ifItems[index]['uniqueCustomId']));
|
isFromThen: false,
|
||||||
|
key: state.ifItems[index]
|
||||||
|
['uniqueCustomId']));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
@ -88,23 +101,35 @@ class IfContainer extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onWillAccept: (data) => data != null,
|
onAcceptWithDetails: (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.data);
|
||||||
mutableData['uniqueCustomId'] = uniqueCustomId;
|
mutableData['uniqueCustomId'] = uniqueCustomId;
|
||||||
|
|
||||||
|
if (state.isAutomation && mutableData['deviceId'] == 'tab_to_run') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!state.isTabToRun) {
|
if (!state.isTabToRun) {
|
||||||
if (mutableData['deviceId'] == 'tab_to_run') {
|
if (mutableData['deviceId'] == 'tab_to_run') {
|
||||||
context.read<RoutineBloc>().add(AddToIfContainer(mutableData, true));
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(AddToIfContainer(mutableData, true));
|
||||||
} else {
|
} else {
|
||||||
final result = await DeviceDialogHelper.showDeviceDialog(context, mutableData);
|
final result = await DeviceDialogHelper.showDeviceDialog(
|
||||||
|
context, mutableData,
|
||||||
|
removeComparetors: false);
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context.read<RoutineBloc>().add(AddToIfContainer(mutableData, false));
|
context
|
||||||
} else if (!['AC', '1G', '2G', '3G'].contains(mutableData['productType'])) {
|
.read<RoutineBloc>()
|
||||||
context.read<RoutineBloc>().add(AddToIfContainer(mutableData, false));
|
.add(AddToIfContainer(mutableData, false));
|
||||||
|
} else if (!['AC', '1G', '2G', '3G']
|
||||||
|
.contains(mutableData['productType'])) {
|
||||||
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(AddToIfContainer(mutableData, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,7 +159,7 @@ class AutomationOperatorSelector extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
TextButton(
|
TextButton(
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
backgroundColor: selectedOperator == 'or'
|
backgroundColor: selectedOperator.toLowerCase() == 'or'
|
||||||
? ColorsManager.dialogBlueTitle
|
? ColorsManager.dialogBlueTitle
|
||||||
: ColorsManager.whiteColors,
|
: ColorsManager.whiteColors,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
@ -144,12 +169,15 @@ class AutomationOperatorSelector extends StatelessWidget {
|
|||||||
child: Text(
|
child: Text(
|
||||||
'Any condition is met',
|
'Any condition is met',
|
||||||
style: context.textTheme.bodyMedium?.copyWith(
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
color:
|
color: selectedOperator.toLowerCase() == 'or'
|
||||||
selectedOperator == 'or' ? ColorsManager.whiteColors : ColorsManager.blackColor,
|
? ColorsManager.whiteColors
|
||||||
|
: ColorsManager.blackColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.read<RoutineBloc>().add(const ChangeAutomationOperator(operator: 'or'));
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(const ChangeAutomationOperator(operator: 'or'));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
@ -159,7 +187,7 @@ class AutomationOperatorSelector extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
backgroundColor: selectedOperator == 'and'
|
backgroundColor: selectedOperator.toLowerCase() == 'and'
|
||||||
? ColorsManager.dialogBlueTitle
|
? ColorsManager.dialogBlueTitle
|
||||||
: ColorsManager.whiteColors,
|
: ColorsManager.whiteColors,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
@ -169,13 +197,15 @@ class AutomationOperatorSelector extends StatelessWidget {
|
|||||||
child: Text(
|
child: Text(
|
||||||
'All condition is met',
|
'All condition is met',
|
||||||
style: context.textTheme.bodyMedium?.copyWith(
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
color: selectedOperator == 'and'
|
color: selectedOperator.toLowerCase() == 'and'
|
||||||
? ColorsManager.whiteColors
|
? ColorsManager.whiteColors
|
||||||
: ColorsManager.blackColor,
|
: ColorsManager.blackColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.read<RoutineBloc>().add(const ChangeAutomationOperator(operator: 'and'));
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(const ChangeAutomationOperator(operator: 'and'));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -0,0 +1,196 @@
|
|||||||
|
import 'package:flutter/material.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/widgets/main_routine_view/routine_view_card.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
class FetchRoutineScenesAutomation extends StatefulWidget {
|
||||||
|
const FetchRoutineScenesAutomation({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FetchRoutineScenesAutomation> createState() =>
|
||||||
|
_FetchRoutineScenesState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
|
||||||
|
with HelperResponsiveLayout {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
context.read<RoutineBloc>()
|
||||||
|
..add(const LoadScenes(spaceId, communityId))
|
||||||
|
..add(const LoadAutomation(spaceId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return state.isLoading
|
||||||
|
? const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
)
|
||||||
|
: SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Scenes (Tab to Run)",
|
||||||
|
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||||
|
color: ColorsManager.grayColor,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
if (state.scenes.isEmpty)
|
||||||
|
Text(
|
||||||
|
"No scenes found",
|
||||||
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: ColorsManager.grayColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (state.scenes.isNotEmpty)
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
maxHeight: isSmallScreenSize(context) ? 160 : 170,
|
||||||
|
),
|
||||||
|
child: ListView.builder(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
itemCount: state.scenes.length,
|
||||||
|
itemBuilder: (context, index) => Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
right: isSmallScreenSize(context) ? 4.0 : 8.0,
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
RoutineViewCard(
|
||||||
|
onTap: () {},
|
||||||
|
textString: state.scenes[index].name,
|
||||||
|
icon: state.scenes[index].icon ??
|
||||||
|
Assets.logoHorizontal,
|
||||||
|
isFromScenes: true,
|
||||||
|
iconInBytes:
|
||||||
|
state.scenes[index].iconInBytes,
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () => context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(
|
||||||
|
DeleteScene(
|
||||||
|
sceneId: state.scenes[index].id,
|
||||||
|
unitUuid: spaceId,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
height: 20,
|
||||||
|
width: 20,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.whiteColors,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(
|
||||||
|
color: ColorsManager.grayColor,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: const Center(
|
||||||
|
child: Icon(Icons.delete,
|
||||||
|
size: 15,
|
||||||
|
color: ColorsManager.grayColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 15),
|
||||||
|
Text(
|
||||||
|
"Automations",
|
||||||
|
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||||
|
color: ColorsManager.grayColor,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
if (state.automations.isEmpty)
|
||||||
|
Text(
|
||||||
|
"No automations found",
|
||||||
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: ColorsManager.grayColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (state.automations.isNotEmpty)
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
maxHeight: isSmallScreenSize(context) ? 160 : 170,
|
||||||
|
),
|
||||||
|
child: ListView.builder(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
itemCount: state.automations.length,
|
||||||
|
itemBuilder: (context, index) => Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
right: isSmallScreenSize(context) ? 4.0 : 8.0,
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
RoutineViewCard(
|
||||||
|
onTap: () {},
|
||||||
|
textString: state.automations[index].name,
|
||||||
|
icon: state.automations[index].icon ??
|
||||||
|
Assets.automation,
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () =>
|
||||||
|
context.read<RoutineBloc>().add(
|
||||||
|
DeleteAutomation(
|
||||||
|
automationId: state
|
||||||
|
.automations[index].id,
|
||||||
|
unitUuid: spaceId,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
height: 20,
|
||||||
|
width: 20,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.whiteColors,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(
|
||||||
|
color: ColorsManager.grayColor,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: const Center(
|
||||||
|
child: Icon(Icons.delete,
|
||||||
|
size: 15,
|
||||||
|
color: ColorsManager.grayColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,127 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
class RoutineViewCard extends StatelessWidget with HelperResponsiveLayout {
|
||||||
|
const RoutineViewCard({
|
||||||
|
super.key,
|
||||||
|
required this.onTap,
|
||||||
|
required this.icon,
|
||||||
|
required this.textString,
|
||||||
|
this.isFromScenes,
|
||||||
|
this.iconInBytes,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Function() onTap;
|
||||||
|
final dynamic icon;
|
||||||
|
final String textString;
|
||||||
|
final bool? isFromScenes;
|
||||||
|
final Uint8List? iconInBytes;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final double cardWidth = isSmallScreenSize(context)
|
||||||
|
? 120
|
||||||
|
: isMediumScreenSize(context)
|
||||||
|
? 135
|
||||||
|
: 150;
|
||||||
|
|
||||||
|
final double cardHeight = isSmallScreenSize(context) ? 160 : 170;
|
||||||
|
|
||||||
|
final double iconSize = isSmallScreenSize(context)
|
||||||
|
? 50
|
||||||
|
: isMediumScreenSize(context)
|
||||||
|
? 60
|
||||||
|
: 70;
|
||||||
|
|
||||||
|
return ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
maxWidth: cardWidth,
|
||||||
|
maxHeight: cardHeight,
|
||||||
|
),
|
||||||
|
child: Card(
|
||||||
|
elevation: 3,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
color: ColorsManager.whiteColors,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onTap,
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.graysColor,
|
||||||
|
borderRadius: BorderRadius.circular(120),
|
||||||
|
border: Border.all(
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
height: iconSize,
|
||||||
|
width: iconSize,
|
||||||
|
child: (isFromScenes ?? false)
|
||||||
|
? (iconInBytes != null &&
|
||||||
|
iconInBytes?.isNotEmpty == true)
|
||||||
|
? Image.memory(
|
||||||
|
iconInBytes!,
|
||||||
|
height: iconSize,
|
||||||
|
width: iconSize,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
errorBuilder: (context, error, stackTrace) =>
|
||||||
|
Image.asset(
|
||||||
|
Assets.logo,
|
||||||
|
height: iconSize,
|
||||||
|
width: iconSize,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Image.asset(
|
||||||
|
Assets.logo,
|
||||||
|
height: iconSize,
|
||||||
|
width: iconSize,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
)
|
||||||
|
: (icon is String && icon.endsWith('.svg'))
|
||||||
|
? SvgPicture.asset(
|
||||||
|
icon,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
)
|
||||||
|
: Icon(
|
||||||
|
icon,
|
||||||
|
color: ColorsManager.dialogBlueTitle,
|
||||||
|
size: isSmallScreenSize(context) ? 30 : 40,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 3),
|
||||||
|
child: Text(
|
||||||
|
textString,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 2,
|
||||||
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
fontSize: isSmallScreenSize(context) ? 10 : 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -75,7 +75,11 @@ class PeriodOptions extends StatelessWidget {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
context.read<EffectPeriodBloc>().add(SetPeriod(value));
|
context.read<EffectPeriodBloc>().add(SetPeriod(value));
|
||||||
},
|
},
|
||||||
title: Text(EffectPeriodHelper.formatEnumValue(value)),
|
title: Text(
|
||||||
|
EffectPeriodHelper.formatEnumValue(value),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
|
color: ColorsManager.blackColor, fontWeight: FontWeight.w400, fontSize: 12),
|
||||||
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
subtitle,
|
subtitle,
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
|
@ -19,6 +19,7 @@ class ACHelper {
|
|||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
List<DeviceFunctionData>? deviceSelectedFunctions,
|
List<DeviceFunctionData>? deviceSelectedFunctions,
|
||||||
String uniqueCustomId,
|
String uniqueCustomId,
|
||||||
|
bool? removeComparetors,
|
||||||
) async {
|
) async {
|
||||||
List<ACFunction> acFunctions = functions.whereType<ACFunction>().toList();
|
List<ACFunction> acFunctions = functions.whereType<ACFunction>().toList();
|
||||||
|
|
||||||
@ -84,6 +85,7 @@ class ACHelper {
|
|||||||
acFunctions: acFunctions,
|
acFunctions: acFunctions,
|
||||||
device: device,
|
device: device,
|
||||||
operationName: selectedOperationName ?? '',
|
operationName: selectedOperationName ?? '',
|
||||||
|
removeComparators: removeComparetors,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -179,6 +181,7 @@ class ACHelper {
|
|||||||
required List<ACFunction> acFunctions,
|
required List<ACFunction> acFunctions,
|
||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
required String operationName,
|
required String operationName,
|
||||||
|
bool? removeComparators,
|
||||||
}) {
|
}) {
|
||||||
if (selectedFunction == 'temp_set' || selectedFunction == 'temp_current') {
|
if (selectedFunction == 'temp_set' || selectedFunction == 'temp_current') {
|
||||||
final initialValue = selectedFunctionData?.value ?? 200;
|
final initialValue = selectedFunctionData?.value ?? 200;
|
||||||
@ -190,6 +193,7 @@ class ACHelper {
|
|||||||
device: device,
|
device: device,
|
||||||
operationName: operationName,
|
operationName: operationName,
|
||||||
selectedFunctionData: selectedFunctionData,
|
selectedFunctionData: selectedFunctionData,
|
||||||
|
removeComparators: removeComparators,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,18 +221,20 @@ class ACHelper {
|
|||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
required String operationName,
|
required String operationName,
|
||||||
DeviceFunctionData? selectedFunctionData,
|
DeviceFunctionData? selectedFunctionData,
|
||||||
|
bool? removeComparators,
|
||||||
}) {
|
}) {
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_buildConditionToggle(
|
if (removeComparators != true)
|
||||||
context,
|
_buildConditionToggle(
|
||||||
currentCondition,
|
context,
|
||||||
selectCode,
|
currentCondition,
|
||||||
device,
|
selectCode,
|
||||||
operationName,
|
device,
|
||||||
selectedFunctionData,
|
operationName,
|
||||||
),
|
selectedFunctionData,
|
||||||
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_buildTemperatureDisplay(
|
_buildTemperatureDisplay(
|
||||||
context,
|
context,
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
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/common/custom_table.dart';
|
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_bloc.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_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/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
@ -20,6 +20,7 @@ class OneGangSwitchHelper {
|
|||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
List<DeviceFunctionData>? deviceSelectedFunctions,
|
List<DeviceFunctionData>? deviceSelectedFunctions,
|
||||||
String uniqueCustomId,
|
String uniqueCustomId,
|
||||||
|
bool removeComparetors,
|
||||||
) async {
|
) async {
|
||||||
List<BaseSwitchFunction> acFunctions =
|
List<BaseSwitchFunction> acFunctions =
|
||||||
functions.whereType<BaseSwitchFunction>().toList();
|
functions.whereType<BaseSwitchFunction>().toList();
|
||||||
@ -106,6 +107,7 @@ class OneGangSwitchHelper {
|
|||||||
acFunctions: acFunctions,
|
acFunctions: acFunctions,
|
||||||
device: device,
|
device: device,
|
||||||
operationName: selectedOperationName ?? '',
|
operationName: selectedOperationName ?? '',
|
||||||
|
removeComparetors: removeComparetors,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -162,6 +164,7 @@ class OneGangSwitchHelper {
|
|||||||
required List<BaseSwitchFunction> acFunctions,
|
required List<BaseSwitchFunction> acFunctions,
|
||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
required String operationName,
|
required String operationName,
|
||||||
|
required bool removeComparetors,
|
||||||
}) {
|
}) {
|
||||||
if (selectedFunction == 'countdown_1') {
|
if (selectedFunction == 'countdown_1') {
|
||||||
final initialValue = selectedFunctionData?.value ?? 200;
|
final initialValue = selectedFunctionData?.value ?? 200;
|
||||||
@ -173,6 +176,7 @@ class OneGangSwitchHelper {
|
|||||||
device: device,
|
device: device,
|
||||||
operationName: operationName,
|
operationName: operationName,
|
||||||
selectedFunctionData: selectedFunctionData,
|
selectedFunctionData: selectedFunctionData,
|
||||||
|
removeComparetors: removeComparetors,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,18 +203,20 @@ class OneGangSwitchHelper {
|
|||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
required String operationName,
|
required String operationName,
|
||||||
DeviceFunctionData? selectedFunctionData,
|
DeviceFunctionData? selectedFunctionData,
|
||||||
|
required bool removeComparetors,
|
||||||
}) {
|
}) {
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_buildConditionToggle(
|
if (removeComparetors != true)
|
||||||
context,
|
_buildConditionToggle(
|
||||||
currentCondition,
|
context,
|
||||||
selectCode,
|
currentCondition,
|
||||||
device,
|
selectCode,
|
||||||
operationName,
|
device,
|
||||||
selectedFunctionData,
|
operationName,
|
||||||
),
|
selectedFunctionData,
|
||||||
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_buildCountDownDisplay(context, initialValue, device, operationName,
|
_buildCountDownDisplay(context, initialValue, device, operationName,
|
||||||
selectedFunctionData, selectCode),
|
selectedFunctionData, selectCode),
|
||||||
|
@ -20,6 +20,7 @@ class ThreeGangSwitchHelper {
|
|||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
List<DeviceFunctionData>? deviceSelectedFunctions,
|
List<DeviceFunctionData>? deviceSelectedFunctions,
|
||||||
String uniqueCustomId,
|
String uniqueCustomId,
|
||||||
|
bool removeComparetors,
|
||||||
) async {
|
) async {
|
||||||
List<BaseSwitchFunction> switchFunctions =
|
List<BaseSwitchFunction> switchFunctions =
|
||||||
functions.whereType<BaseSwitchFunction>().toList();
|
functions.whereType<BaseSwitchFunction>().toList();
|
||||||
@ -106,6 +107,7 @@ class ThreeGangSwitchHelper {
|
|||||||
switchFunctions: switchFunctions,
|
switchFunctions: switchFunctions,
|
||||||
device: device,
|
device: device,
|
||||||
operationName: selectedOperationName ?? '',
|
operationName: selectedOperationName ?? '',
|
||||||
|
removeComparetors: removeComparetors,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -162,6 +164,7 @@ class ThreeGangSwitchHelper {
|
|||||||
required List<BaseSwitchFunction> switchFunctions,
|
required List<BaseSwitchFunction> switchFunctions,
|
||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
required String operationName,
|
required String operationName,
|
||||||
|
required bool removeComparetors,
|
||||||
}) {
|
}) {
|
||||||
if (selectedFunction == 'countdown_1' ||
|
if (selectedFunction == 'countdown_1' ||
|
||||||
selectedFunction == 'countdown_2' ||
|
selectedFunction == 'countdown_2' ||
|
||||||
@ -175,6 +178,7 @@ class ThreeGangSwitchHelper {
|
|||||||
device: device,
|
device: device,
|
||||||
operationName: operationName,
|
operationName: operationName,
|
||||||
selectedFunctionData: selectedFunctionData,
|
selectedFunctionData: selectedFunctionData,
|
||||||
|
removeComparetors: removeComparetors,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,18 +205,20 @@ class ThreeGangSwitchHelper {
|
|||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
required String operationName,
|
required String operationName,
|
||||||
DeviceFunctionData? selectedFunctionData,
|
DeviceFunctionData? selectedFunctionData,
|
||||||
|
bool? removeComparetors,
|
||||||
}) {
|
}) {
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_buildConditionToggle(
|
if (removeComparetors != true)
|
||||||
context,
|
_buildConditionToggle(
|
||||||
currentCondition,
|
context,
|
||||||
selectCode,
|
currentCondition,
|
||||||
device,
|
selectCode,
|
||||||
operationName,
|
device,
|
||||||
selectedFunctionData,
|
operationName,
|
||||||
),
|
selectedFunctionData,
|
||||||
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_buildCountDownDisplay(context, initialValue, device, operationName,
|
_buildCountDownDisplay(context, initialValue, device, operationName,
|
||||||
selectedFunctionData, selectCode),
|
selectedFunctionData, selectCode),
|
||||||
|
@ -20,6 +20,7 @@ class TwoGangSwitchHelper {
|
|||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
List<DeviceFunctionData>? deviceSelectedFunctions,
|
List<DeviceFunctionData>? deviceSelectedFunctions,
|
||||||
String uniqueCustomId,
|
String uniqueCustomId,
|
||||||
|
bool removeComparetors,
|
||||||
) async {
|
) async {
|
||||||
List<BaseSwitchFunction> switchFunctions =
|
List<BaseSwitchFunction> switchFunctions =
|
||||||
functions.whereType<BaseSwitchFunction>().toList();
|
functions.whereType<BaseSwitchFunction>().toList();
|
||||||
@ -106,6 +107,7 @@ class TwoGangSwitchHelper {
|
|||||||
switchFunctions: switchFunctions,
|
switchFunctions: switchFunctions,
|
||||||
device: device,
|
device: device,
|
||||||
operationName: selectedOperationName ?? '',
|
operationName: selectedOperationName ?? '',
|
||||||
|
removeComparetors: removeComparetors,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -162,6 +164,7 @@ class TwoGangSwitchHelper {
|
|||||||
required List<BaseSwitchFunction> switchFunctions,
|
required List<BaseSwitchFunction> switchFunctions,
|
||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
required String operationName,
|
required String operationName,
|
||||||
|
required bool removeComparetors,
|
||||||
}) {
|
}) {
|
||||||
if (selectedFunction == 'countdown_1' ||
|
if (selectedFunction == 'countdown_1' ||
|
||||||
selectedFunction == 'countdown_2') {
|
selectedFunction == 'countdown_2') {
|
||||||
@ -174,6 +177,7 @@ class TwoGangSwitchHelper {
|
|||||||
device: device,
|
device: device,
|
||||||
operationName: operationName,
|
operationName: operationName,
|
||||||
selectedFunctionData: selectedFunctionData,
|
selectedFunctionData: selectedFunctionData,
|
||||||
|
removeComparetors: removeComparetors,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,18 +204,20 @@ class TwoGangSwitchHelper {
|
|||||||
AllDevicesModel? device,
|
AllDevicesModel? device,
|
||||||
required String operationName,
|
required String operationName,
|
||||||
DeviceFunctionData? selectedFunctionData,
|
DeviceFunctionData? selectedFunctionData,
|
||||||
|
bool? removeComparetors,
|
||||||
}) {
|
}) {
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_buildConditionToggle(
|
if (removeComparetors != true)
|
||||||
context,
|
_buildConditionToggle(
|
||||||
currentCondition,
|
context,
|
||||||
selectCode,
|
currentCondition,
|
||||||
device,
|
selectCode,
|
||||||
operationName,
|
device,
|
||||||
selectedFunctionData,
|
operationName,
|
||||||
),
|
selectedFunctionData,
|
||||||
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_buildCountDownDisplay(context, initialValue, device, operationName,
|
_buildCountDownDisplay(context, initialValue, device, operationName,
|
||||||
selectedFunctionData, selectCode),
|
selectedFunctionData, selectCode),
|
||||||
|
@ -1,6 +1,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/common/buttons/default_button.dart';
|
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_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/save_routine_helper.dart';
|
import 'package:syncrow_web/pages/routiens/helper/save_routine_helper.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/discard_dialog.dart';
|
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/discard_dialog.dart';
|
||||||
@ -173,7 +174,7 @@ class RoutineSearchAndButtons extends StatelessWidget {
|
|||||||
width: 200,
|
width: 200,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: DefaultButton(
|
child: DefaultButton(
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
if (state.routineName == null || state.routineName!.isEmpty) {
|
if (state.routineName == null || state.routineName!.isEmpty) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
@ -207,7 +208,16 @@ class RoutineSearchAndButtons extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SaveRoutineHelper.showSaveRoutineDialog(context);
|
final result =
|
||||||
|
await SaveRoutineHelper.showSaveRoutineDialog(context);
|
||||||
|
if (result != null && result) {
|
||||||
|
BlocProvider.of<SwitchTabsBloc>(context).add(
|
||||||
|
const CreateNewRoutineViewEvent(false),
|
||||||
|
);
|
||||||
|
BlocProvider.of<SwitchTabsBloc>(context).add(
|
||||||
|
const TriggerSwitchTabsEvent(true),
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
borderRadius: 15,
|
borderRadius: 15,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
|
@ -18,7 +18,7 @@ class _ScenesAndAutomationsState extends State<ScenesAndAutomations> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
context.read<RoutineBloc>()
|
context.read<RoutineBloc>()
|
||||||
..add(const LoadScenes(spaceId))
|
..add(const LoadScenes(spaceId, communityId))
|
||||||
..add(const LoadAutomation(spaceId));
|
..add(const LoadAutomation(spaceId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,7 +34,9 @@ class _ScenesAndAutomationsState extends State<ScenesAndAutomations> {
|
|||||||
children: scenes.asMap().entries.map((entry) {
|
children: scenes.asMap().entries.map((entry) {
|
||||||
final scene = entry.value;
|
final scene = entry.value;
|
||||||
if (state.searchText != null && state.searchText!.isNotEmpty) {
|
if (state.searchText != null && state.searchText!.isNotEmpty) {
|
||||||
return scene.name.toLowerCase().contains(state.searchText!.toLowerCase())
|
return scene.name
|
||||||
|
.toLowerCase()
|
||||||
|
.contains(state.searchText!.toLowerCase())
|
||||||
? DraggableCard(
|
? DraggableCard(
|
||||||
imagePath: scene.icon ?? Assets.loginLogo,
|
imagePath: scene.icon ?? Assets.loginLogo,
|
||||||
title: scene.name,
|
title: scene.name,
|
||||||
|
@ -26,7 +26,9 @@ class ThenContainer extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text('THEN', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
const Text('THEN',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18, fontWeight: FontWeight.bold)),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Wrap(
|
Wrap(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
@ -35,12 +37,16 @@ class ThenContainer extends StatelessWidget {
|
|||||||
state.thenItems.length,
|
state.thenItems.length,
|
||||||
(index) => GestureDetector(
|
(index) => GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (state.thenItems[index]['deviceId'] == 'delay') {
|
if (state.thenItems[index]['deviceId'] ==
|
||||||
final result = await DelayHelper.showDelayPickerDialog(
|
'delay') {
|
||||||
context, state.thenItems[index]);
|
final result = await DelayHelper
|
||||||
|
.showDelayPickerDialog(
|
||||||
|
context, state.thenItems[index]);
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context.read<RoutineBloc>().add(AddToThenContainer({
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(AddToThenContainer({
|
||||||
...state.thenItems[index],
|
...state.thenItems[index],
|
||||||
'imagePath': Assets.delay,
|
'imagePath': Assets.delay,
|
||||||
'title': 'Delay',
|
'title': 'Delay',
|
||||||
@ -49,32 +55,41 @@ class ThenContainer extends StatelessWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await DeviceDialogHelper.showDeviceDialog(
|
final result = await DeviceDialogHelper
|
||||||
context, state.thenItems[index]);
|
.showDeviceDialog(
|
||||||
|
context, state.thenItems[index],
|
||||||
|
removeComparetors: true);
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context
|
context.read<RoutineBloc>().add(
|
||||||
.read<RoutineBloc>()
|
AddToThenContainer(
|
||||||
.add(AddToThenContainer(state.thenItems[index]));
|
state.thenItems[index]));
|
||||||
} else if (!['AC', '1G', '2G', '3G']
|
} else if (!['AC', '1G', '2G', '3G']
|
||||||
.contains(state.thenItems[index]['productType'])) {
|
.contains(state.thenItems[index]
|
||||||
context
|
['productType'])) {
|
||||||
.read<RoutineBloc>()
|
context.read<RoutineBloc>().add(
|
||||||
.add(AddToThenContainer(state.thenItems[index]));
|
AddToThenContainer(
|
||||||
|
state.thenItems[index]));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: DraggableCard(
|
child: DraggableCard(
|
||||||
imagePath: state.thenItems[index]['imagePath'] ?? '',
|
imagePath: state.thenItems[index]
|
||||||
title: state.thenItems[index]['title'] ?? '',
|
['imagePath'] ??
|
||||||
|
'',
|
||||||
|
title:
|
||||||
|
state.thenItems[index]['title'] ?? '',
|
||||||
deviceData: state.thenItems[index],
|
deviceData: state.thenItems[index],
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 8),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 4, vertical: 8),
|
||||||
isFromThen: true,
|
isFromThen: true,
|
||||||
isFromIf: false,
|
isFromIf: false,
|
||||||
onRemove: () {
|
onRemove: () {
|
||||||
context.read<RoutineBloc>().add(RemoveDragCard(
|
context.read<RoutineBloc>().add(
|
||||||
index: index,
|
RemoveDragCard(
|
||||||
isFromThen: true,
|
index: index,
|
||||||
key: state.thenItems[index]['uniqueCustomId']));
|
isFromThen: true,
|
||||||
|
key: state.thenItems[index]
|
||||||
|
['uniqueCustomId']));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
))),
|
))),
|
||||||
@ -83,21 +98,6 @@ class ThenContainer extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
// onWillAcceptWithDetails: (data) {
|
|
||||||
// if (data == null) return false;
|
|
||||||
// return data.data;
|
|
||||||
|
|
||||||
// // 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;
|
|
||||||
// },
|
|
||||||
onAcceptWithDetails: (data) async {
|
onAcceptWithDetails: (data) async {
|
||||||
final uniqueCustomId = const Uuid().v4();
|
final uniqueCustomId = const Uuid().v4();
|
||||||
final mutableData = Map<String, dynamic>.from(data.data);
|
final mutableData = Map<String, dynamic>.from(data.data);
|
||||||
@ -128,8 +128,23 @@ class ThenContainer extends StatelessWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mutableData['type'] == 'tap_to_run' && state.isAutomation) {
|
||||||
|
context.read<RoutineBloc>().add(AddToThenContainer({
|
||||||
|
...mutableData,
|
||||||
|
'imagePath': Assets.logo,
|
||||||
|
'title': mutableData['name'],
|
||||||
|
}));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mutableData['type'] == 'tap_to_run' && !state.isAutomation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mutableData['deviceId'] == 'delay') {
|
if (mutableData['deviceId'] == 'delay') {
|
||||||
final result = await DelayHelper.showDelayPickerDialog(context, mutableData);
|
final result =
|
||||||
|
await DelayHelper.showDelayPickerDialog(context, mutableData);
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context.read<RoutineBloc>().add(AddToThenContainer({
|
context.read<RoutineBloc>().add(AddToThenContainer({
|
||||||
@ -141,11 +156,13 @@ class ThenContainer extends StatelessWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await DeviceDialogHelper.showDeviceDialog(context, mutableData);
|
final result = await DeviceDialogHelper.showDeviceDialog(
|
||||||
|
context, mutableData,
|
||||||
|
removeComparetors: true);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
||||||
} else if (!['AC', '1G', '2G', '3G'].contains(mutableData['productType'])) {
|
} else if (!['AC', '1G', '2G', '3G']
|
||||||
|
.contains(mutableData['productType'])) {
|
||||||
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_automation_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_scene_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_scene_model.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/icon_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/icon_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/models/routine_details_model.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||||
@ -67,17 +68,24 @@ class SceneApi {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
//get scene by unit id
|
//get scenes by community id and space id
|
||||||
|
|
||||||
static Future<List<ScenesModel>> getScenesByUnitId(String unitId) async {
|
static Future<List<ScenesModel>> getScenesByUnitId(
|
||||||
|
String unitId, String communityId,
|
||||||
|
{showInDevice = false}) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getSpaceScenes.replaceAll('{unitUuid}', unitId),
|
path: ApiEndpoints.getUnitScenes
|
||||||
|
.replaceAll('{spaceUuid}', unitId)
|
||||||
|
.replaceAll('{communityUuid}', communityId),
|
||||||
|
queryParameters: {'showInHomePage': showInDevice},
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
|
final scenesJson = json['data'] as List;
|
||||||
|
|
||||||
List<ScenesModel> scenes = [];
|
List<ScenesModel> scenes = [];
|
||||||
for (var scene in json) {
|
for (var scene in scenesJson) {
|
||||||
scenes.add(ScenesModel.fromJson(scene));
|
scenes.add(ScenesModel.fromJson(scene, isAutomation: false));
|
||||||
}
|
}
|
||||||
return scenes;
|
return scenes;
|
||||||
},
|
},
|
||||||
@ -122,21 +130,21 @@ class SceneApi {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// //automation details
|
//automation details
|
||||||
// static Future<SceneDetailsModel> getAutomationDetails(
|
static Future<RoutineDetailsModel> getAutomationDetails(
|
||||||
// String automationId) async {
|
String automationId) async {
|
||||||
// try {
|
try {
|
||||||
// final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
// path: ApiEndpoints.getAutomationDetails
|
path: ApiEndpoints.getAutomationDetails
|
||||||
// .replaceAll('{automationId}', automationId),
|
.replaceAll('{automationId}', automationId),
|
||||||
// showServerMessage: false,
|
showServerMessage: false,
|
||||||
// expectedResponseModel: (json) => SceneDetailsModel.fromJson(json),
|
expectedResponseModel: (json) => RoutineDetailsModel.fromJson(json),
|
||||||
// );
|
);
|
||||||
// return response;
|
return response;
|
||||||
// } catch (e) {
|
} catch (e) {
|
||||||
// rethrow;
|
rethrow;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
//
|
||||||
// //updateAutomationStatus
|
// //updateAutomationStatus
|
||||||
// static Future<bool> updateAutomationStatus(String automationId,
|
// static Future<bool> updateAutomationStatus(String automationId,
|
||||||
@ -154,20 +162,19 @@ class SceneApi {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// //getScene
|
//getScene
|
||||||
//
|
static Future<RoutineDetailsModel> getSceneDetails(String sceneId) async {
|
||||||
// static Future<SceneDetailsModel> getSceneDetails(String sceneId) async {
|
try {
|
||||||
// try {
|
final response = await _httpService.get(
|
||||||
// final response = await _httpService.get(
|
path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId),
|
||||||
// path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId),
|
showServerMessage: false,
|
||||||
// showServerMessage: false,
|
expectedResponseModel: (json) => RoutineDetailsModel.fromJson(json),
|
||||||
// expectedResponseModel: (json) => SceneDetailsModel.fromJson(json),
|
);
|
||||||
// );
|
return response;
|
||||||
// return response;
|
} catch (e) {
|
||||||
// } catch (e) {
|
rethrow;
|
||||||
// rethrow;
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
//
|
//
|
||||||
// //update Scene
|
// //update Scene
|
||||||
// static updateScene(CreateSceneModel createSceneModel, String sceneId) async {
|
// static updateScene(CreateSceneModel createSceneModel, String sceneId) async {
|
||||||
@ -205,38 +212,39 @@ class SceneApi {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// //delete Scene
|
|
||||||
//
|
|
||||||
// static Future<bool> deleteScene(
|
//delete Scene
|
||||||
// {required String unitUuid, required String sceneId}) async {
|
static Future<bool> deleteScene(
|
||||||
// try {
|
{required String unitUuid, required String sceneId}) async {
|
||||||
// final response = await _httpService.delete(
|
try {
|
||||||
// path: ApiEndpoints.deleteScene
|
final response = await _httpService.delete(
|
||||||
// .replaceAll('{sceneId}', sceneId)
|
path: ApiEndpoints.deleteScene
|
||||||
// .replaceAll('{unitUuid}', unitUuid),
|
.replaceAll('{sceneId}', sceneId)
|
||||||
// showServerMessage: false,
|
.replaceAll('{unitUuid}', unitUuid),
|
||||||
// expectedResponseModel: (json) => json['statusCode'] == 200,
|
showServerMessage: false,
|
||||||
// );
|
expectedResponseModel: (json) => json['statusCode'] == 200,
|
||||||
// return response;
|
);
|
||||||
// } catch (e) {
|
return response;
|
||||||
// rethrow;
|
} catch (e) {
|
||||||
// }
|
rethrow;
|
||||||
// }
|
}
|
||||||
//
|
}
|
||||||
// // delete automation
|
|
||||||
// static Future<bool> deleteAutomation(
|
// delete automation
|
||||||
// {required String unitUuid, required String automationId}) async {
|
static Future<bool> deleteAutomation(
|
||||||
// try {
|
{required String unitUuid, required String automationId}) async {
|
||||||
// final response = await _httpService.delete(
|
try {
|
||||||
// path: ApiEndpoints.deleteAutomation
|
final response = await _httpService.delete(
|
||||||
// .replaceAll('{automationId}', automationId)
|
path: ApiEndpoints.deleteAutomation
|
||||||
// .replaceAll('{unitUuid}', unitUuid),
|
.replaceAll('{automationId}', automationId)
|
||||||
// showServerMessage: false,
|
.replaceAll('{unitUuid}', unitUuid),
|
||||||
// expectedResponseModel: (json) => json['statusCode'] == 200,
|
showServerMessage: false,
|
||||||
// );
|
expectedResponseModel: (json) => json['statusCode'] == 200,
|
||||||
// return response;
|
);
|
||||||
// } catch (e) {
|
return response;
|
||||||
// rethrow;
|
} catch (e) {
|
||||||
// }
|
rethrow;
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,6 @@ abstract class ApiEndpoints {
|
|||||||
'/schedule/{deviceUuid}/{scheduleUuid}';
|
'/schedule/{deviceUuid}/{scheduleUuid}';
|
||||||
static const String updateScheduleByDeviceId =
|
static const String updateScheduleByDeviceId =
|
||||||
'/schedule/enable/{deviceUuid}';
|
'/schedule/enable/{deviceUuid}';
|
||||||
|
|
||||||
static const String factoryReset = '/device/factory/reset/{deviceUuid}';
|
static const String factoryReset = '/device/factory/reset/{deviceUuid}';
|
||||||
static const String powerClamp =
|
static const String powerClamp =
|
||||||
'/device/{powerClampUuid}/power-clamp/status';
|
'/device/{powerClampUuid}/power-clamp/status';
|
||||||
@ -55,4 +54,12 @@ abstract class ApiEndpoints {
|
|||||||
static const String getIconScene = '/scene/icon';
|
static const String getIconScene = '/scene/icon';
|
||||||
static const String createScene = '/scene/tap-to-run';
|
static const String createScene = '/scene/tap-to-run';
|
||||||
static const String createAutomation = '/automation';
|
static const String createAutomation = '/automation';
|
||||||
|
static const String getUnitScenes =
|
||||||
|
'/communities/{communityUuid}/spaces/{spaceUuid}/scenes';
|
||||||
|
static const String getAutomationDetails =
|
||||||
|
'/automation/details/{automationId}';
|
||||||
|
static const String getScene = '/scene/tap-to-run/{sceneId}';
|
||||||
|
static const String deleteScene = '/scene/tap-to-run/{sceneId}';
|
||||||
|
|
||||||
|
static const String deleteAutomation = '/automation/{automationId}';
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user