mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
push changes
This commit is contained in:
@ -3,12 +3,17 @@ import 'dart:async';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_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/delay/delay_fucntions.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/services/devices_mang_api.dart';
|
||||
import 'package:syncrow_web/services/routines_api.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
part 'routine_event.dart';
|
||||
part 'routine_state.dart';
|
||||
@ -34,11 +39,11 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
on<ResetRoutineState>(_onResetRoutineState);
|
||||
on<GetSceneDetails>(_onGetSceneDetails);
|
||||
on<GetAutomationDetails>(_onGetAutomationDetails);
|
||||
// on<InitializeRoutineState>(_onInitializeRoutineState);
|
||||
on<DeleteScene>(_deleteScene);
|
||||
on<DeleteAutomation>(_deleteAutomation);
|
||||
// on<RemoveFunction>(_onRemoveFunction);
|
||||
// on<ClearFunctions>(_onClearFunctions);
|
||||
on<FetchDevicesInRoutine>(_fetchDevices);
|
||||
on<UpdateScene>(_onUpdateScene);
|
||||
on<UpdateAutomation>(_onUpdateAutomation);
|
||||
}
|
||||
|
||||
void _onAddToIfContainer(AddToIfContainer event, Emitter<RoutineState> emit) {
|
||||
@ -419,6 +424,127 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
emit(state.copyWith(routineName: event.name));
|
||||
}
|
||||
|
||||
(
|
||||
List<Map<String, dynamic>>,
|
||||
List<Map<String, dynamic>>,
|
||||
Map<String, List<DeviceFunctionData>>
|
||||
) _createCardData(
|
||||
List<RoutineAction> actions,
|
||||
List<RoutineCondition>? conditions,
|
||||
Map<String, List<DeviceFunctionData>> currentFunctions,
|
||||
bool isTabToRun,
|
||||
) {
|
||||
final ifItems = isTabToRun
|
||||
? [
|
||||
{
|
||||
'entityId': 'tab_to_run',
|
||||
'uniqueCustomId': const Uuid().v4(),
|
||||
'deviceId': 'tab_to_run',
|
||||
'title': 'Tab to run',
|
||||
'productType': 'tab_to_run',
|
||||
'imagePath': Assets.tabToRun,
|
||||
}
|
||||
]
|
||||
: conditions?.map((condition) {
|
||||
final matchingDevice = state.devices.firstWhere(
|
||||
(device) => device.uuid == condition.entityId,
|
||||
orElse: () => AllDevicesModel(
|
||||
uuid: condition.entityId,
|
||||
name: condition.entityId,
|
||||
productType: condition.entityType,
|
||||
),
|
||||
);
|
||||
|
||||
final cardData = {
|
||||
'entityId': condition.entityId,
|
||||
'uniqueCustomId': const Uuid().v4(),
|
||||
'deviceId': condition.entityId,
|
||||
'title': matchingDevice.name ?? condition.entityId,
|
||||
'productType': condition.entityType,
|
||||
'imagePath':
|
||||
matchingDevice.getDefaultIcon(condition.entityType),
|
||||
};
|
||||
|
||||
final functions = matchingDevice.functions;
|
||||
|
||||
for (var function in functions) {
|
||||
if (function.code == condition.expr.statusCode) {
|
||||
currentFunctions[cardData['uniqueCustomId'] ?? ''] = [
|
||||
DeviceFunctionData(
|
||||
entityId: condition.entityId,
|
||||
functionCode: condition.expr.statusCode,
|
||||
value: condition.expr.statusValue,
|
||||
operationName: function.operationName,
|
||||
),
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cardData;
|
||||
}).toList() ??
|
||||
[];
|
||||
|
||||
final thenItems = actions.map((action) {
|
||||
final matchingDevice = state.devices.firstWhere(
|
||||
(device) => device.uuid == action.entityId,
|
||||
orElse: () => AllDevicesModel(
|
||||
uuid: action.entityId,
|
||||
name: action.entityId,
|
||||
productType: action.productType,
|
||||
),
|
||||
);
|
||||
|
||||
final cardData = {
|
||||
'entityId': action.entityId,
|
||||
'uniqueCustomId': const Uuid().v4(),
|
||||
'deviceId':
|
||||
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
||||
'title': action.actionExecutor == 'delay'
|
||||
? 'Delay'
|
||||
: (matchingDevice.name ?? 'Device'),
|
||||
'productType': action.productType,
|
||||
'imagePath': matchingDevice.getDefaultIcon(action.productType),
|
||||
};
|
||||
|
||||
final functions = matchingDevice.functions;
|
||||
|
||||
if (action.executorProperty != null && action.actionExecutor != 'delay') {
|
||||
final functionCode = action.executorProperty!.functionCode;
|
||||
for (var function in functions) {
|
||||
if (function.code == functionCode) {
|
||||
currentFunctions[cardData['uniqueCustomId'] ?? ''] = [
|
||||
DeviceFunctionData(
|
||||
entityId: action.entityId,
|
||||
functionCode: functionCode ?? '',
|
||||
value: action.executorProperty!.functionValue,
|
||||
operationName: function.operationName,
|
||||
),
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (action.actionExecutor == 'delay') {
|
||||
final delayFunction = DelayFunction(
|
||||
deviceId: action.entityId,
|
||||
deviceName: 'Delay',
|
||||
);
|
||||
currentFunctions[cardData['uniqueCustomId'] ?? ''] = [
|
||||
DeviceFunctionData(
|
||||
entityId: action.entityId,
|
||||
functionCode: 'delay',
|
||||
value: action.executorProperty?.delaySeconds ?? 0,
|
||||
operationName: delayFunction.operationName,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
return cardData;
|
||||
}).toList();
|
||||
|
||||
return (thenItems, ifItems, currentFunctions);
|
||||
}
|
||||
|
||||
Future<void> _onGetSceneDetails(
|
||||
GetSceneDetails event, Emitter<RoutineState> emit) async {
|
||||
try {
|
||||
@ -427,13 +553,125 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
isTabToRun: event.isTabToRun,
|
||||
isUpdate: true,
|
||||
sceneId: event.sceneId,
|
||||
isAutomation: false));
|
||||
isAutomation: false,
|
||||
ifItems: [],
|
||||
thenItems: [],
|
||||
));
|
||||
|
||||
final sceneDetails = await SceneApi.getSceneDetails(event.sceneId);
|
||||
add(InitializeRoutineState(sceneDetails));
|
||||
|
||||
final List<Map<String, dynamic>> thenItems;
|
||||
final List<Map<String, dynamic>> ifItems;
|
||||
final Map<String, List<DeviceFunctionData>> updatedFunctions =
|
||||
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||
|
||||
if (event.isTabToRun) {
|
||||
thenItems = sceneDetails.actions.map((action) {
|
||||
late AllDevicesModel? matchingDevice;
|
||||
for (var device in state.devices) {
|
||||
if (device.uuid == action.entityId) {
|
||||
matchingDevice = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final cardData = {
|
||||
'entityId': action.entityId,
|
||||
'uniqueCustomId': const Uuid().v4(),
|
||||
'deviceId':
|
||||
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
||||
'title': action.actionExecutor == 'delay'
|
||||
? 'Delay'
|
||||
: action.type == 'automation'
|
||||
? action.name ?? 'Automation'
|
||||
: (matchingDevice?.name ?? 'Device'),
|
||||
'productType': action.productType,
|
||||
'functions': matchingDevice?.functions,
|
||||
'imagePath': matchingDevice?.getDefaultIcon(action.productType),
|
||||
'device': matchingDevice,
|
||||
};
|
||||
if (action.type == 'automation') {
|
||||
updatedFunctions[cardData['uniqueCustomId'].toString()] = [
|
||||
DeviceFunctionData(
|
||||
entityId: action.entityId,
|
||||
functionCode: 'rule',
|
||||
value: action.actionExecutor,
|
||||
operationName: action.name ?? 'Automation',
|
||||
),
|
||||
];
|
||||
} else if (action.executorProperty != null &&
|
||||
action.actionExecutor != 'delay') {
|
||||
final functions = matchingDevice?.functions;
|
||||
final functionCode = action.executorProperty!.functionCode;
|
||||
for (var function in functions ?? []) {
|
||||
if (function.code == functionCode) {
|
||||
updatedFunctions[cardData['uniqueCustomId'].toString()] = [
|
||||
DeviceFunctionData(
|
||||
entityId: action.entityId,
|
||||
functionCode: functionCode ?? '',
|
||||
value: action.executorProperty!.functionValue,
|
||||
operationName: function.operationName,
|
||||
),
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (action.actionExecutor == 'delay') {
|
||||
final delayFunction = DelayFunction(
|
||||
deviceId: action.entityId,
|
||||
deviceName: 'Delay',
|
||||
);
|
||||
updatedFunctions[cardData['uniqueCustomId'].toString()] = [
|
||||
DeviceFunctionData(
|
||||
entityId: action.entityId,
|
||||
functionCode: 'delay',
|
||||
value: action.executorProperty?.delaySeconds ?? 0,
|
||||
operationName: delayFunction.operationName,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
return cardData;
|
||||
}).toList();
|
||||
|
||||
ifItems = [
|
||||
{
|
||||
'entityId': 'tab_to_run',
|
||||
'uniqueCustomId': const Uuid().v4(),
|
||||
'deviceId': 'tab_to_run',
|
||||
'title': 'Tab to run',
|
||||
'productType': 'tab_to_run',
|
||||
'imagePath': Assets.tabToRun,
|
||||
}
|
||||
];
|
||||
} else {
|
||||
final result = _createCardData(
|
||||
sceneDetails.actions,
|
||||
sceneDetails.conditions,
|
||||
updatedFunctions,
|
||||
false,
|
||||
);
|
||||
thenItems = result.$1;
|
||||
ifItems = result.$2;
|
||||
}
|
||||
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
routineName: sceneDetails.name,
|
||||
selectedIcon: sceneDetails.iconId,
|
||||
selectedAutomationOperator: sceneDetails.decisionExpr,
|
||||
effectiveTime: sceneDetails.effectiveTime,
|
||||
isAutomation: false,
|
||||
isTabToRun: event.isTabToRun,
|
||||
thenItems: thenItems,
|
||||
ifItems: ifItems,
|
||||
selectedFunctions: updatedFunctions,
|
||||
sceneId: sceneDetails.sceneId,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: 'Failed to load scene details',
|
||||
errorMessage: 'Failed to load scene details: $e',
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -443,100 +681,155 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
try {
|
||||
emit(state.copyWith(
|
||||
isLoading: true,
|
||||
isAutomation: event.isAutomation,
|
||||
automationId: event.automationId,
|
||||
isTabToRun: false,
|
||||
isUpdate: true,
|
||||
isTabToRun: false,
|
||||
automationId: event.automationId,
|
||||
isAutomation: true,
|
||||
ifItems: [],
|
||||
thenItems: [],
|
||||
));
|
||||
|
||||
final automationDetails =
|
||||
await SceneApi.getAutomationDetails(event.automationId);
|
||||
add(InitializeRoutineState(automationDetails));
|
||||
|
||||
final List<Map<String, dynamic>> thenItems;
|
||||
final List<Map<String, dynamic>> ifItems;
|
||||
final Map<String, List<DeviceFunctionData>> updatedFunctions =
|
||||
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||
|
||||
ifItems = automationDetails.conditions?.map((condition) {
|
||||
late AllDevicesModel? matchingDevice;
|
||||
for (var device in state.devices) {
|
||||
if (device.uuid == condition.entityId) {
|
||||
matchingDevice = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final cardData = {
|
||||
'entityId': condition.entityId,
|
||||
'uniqueCustomId': const Uuid().v4(),
|
||||
'deviceId': condition.expr.statusCode == 'delay'
|
||||
? 'delay'
|
||||
: condition.entityId,
|
||||
'title': condition.expr.statusCode == 'delay'
|
||||
? 'Delay'
|
||||
: (matchingDevice?.name ?? 'Device'),
|
||||
'productType': condition.productType,
|
||||
'functions': matchingDevice?.functions,
|
||||
'imagePath':
|
||||
matchingDevice?.getDefaultIcon(condition.productType),
|
||||
'device': matchingDevice,
|
||||
};
|
||||
|
||||
final functions = matchingDevice?.functions;
|
||||
for (var function in functions ?? []) {
|
||||
if (function.code == condition.expr.statusCode) {
|
||||
updatedFunctions[cardData['uniqueCustomId'].toString()] = [
|
||||
DeviceFunctionData(
|
||||
entityId: condition.entityId,
|
||||
functionCode: condition.expr.statusCode,
|
||||
value: condition.expr.statusValue,
|
||||
operationName: function.operationName,
|
||||
),
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cardData;
|
||||
}).toList() ??
|
||||
[];
|
||||
|
||||
// Create then items from actions
|
||||
thenItems = automationDetails.actions.map((action) {
|
||||
final matchingDevice = state.devices.firstWhere(
|
||||
(device) => device.uuid == action.entityId,
|
||||
orElse: () => AllDevicesModel(
|
||||
uuid: action.entityId,
|
||||
name: action.entityId,
|
||||
productType: action.productType,
|
||||
),
|
||||
);
|
||||
|
||||
final cardData = {
|
||||
'entityId': action.entityId,
|
||||
'uniqueCustomId': const Uuid().v4(),
|
||||
'deviceId':
|
||||
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
||||
'title': action.actionExecutor == 'delay'
|
||||
? 'Delay'
|
||||
: (matchingDevice.name ?? 'Device'),
|
||||
'productType': action.productType,
|
||||
'functions': matchingDevice.functions,
|
||||
'imagePath': matchingDevice.getDefaultIcon(action.productType),
|
||||
'device': matchingDevice,
|
||||
};
|
||||
|
||||
if (action.executorProperty != null &&
|
||||
action.actionExecutor != 'delay') {
|
||||
final functions = matchingDevice.functions;
|
||||
final functionCode = action.executorProperty!.functionCode;
|
||||
for (var function in functions) {
|
||||
if (function.code == functionCode) {
|
||||
updatedFunctions[cardData['uniqueCustomId'].toString()] = [
|
||||
DeviceFunctionData(
|
||||
entityId: action.entityId,
|
||||
functionCode: functionCode ?? '',
|
||||
value: action.executorProperty!.functionValue,
|
||||
operationName: function.operationName,
|
||||
),
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (action.actionExecutor == 'delay') {
|
||||
final delayFunction = DelayFunction(
|
||||
deviceId: action.entityId,
|
||||
deviceName: 'Delay',
|
||||
);
|
||||
updatedFunctions[cardData['uniqueCustomId'].toString()] = [
|
||||
DeviceFunctionData(
|
||||
entityId: action.entityId,
|
||||
functionCode: 'delay',
|
||||
value: action.executorProperty?.delaySeconds ?? 0,
|
||||
operationName: delayFunction.operationName,
|
||||
),
|
||||
];
|
||||
} else if (action.actionExecutor == 'rule_disable' ||
|
||||
action.actionExecutor == 'rule_enable') {
|
||||
updatedFunctions[cardData['uniqueCustomId'].toString()] = [
|
||||
DeviceFunctionData(
|
||||
entityId: action.entityId,
|
||||
functionCode: 'automation',
|
||||
value: action.actionExecutor,
|
||||
operationName: action.name ?? 'Automation',
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
return cardData;
|
||||
}).toList();
|
||||
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
routineName: automationDetails.name,
|
||||
selectedAutomationOperator: automationDetails.decisionExpr,
|
||||
effectiveTime: automationDetails.effectiveTime,
|
||||
isAutomation: true,
|
||||
thenItems: thenItems,
|
||||
ifItems: ifItems,
|
||||
selectedFunctions: updatedFunctions,
|
||||
automationId: automationDetails.automationId,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: 'Failed to load automation details',
|
||||
errorMessage: 'Failed to load automation details: $e',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// 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() {
|
||||
return const RoutineState(
|
||||
ifItems: [],
|
||||
@ -565,10 +858,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
|
||||
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,
|
||||
@ -580,11 +871,9 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
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,
|
||||
@ -592,4 +881,170 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _fetchDevices(
|
||||
FetchDevicesInRoutine event, Emitter<RoutineState> emit) async {
|
||||
emit(state.copyWith(isLoading: true));
|
||||
try {
|
||||
final devices = await DevicesManagementApi().fetchDevices();
|
||||
|
||||
emit(state.copyWith(isLoading: false, devices: devices));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(isLoading: false));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _onUpdateScene(
|
||||
UpdateScene event, Emitter<RoutineState> emit) async {
|
||||
try {
|
||||
// Check if first action is delay
|
||||
if (_isFirstActionDelay(state.thenItems)) {
|
||||
emit(state.copyWith(
|
||||
errorMessage: 'Cannot have delay as the first action',
|
||||
isLoading: false,
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
emit(state.copyWith(isLoading: true));
|
||||
|
||||
final actions = state.thenItems.expand((item) {
|
||||
final functions = state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||
return functions.map((function) {
|
||||
if (function.functionCode == 'automation') {
|
||||
return CreateSceneAction(
|
||||
entityId: function.entityId,
|
||||
actionExecutor: function.value,
|
||||
executorProperty: null,
|
||||
);
|
||||
}
|
||||
|
||||
if (item['deviceId'] == 'delay') {
|
||||
return CreateSceneAction(
|
||||
entityId: function.entityId,
|
||||
actionExecutor: 'delay',
|
||||
executorProperty: CreateSceneExecutorProperty(
|
||||
functionCode: '',
|
||||
functionValue: '',
|
||||
delaySeconds: int.tryParse(function.value.toString()) ?? 0,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return CreateSceneAction(
|
||||
entityId: function.entityId,
|
||||
actionExecutor: 'device_issue',
|
||||
executorProperty: CreateSceneExecutorProperty(
|
||||
functionCode: function.functionCode,
|
||||
functionValue: function.value,
|
||||
delaySeconds: 0,
|
||||
),
|
||||
);
|
||||
});
|
||||
}).toList();
|
||||
|
||||
final createSceneModel = CreateSceneModel(
|
||||
spaceUuid: state.sceneId ?? '',
|
||||
iconId: state.selectedIcon ?? '',
|
||||
showInDevice: true,
|
||||
sceneName: state.routineName ?? '',
|
||||
decisionExpr: 'and',
|
||||
actions: actions,
|
||||
);
|
||||
|
||||
final result =
|
||||
await SceneApi.updateScene(createSceneModel, state.sceneId ?? '');
|
||||
if (result['success']) {
|
||||
emit(_resetState());
|
||||
add(const LoadScenes(spaceId, communityId));
|
||||
} else {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: result['message'],
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: 'Something went wrong',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _onUpdateAutomation(
|
||||
UpdateAutomation event, Emitter<RoutineState> emit) async {
|
||||
if (_isFirstActionDelay(state.thenItems)) {
|
||||
emit(state.copyWith(
|
||||
errorMessage: 'Cannot have delay as the first action',
|
||||
isLoading: false,
|
||||
));
|
||||
return;
|
||||
}
|
||||
emit(state.copyWith(isLoading: true));
|
||||
try {
|
||||
final conditions = state.ifItems
|
||||
.map((item) {
|
||||
final functions =
|
||||
state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||
if (functions.isEmpty) return null;
|
||||
|
||||
final function = functions.first;
|
||||
return Condition(
|
||||
code: state.ifItems.indexOf(item) + 1,
|
||||
entityId: function.entityId,
|
||||
entityType: item['productType'],
|
||||
expr: ConditionExpr(
|
||||
statusCode: function.functionCode,
|
||||
statusValue: function.value,
|
||||
comparator: function.condition ?? '==',
|
||||
),
|
||||
);
|
||||
})
|
||||
.whereType<Condition>()
|
||||
.toList();
|
||||
|
||||
final actions = state.thenItems
|
||||
.map((item) {
|
||||
final functions =
|
||||
state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||
if (functions.isEmpty) return null;
|
||||
|
||||
final function = functions.first;
|
||||
return AutomationAction(
|
||||
entityId: function.entityId,
|
||||
actionExecutor: function.actionExecutor,
|
||||
executorProperty: ExecutorProperty(
|
||||
functionCode: function.functionCode,
|
||||
functionValue: function.value,
|
||||
delaySeconds: function.functionCode == 'delay'
|
||||
? (function.value as num).toInt()
|
||||
: null,
|
||||
),
|
||||
);
|
||||
})
|
||||
.whereType<AutomationAction>()
|
||||
.toList();
|
||||
|
||||
final createAutomationModel = CreateAutomationModel(
|
||||
spaceUuid: spaceId,
|
||||
automationName: state.routineName ?? '',
|
||||
decisionExpr: state.selectedAutomationOperator,
|
||||
effectiveTime:
|
||||
state.effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''),
|
||||
conditions: conditions,
|
||||
actions: actions,
|
||||
);
|
||||
|
||||
await SceneApi.updateAutomation(
|
||||
createAutomationModel, state.automationId ?? '');
|
||||
|
||||
add(const LoadAutomation(spaceId));
|
||||
emit(state.copyWith(isLoading: false));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: 'Failed to update automation: $e',
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,12 +105,10 @@ class EffectiveTimePeriodEvent extends RoutineEvent {
|
||||
}
|
||||
|
||||
class CreateAutomationEvent extends RoutineEvent {
|
||||
// final CreateAutomationModel createAutomationModel;
|
||||
final String? automationId;
|
||||
final bool updateAutomation;
|
||||
|
||||
const CreateAutomationEvent({
|
||||
//required this.createAutomationModel,
|
||||
this.automationId,
|
||||
this.updateAutomation = false,
|
||||
});
|
||||
@ -174,6 +172,20 @@ class DeleteAutomation extends RoutineEvent {
|
||||
List<Object> get props => [automationId];
|
||||
}
|
||||
|
||||
class UpdateScene extends RoutineEvent {
|
||||
const UpdateScene();
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class UpdateAutomation extends RoutineEvent {
|
||||
const UpdateAutomation();
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class FetchDevicesInRoutine extends RoutineEvent {}
|
||||
|
||||
class ResetRoutineState extends RoutineEvent {}
|
||||
|
||||
class ClearFunctions extends RoutineEvent {}
|
||||
|
@ -21,6 +21,7 @@ class RoutineState extends Equatable {
|
||||
final String? sceneId;
|
||||
final String? automationId;
|
||||
final bool? isUpdate;
|
||||
final List<AllDevicesModel> devices;
|
||||
|
||||
const RoutineState({
|
||||
this.ifItems = const [],
|
||||
@ -43,6 +44,7 @@ class RoutineState extends Equatable {
|
||||
this.sceneId,
|
||||
this.automationId,
|
||||
this.isUpdate,
|
||||
this.devices = const [],
|
||||
});
|
||||
|
||||
RoutineState copyWith({
|
||||
@ -65,6 +67,7 @@ class RoutineState extends Equatable {
|
||||
String? sceneId,
|
||||
String? automationId,
|
||||
bool? isUpdate,
|
||||
List<AllDevicesModel>? devices,
|
||||
}) {
|
||||
return RoutineState(
|
||||
ifItems: ifItems ?? this.ifItems,
|
||||
@ -89,6 +92,7 @@ class RoutineState extends Equatable {
|
||||
sceneId: sceneId ?? this.sceneId,
|
||||
automationId: automationId ?? this.automationId,
|
||||
isUpdate: isUpdate ?? this.isUpdate,
|
||||
devices: devices ?? this.devices,
|
||||
);
|
||||
}
|
||||
|
||||
@ -112,6 +116,7 @@ class RoutineState extends Equatable {
|
||||
effectiveTime,
|
||||
sceneId,
|
||||
automationId,
|
||||
isUpdate
|
||||
isUpdate,
|
||||
devices,
|
||||
];
|
||||
}
|
||||
|
@ -54,23 +54,27 @@ class SaveRoutineHelper {
|
||||
),
|
||||
if (state.isAutomation)
|
||||
...state.ifItems.map((item) {
|
||||
final functions =
|
||||
state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||
final functions = state.selectedFunctions[
|
||||
item['uniqueCustomId']] ??
|
||||
[];
|
||||
return ListTile(
|
||||
leading: SvgPicture.asset(
|
||||
item['imagePath'],
|
||||
width: 22,
|
||||
height: 22,
|
||||
),
|
||||
title:
|
||||
Text(item['title'], style: const TextStyle(fontSize: 14)),
|
||||
title: Text(item['title'],
|
||||
style: const TextStyle(fontSize: 14)),
|
||||
subtitle: Wrap(
|
||||
children: functions
|
||||
.map((f) => Text(
|
||||
'${f.operationName}: ${f.value}, ',
|
||||
style: const TextStyle(
|
||||
color: ColorsManager.grayColor, fontSize: 8),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
color: ColorsManager
|
||||
.grayColor,
|
||||
fontSize: 8),
|
||||
overflow:
|
||||
TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
))
|
||||
.toList(),
|
||||
@ -95,22 +99,25 @@ class SaveRoutineHelper {
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
...state.thenItems.map((item) {
|
||||
final functions =
|
||||
state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||
final functions = state.selectedFunctions[
|
||||
item['uniqueCustomId']] ??
|
||||
[];
|
||||
return ListTile(
|
||||
leading: SvgPicture.asset(
|
||||
item['imagePath'],
|
||||
width: 22,
|
||||
height: 22,
|
||||
),
|
||||
title:
|
||||
Text(item['title'], style: const TextStyle(fontSize: 14)),
|
||||
title: Text(item['title'],
|
||||
style: const TextStyle(fontSize: 14)),
|
||||
subtitle: Wrap(
|
||||
children: functions
|
||||
.map((f) => Text(
|
||||
'${f.operationName}: ${f.value}, ',
|
||||
style: const TextStyle(
|
||||
color: ColorsManager.grayColor, fontSize: 8),
|
||||
color:
|
||||
ColorsManager.grayColor,
|
||||
fontSize: 8),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
))
|
||||
@ -136,9 +143,25 @@ class SaveRoutineHelper {
|
||||
onCancel: () => Navigator.pop(context, false),
|
||||
onConfirm: () {
|
||||
if (state.isAutomation) {
|
||||
context.read<RoutineBloc>().add(const CreateAutomationEvent());
|
||||
if (state.automationId != null) {
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(const UpdateAutomation());
|
||||
} else {
|
||||
context.read<RoutineBloc>().add(const CreateSceneEvent());
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(const CreateAutomationEvent());
|
||||
}
|
||||
} else {
|
||||
if (state.sceneId != null) {
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(const UpdateScene());
|
||||
} else {
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(const CreateSceneEvent());
|
||||
}
|
||||
}
|
||||
|
||||
Navigator.pop(context, true);
|
||||
|
@ -17,7 +17,7 @@ class CreateAutomationModel {
|
||||
required this.actions,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
Map<String, dynamic> toMap([String? automationId]) {
|
||||
return {
|
||||
'spaceUuid': spaceUuid,
|
||||
'automationName': automationName,
|
||||
@ -41,7 +41,7 @@ class CreateAutomationModel {
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
String toJson(String? automationId) => json.encode(toMap(automationId));
|
||||
|
||||
factory CreateAutomationModel.fromJson(String source) =>
|
||||
CreateAutomationModel.fromMap(json.decode(source));
|
||||
|
@ -13,6 +13,8 @@ class RoutineDetailsModel {
|
||||
final EffectiveTime? effectiveTime;
|
||||
final List<RoutineCondition>? conditions;
|
||||
final String? type;
|
||||
final String? sceneId;
|
||||
final String? automationId;
|
||||
|
||||
RoutineDetailsModel({
|
||||
required this.spaceUuid,
|
||||
@ -24,6 +26,8 @@ class RoutineDetailsModel {
|
||||
this.effectiveTime,
|
||||
this.conditions,
|
||||
this.type,
|
||||
this.sceneId,
|
||||
this.automationId,
|
||||
});
|
||||
|
||||
// Convert to CreateSceneModel
|
||||
@ -57,12 +61,14 @@ class RoutineDetailsModel {
|
||||
'name': name,
|
||||
'decisionExpr': decisionExpr,
|
||||
'actions': actions.map((x) => x.toMap()).toList(),
|
||||
if (iconId != null) 'iconId': iconId,
|
||||
if (iconId != null) 'iconUuid': 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,
|
||||
if (sceneId != null) 'sceneId': sceneId,
|
||||
if (automationId != null) 'automationId': automationId,
|
||||
};
|
||||
}
|
||||
|
||||
@ -74,7 +80,7 @@ class RoutineDetailsModel {
|
||||
actions: List<RoutineAction>.from(
|
||||
map['actions']?.map((x) => RoutineAction.fromMap(x)) ?? [],
|
||||
),
|
||||
iconId: map['iconId'],
|
||||
iconId: map['iconUuid'],
|
||||
showInDevice: map['showInDevice'],
|
||||
effectiveTime: map['effectiveTime'] != null
|
||||
? EffectiveTime.fromMap(map['effectiveTime'])
|
||||
@ -84,6 +90,8 @@ class RoutineDetailsModel {
|
||||
map['conditions'].map((x) => RoutineCondition.fromMap(x)))
|
||||
: null,
|
||||
type: map['type'],
|
||||
sceneId: map['sceneId'],
|
||||
automationId: map['automationId'],
|
||||
);
|
||||
}
|
||||
|
||||
@ -96,12 +104,18 @@ class RoutineDetailsModel {
|
||||
class RoutineAction {
|
||||
final String entityId;
|
||||
final String actionExecutor;
|
||||
final String? name;
|
||||
final RoutineExecutorProperty? executorProperty;
|
||||
final String productType;
|
||||
final String? type;
|
||||
|
||||
RoutineAction({
|
||||
required this.entityId,
|
||||
required this.actionExecutor,
|
||||
required this.productType,
|
||||
this.executorProperty,
|
||||
this.name,
|
||||
this.type,
|
||||
});
|
||||
|
||||
CreateSceneAction toCreateSceneAction() {
|
||||
@ -124,6 +138,8 @@ class RoutineAction {
|
||||
return {
|
||||
'entityId': entityId,
|
||||
'actionExecutor': actionExecutor,
|
||||
if (type != null) 'type': type,
|
||||
if (name != null) 'name': name,
|
||||
if (executorProperty != null)
|
||||
'executorProperty': executorProperty!.toMap(),
|
||||
};
|
||||
@ -133,6 +149,9 @@ class RoutineAction {
|
||||
return RoutineAction(
|
||||
entityId: map['entityId'] ?? '',
|
||||
actionExecutor: map['actionExecutor'] ?? '',
|
||||
productType: map['productType'] ?? '',
|
||||
name: map['name'] ?? '',
|
||||
type: map['type'] ?? '',
|
||||
executorProperty: map['executorProperty'] != null
|
||||
? RoutineExecutorProperty.fromMap(map['executorProperty'])
|
||||
: null,
|
||||
@ -189,12 +208,14 @@ class RoutineCondition {
|
||||
final String entityId;
|
||||
final String entityType;
|
||||
final RoutineConditionExpr expr;
|
||||
final String productType;
|
||||
|
||||
RoutineCondition({
|
||||
required this.code,
|
||||
required this.entityId,
|
||||
required this.entityType,
|
||||
required this.expr,
|
||||
required this.productType,
|
||||
});
|
||||
|
||||
Condition toCondition() {
|
||||
@ -221,6 +242,7 @@ class RoutineCondition {
|
||||
entityId: map['entityId'] ?? '',
|
||||
entityType: map['entityType'] ?? '',
|
||||
expr: RoutineConditionExpr.fromMap(map['expr']),
|
||||
productType: map['productType'] ?? '',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ class CreateNewRoutineView extends StatelessWidget {
|
||||
this.routineId,
|
||||
this.isScene = true,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
|
@ -7,9 +7,20 @@ import 'package:syncrow_web/pages/routiens/widgets/main_routine_view/fetch_routi
|
||||
import 'package:syncrow_web/pages/routiens/widgets/main_routine_view/routine_view_card.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class RoutinesView extends StatelessWidget {
|
||||
class RoutinesView extends StatefulWidget {
|
||||
const RoutinesView({super.key});
|
||||
|
||||
@override
|
||||
State<RoutinesView> createState() => _RoutinesViewState();
|
||||
}
|
||||
|
||||
class _RoutinesViewState extends State<RoutinesView> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
context.read<RoutineBloc>().add(FetchDevicesInRoutine());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SwitchTabsBloc, SwitchTabsState>(
|
||||
|
@ -83,6 +83,10 @@ class DraggableCard extends StatelessWidget {
|
||||
? SvgPicture.asset(
|
||||
imagePath,
|
||||
)
|
||||
: imagePath.contains('.png')
|
||||
? Image.asset(
|
||||
imagePath,
|
||||
)
|
||||
: Image.memory(
|
||||
base64Decode(imagePath),
|
||||
),
|
||||
@ -91,7 +95,7 @@ class DraggableCard extends StatelessWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 3),
|
||||
child: Text(
|
||||
title,
|
||||
deviceData['title'] ?? deviceData['name'] ?? title,
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
@ -104,7 +108,6 @@ class DraggableCard extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
if (deviceFunctions.isNotEmpty)
|
||||
// const Divider(height: 1),
|
||||
...deviceFunctions.map((function) => Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.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/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';
|
||||
@ -70,7 +71,19 @@ class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
|
||||
child: Stack(
|
||||
children: [
|
||||
RoutineViewCard(
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
BlocProvider.of<SwitchTabsBloc>(context)
|
||||
.add(
|
||||
const CreateNewRoutineViewEvent(true),
|
||||
);
|
||||
context.read<RoutineBloc>().add(
|
||||
GetSceneDetails(
|
||||
sceneId: state.scenes[index].id,
|
||||
isTabToRun: true,
|
||||
isUpdate: true,
|
||||
),
|
||||
);
|
||||
},
|
||||
textString: state.scenes[index].name,
|
||||
icon: state.scenes[index].icon ??
|
||||
Assets.logoHorizontal,
|
||||
@ -145,7 +158,19 @@ class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
|
||||
child: Stack(
|
||||
children: [
|
||||
RoutineViewCard(
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
BlocProvider.of<SwitchTabsBloc>(context)
|
||||
.add(
|
||||
const CreateNewRoutineViewEvent(true),
|
||||
);
|
||||
context.read<RoutineBloc>().add(
|
||||
GetAutomationDetails(
|
||||
automationId:
|
||||
state.automations[index].id,
|
||||
isAutomation: true,
|
||||
isUpdate: true),
|
||||
);
|
||||
},
|
||||
textString: state.automations[index].name,
|
||||
icon: state.automations[index].icon ??
|
||||
Assets.automation,
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||
@ -10,11 +9,18 @@ class RoutineDevices extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => DeviceManagementBloc()..add(FetchDevices()),
|
||||
child: BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
|
||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||
builder: (context, state) {
|
||||
if (state is DeviceManagementLoaded) {
|
||||
if (state.isLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
if (state.devices.isEmpty) {
|
||||
return const Center(child: Text('No devices found'));
|
||||
}
|
||||
});
|
||||
|
||||
List<AllDevicesModel> deviceList = state.devices
|
||||
.where((device) =>
|
||||
device.productType == 'AC' ||
|
||||
@ -23,18 +29,15 @@ class RoutineDevices extends StatelessWidget {
|
||||
device.productType == '3G')
|
||||
.toList();
|
||||
|
||||
// Provide the RoutineBloc to the child widgets
|
||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||
builder: (context, routineState) {
|
||||
return Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: deviceList.asMap().entries.map((entry) {
|
||||
final device = entry.value;
|
||||
if (routineState.searchText != null && routineState.searchText!.isNotEmpty) {
|
||||
if (state.searchText != null && state.searchText!.isNotEmpty) {
|
||||
return device.name!
|
||||
.toLowerCase()
|
||||
.contains(routineState.searchText!.toLowerCase())
|
||||
.contains(state.searchText!.toLowerCase())
|
||||
? DraggableCard(
|
||||
imagePath: device.getDefaultIcon(device.productType),
|
||||
title: device.name ?? '',
|
||||
@ -69,9 +72,4 @@ class RoutineDevices extends StatelessWidget {
|
||||
},
|
||||
);
|
||||
}
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -30,18 +30,23 @@ class ThenContainer extends StatelessWidget {
|
||||
style: TextStyle(
|
||||
fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 16),
|
||||
Wrap(
|
||||
state.isLoading && state.isUpdate == true
|
||||
? const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
)
|
||||
: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: List.generate(
|
||||
state.thenItems.length,
|
||||
(index) => GestureDetector(
|
||||
onTap: () async {
|
||||
if (state.thenItems[index]['deviceId'] ==
|
||||
if (state.thenItems[index]
|
||||
['deviceId'] ==
|
||||
'delay') {
|
||||
final result = await DelayHelper
|
||||
.showDelayPickerDialog(
|
||||
context, state.thenItems[index]);
|
||||
.showDelayPickerDialog(context,
|
||||
state.thenItems[index]);
|
||||
|
||||
if (result != null) {
|
||||
context
|
||||
@ -76,8 +81,9 @@ class ThenContainer extends StatelessWidget {
|
||||
imagePath: state.thenItems[index]
|
||||
['imagePath'] ??
|
||||
'',
|
||||
title:
|
||||
state.thenItems[index]['title'] ?? '',
|
||||
title: state.thenItems[index]
|
||||
['title'] ??
|
||||
'',
|
||||
deviceData: state.thenItems[index],
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4, vertical: 8),
|
||||
|
@ -138,29 +138,49 @@ class SceneApi {
|
||||
path: ApiEndpoints.getAutomationDetails
|
||||
.replaceAll('{automationId}', automationId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => RoutineDetailsModel.fromJson(json),
|
||||
expectedResponseModel: (json) => RoutineDetailsModel.fromMap(json),
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
//update Scene
|
||||
static updateScene(CreateSceneModel createSceneModel, String sceneId) async {
|
||||
try {
|
||||
final response = await _httpService.put(
|
||||
path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId),
|
||||
body: createSceneModel
|
||||
.toJson(sceneId.isNotEmpty == true ? sceneId : null),
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
//update automation
|
||||
static updateAutomation(
|
||||
CreateAutomationModel createAutomationModel, String automationId) async {
|
||||
try {
|
||||
final response = await _httpService.put(
|
||||
path: ApiEndpoints.updateAutomation
|
||||
.replaceAll('{automationId}', automationId),
|
||||
body: createAutomationModel
|
||||
.toJson(automationId.isNotEmpty == true ? automationId : null),
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
//
|
||||
// //updateAutomationStatus
|
||||
// static Future<bool> updateAutomationStatus(String automationId,
|
||||
// AutomationStatusUpdate createAutomationEnable) async {
|
||||
// try {
|
||||
// final response = await _httpService.put(
|
||||
// path: ApiEndpoints.updateAutomationStatus
|
||||
// .replaceAll('{automationId}', automationId),
|
||||
// body: createAutomationEnable.toMap(),
|
||||
// expectedResponseModel: (json) => json['success'],
|
||||
// );
|
||||
// return response;
|
||||
// } catch (e) {
|
||||
// rethrow;
|
||||
// }
|
||||
// }
|
||||
|
||||
//getScene
|
||||
static Future<RoutineDetailsModel> getSceneDetails(String sceneId) async {
|
||||
@ -168,51 +188,14 @@ class SceneApi {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => RoutineDetailsModel.fromJson(json),
|
||||
expectedResponseModel: (json) =>
|
||||
RoutineDetailsModel.fromMap(json['data']),
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
//
|
||||
// //update Scene
|
||||
// static updateScene(CreateSceneModel createSceneModel, String sceneId) async {
|
||||
// try {
|
||||
// final response = await _httpService.put(
|
||||
// path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId),
|
||||
// body: createSceneModel
|
||||
// .toJson(sceneId.isNotEmpty == true ? sceneId : null),
|
||||
// expectedResponseModel: (json) {
|
||||
// return json;
|
||||
// },
|
||||
// );
|
||||
// return response;
|
||||
// } catch (e) {
|
||||
// rethrow;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //update automation
|
||||
// static updateAutomation(
|
||||
// CreateAutomationModel createAutomationModel, String automationId) async {
|
||||
// try {
|
||||
// final response = await _httpService.put(
|
||||
// path: ApiEndpoints.updateAutomation
|
||||
// .replaceAll('{automationId}', automationId),
|
||||
// body: createAutomationModel
|
||||
// .toJson(automationId.isNotEmpty == true ? automationId : null),
|
||||
// expectedResponseModel: (json) {
|
||||
// return json;
|
||||
// },
|
||||
// );
|
||||
// return response;
|
||||
// } catch (e) {
|
||||
// rethrow;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
//delete Scene
|
||||
static Future<bool> deleteScene(
|
||||
|
@ -74,4 +74,7 @@ abstract class ApiEndpoints {
|
||||
static const String deleteScene = '/scene/tap-to-run/{sceneId}';
|
||||
|
||||
static const String deleteAutomation = '/automation/{automationId}';
|
||||
static const String updateScene = '/scene/tap-to-run/{sceneId}';
|
||||
|
||||
static const String updateAutomation = '/automation/{automationId}';
|
||||
}
|
||||
|
Reference in New Issue
Block a user