Compare commits

..

5 Commits

Author SHA1 Message Date
73d28a1800 Refactor Action class to use type annotations for actionExecutor and entityId 2025-04-17 10:41:01 +03:00
5493ca6fb0 Refactor device filtering logic to improve code readability 2025-04-17 10:38:25 +03:00
7005d8ba83 Refactor device filtering logic and improve code readability
- Extracted the logic for filtering implemented devices into a separate method `_getOnlyImplementedDevices`
- Created a set `allowedDevices` to store the allowed device types
- Updated the filtering logic to use the `allowedDevices` set for checking device types
- Removed unnecessary conditions for filtering devices

Fix nullability issues in `Action` model

- Added null checks for `actionExecutor`, `entityId`, `name`, `type`, and `productType` properties in the `fromJson` method of the `Action` model
- Set default values for `actionExecutor` and `entityId` if they are null
- Updated the type casting for `name`, `type`, and `productType` properties to avoid potential nullability issues
2025-04-17 10:16:10 +03:00
1cff69d496 change icon 2025-04-17 09:39:58 +03:00
60df77efad add OneGang product type to routine 2025-04-17 09:32:20 +03:00
19 changed files with 544 additions and 487 deletions

View File

@ -1,5 +1,3 @@
ENV_NAME=development ENV_NAME=development
BASE_URL=https://syncrow-dev.azurewebsites.net BASE_URL=https://syncrow-dev.azurewebsites.net
PROJECT_ID=0e62577c-06fa-41b9-8a92-99a21fbaf51c PROJECT_ID=0e62577c-06fa-41b9-8a92-99a21fbaf51c
CLIENT_ID=c024573d191a327ce74db7d4502fdc29
CLIENT_SECRET=fec6ccbc33664f94a3b84a45c7cceef3f3ebd1613ef4307db8946ede530cd1ed

View File

@ -1,6 +1,5 @@
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_dotenv/flutter_dotenv.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:syncrow_app/features/auth/model/login_with_email_model.dart'; import 'package:syncrow_app/features/auth/model/login_with_email_model.dart';
import 'package:syncrow_app/features/auth/model/signup_model.dart'; import 'package:syncrow_app/features/auth/model/signup_model.dart';
@ -218,22 +217,9 @@ class AuthCubit extends Cubit<AuthState> {
signUp() async { signUp() async {
emit(AuthLoginLoading()); emit(AuthLoginLoading());
final response; final response;
final clientId = dotenv.env['CLIENT_ID'] ?? '';
final clientSecret = dotenv.env['CLIENT_SECRET'] ?? '';
try { try {
List<String> userFullName = fullName.split(' '); List<String> userFullName = fullName.split(' ');
final clientToken = await AuthenticationAPI.fetchClientToken(
clientId: clientId,
clientSecret: clientSecret,
);
final accessToken = clientToken['accessToken'];
response = await AuthenticationAPI.signUp( response = await AuthenticationAPI.signUp(
accessToken: accessToken,
model: SignUpModel( model: SignUpModel(
hasAcceptedAppAgreement: true, hasAcceptedAppAgreement: true,
email: email.toLowerCase(), email: email.toLowerCase(),

View File

@ -169,18 +169,19 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
} }
} }
_getOnlyImplementedDevices(List<DeviceModel> devices) { List<DeviceModel> _getOnlyImplementedDevices(List<DeviceModel> devices) {
List<DeviceModel> implementedDevices = []; const allowedDeviceTypes = {
for (int i = 0; i < devices.length; i++) { DeviceType.AC,
if (devices[i].productType == DeviceType.AC || DeviceType.DoorLock,
devices[i].productType == DeviceType.DoorLock || DeviceType.Gateway,
devices[i].productType == DeviceType.Gateway || DeviceType.WallSensor,
devices[i].productType == DeviceType.WallSensor || DeviceType.CeilingSensor,
devices[i].productType == DeviceType.CeilingSensor || DeviceType.ThreeGang,
devices[i].productType == DeviceType.ThreeGang) { DeviceType.OneGang,
implementedDevices.add(devices[i]); };
}
} return devices
return implementedDevices; .where((device) => allowedDeviceTypes.contains(device.productType))
.toList();
} }
} }

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_event.dart'; import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_event.dart';
@ -5,31 +7,19 @@ import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_state.dart'; import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_state.dart';
class TabBarBloc extends Bloc<TabBarEvent, TabBarState> { class TabBarBloc extends Bloc<TabBarEvent, TabBarState> {
TabBarBloc(this.deviceManagerBloc) : super(const TabBarInitialState()) {
on<TabBarTabChangedEvent>(_onTabBarTabChangedEvent);
}
final DeviceManagerBloc deviceManagerBloc; final DeviceManagerBloc deviceManagerBloc;
TabBarBloc(this.deviceManagerBloc) : super(const Initial()) {
void _onTabBarTabChangedEvent( on<TabChanged>(_handleTabChanged);
TabBarTabChangedEvent event,
Emitter<TabBarState> emit,
) {
_getDevices(event);
emit(
TabBarTabSelectedState(
roomId: event.roomId,
selectedTabIndex: event.selectedIndex,
),
);
} }
void _getDevices(TabBarTabChangedEvent event) { FutureOr<void> _handleTabChanged(
TabChanged event, Emitter<TabBarState> emit) {
if (event.roomId == "-1") { if (event.roomId == "-1") {
deviceManagerBloc.add(FetchAllDevices()); deviceManagerBloc.add(FetchAllDevices());
} else { } else {
deviceManagerBloc.add(FetchDevicesByRoomId(event.roomId, event.unit)); deviceManagerBloc.add(FetchDevicesByRoomId(event.roomId,event.unit));
} }
emit(TabSelected(
roomId: event.roomId, selectedTabIndex: event.selectedIndex));
} }
} }

View File

@ -4,14 +4,10 @@ abstract class TabBarEvent {
const TabBarEvent(); const TabBarEvent();
} }
class TabBarTabChangedEvent extends TabBarEvent { class TabChanged extends TabBarEvent {
const TabBarTabChangedEvent({
required this.selectedIndex,
required this.roomId,
required this.unit,
});
final int selectedIndex; final int selectedIndex;
final String roomId; final String roomId;
final SpaceModel unit; final SpaceModel unit;
const TabChanged(
{required this.selectedIndex, required this.roomId, required this.unit});
} }

View File

@ -2,16 +2,12 @@ abstract class TabBarState {
const TabBarState(); const TabBarState();
} }
class TabBarInitialState extends TabBarState { class Initial extends TabBarState {
const TabBarInitialState(); const Initial();
} }
class TabBarTabSelectedState extends TabBarState { class TabSelected extends TabBarState {
const TabBarTabSelectedState({
required this.roomId,
required this.selectedTabIndex,
});
final int selectedTabIndex; final int selectedTabIndex;
final String roomId; final String roomId;
const TabSelected({required this.roomId, required this.selectedTabIndex});
} }

View File

@ -0,0 +1,78 @@
import 'package:syncrow_app/features/scene/enum/operation_dialog_type.dart';
import 'package:syncrow_app/features/scene/model/scene_static_function.dart';
import 'package:syncrow_app/generated/assets.dart';
class OneGangHelperFunctions {
static List<SceneStaticFunction> oneGangHelperFunctions(
String deviceId, String deviceName, functionValue) {
return [
SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsAcPower,
operationName: 'Light Switch',
code: 'switch_1',
functionValue: functionValue,
operationDialogType: OperationDialogType.onOff,
operationalValues: [
SceneOperationalValue(
icon: Assets.assetsAcPower, description: "ON", value: true),
SceneOperationalValue(
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
],
),
SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsLightCountdown,
operationName: 'Light CountDown',
code: 'countdown_1',
functionValue: functionValue,
operationDialogType: OperationDialogType.countdown,
operationalValues: [
SceneOperationalValue(icon: '', value: 0),
],
),
];
}
static List<SceneStaticFunction> oneGangAutomationFunctions(
String deviceId, String deviceName, functionValue) {
return [
SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsAcPower,
operationName: 'Light Switch',
code: 'switch_1',
functionValue: functionValue,
operationDialogType: OperationDialogType.onOff,
operationalValues: [
SceneOperationalValue(
icon: Assets.assetsAcPower, description: "ON", value: true),
SceneOperationalValue(
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
],
),
SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsLightCountdown,
operationName: 'Light CountDown',
code: 'countdown_1',
functionValue: functionValue,
operationDialogType: OperationDialogType.integerSteps,
operationalValues: [
SceneOperationalValue(
icon: '',
description: "sec",
value: 0.0,
minValue: 0,
maxValue: 43200,
stepValue: 1,
),
],
),
];
}
}

View File

@ -6,6 +6,7 @@ import 'package:syncrow_app/features/scene/helper/functions_per_device/ac_functi
import 'package:syncrow_app/features/scene/helper/functions_per_device/door_lock_functions.dart'; import 'package:syncrow_app/features/scene/helper/functions_per_device/door_lock_functions.dart';
import 'package:syncrow_app/features/scene/helper/functions_per_device/gateway_functions.dart'; import 'package:syncrow_app/features/scene/helper/functions_per_device/gateway_functions.dart';
import 'package:syncrow_app/features/scene/helper/functions_per_device/human_presence_functions.dart'; import 'package:syncrow_app/features/scene/helper/functions_per_device/human_presence_functions.dart';
import 'package:syncrow_app/features/scene/helper/functions_per_device/one_gang_functions.dart';
import 'package:syncrow_app/features/scene/helper/functions_per_device/presence_sensor.dart'; import 'package:syncrow_app/features/scene/helper/functions_per_device/presence_sensor.dart';
import 'package:syncrow_app/features/scene/helper/functions_per_device/three_gang_functions.dart'; import 'package:syncrow_app/features/scene/helper/functions_per_device/three_gang_functions.dart';
import 'package:syncrow_app/features/scene/model/scene_details_model.dart'; import 'package:syncrow_app/features/scene/model/scene_details_model.dart';
@ -14,8 +15,9 @@ import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart';
mixin SceneOperationsDataHelper { mixin SceneOperationsDataHelper {
final Map<DeviceType, Function(List<FunctionModel>, String, String, dynamic, bool)> _functionMap = final Map<DeviceType,
{ Function(List<FunctionModel>, String, String, dynamic, bool)>
_functionMap = {
DeviceType.LightBulb: lightBulbFunctions, DeviceType.LightBulb: lightBulbFunctions,
DeviceType.CeilingSensor: ceilingSensorFunctions, DeviceType.CeilingSensor: ceilingSensorFunctions,
DeviceType.WallSensor: wallSensorFunctions, DeviceType.WallSensor: wallSensorFunctions,
@ -24,6 +26,7 @@ mixin SceneOperationsDataHelper {
DeviceType.Curtain: curtainFunctions, DeviceType.Curtain: curtainFunctions,
DeviceType.ThreeGang: threeGangFunctions, DeviceType.ThreeGang: threeGangFunctions,
DeviceType.Gateway: gatewayFunctions, DeviceType.Gateway: gatewayFunctions,
DeviceType.OneGang: oneGangFunctions,
}; };
final Map<DeviceType, String> _titleMap = { final Map<DeviceType, String> _titleMap = {
@ -35,7 +38,24 @@ mixin SceneOperationsDataHelper {
DeviceType.Curtain: 'Curtain Functions', DeviceType.Curtain: 'Curtain Functions',
DeviceType.ThreeGang: '3G Light Switch Functions', DeviceType.ThreeGang: '3G Light Switch Functions',
DeviceType.Gateway: 'Gateway Functions', DeviceType.Gateway: 'Gateway Functions',
DeviceType.OneGang: '1G Light Switch Conditions',
}; };
static String _productTypeCache = '';
//one gang functions
static List<SceneStaticFunction> oneGangFunctions(
List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) {
return OneGangHelperFunctions.oneGangAutomationFunctions(
deviceId, deviceName, functionValue);
}
return OneGangHelperFunctions.oneGangHelperFunctions(
deviceId, deviceName, functionValue);
}
List<SceneStaticFunction> getFunctionsWithIcons({ List<SceneStaticFunction> getFunctionsWithIcons({
DeviceType? type, DeviceType? type,
@ -45,16 +65,22 @@ mixin SceneOperationsDataHelper {
required bool isAutomation, required bool isAutomation,
}) { }) {
final functionValue = null; final functionValue = null;
return _functionMap[type]?.call(functions, deviceId, deviceName, functionValue, isAutomation) ?? return _functionMap[type]?.call(
lightBulbFunctions(functions, deviceId, deviceName, functionValue, isAutomation); functions, deviceId, deviceName, functionValue, isAutomation) ??
lightBulbFunctions(
functions, deviceId, deviceName, functionValue, isAutomation);
} }
String getTitle({DeviceType? type}) { String getTitle({DeviceType? type}) {
return _titleMap[type] ?? ''; return _titleMap[type] ?? '';
} }
static List<SceneStaticFunction> ceilingSensorFunctions(List<FunctionModel> functions, static List<SceneStaticFunction> ceilingSensorFunctions(
String deviceId, String deviceName, dynamic functionValue, bool isAutomation) { List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) { if (isAutomation) {
return PresenceSensorHelperFunctions.automationPresenceSensorFunctions( return PresenceSensorHelperFunctions.automationPresenceSensorFunctions(
deviceId, deviceName, functionValue); deviceId, deviceName, functionValue);
@ -63,22 +89,35 @@ mixin SceneOperationsDataHelper {
deviceId, deviceName, functionValue); deviceId, deviceName, functionValue);
} }
static List<SceneStaticFunction> curtainFunctions(List<FunctionModel> functions, String deviceId, static List<SceneStaticFunction> curtainFunctions(
String deviceName, dynamic functionValue, bool isAutomation) { List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
return []; return [];
} }
static List<SceneStaticFunction> doorLockFunctions(List<FunctionModel> functions, String deviceId, static List<SceneStaticFunction> doorLockFunctions(
String deviceName, dynamic functionValue, bool isAutomation) { List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) { if (isAutomation) {
return DoorLockHelperFunctions.doorLockAutomationFunctions( return DoorLockHelperFunctions.doorLockAutomationFunctions(
deviceId, deviceName, functionValue); deviceId, deviceName, functionValue);
} }
return DoorLockHelperFunctions.doorLockTapToRunFunctions(deviceId, deviceName, functionValue); return DoorLockHelperFunctions.doorLockTapToRunFunctions(
deviceId, deviceName, functionValue);
} }
static List<SceneStaticFunction> wallSensorFunctions(List<FunctionModel> functions, static List<SceneStaticFunction> wallSensorFunctions(
String deviceId, String deviceName, dynamic functionValue, bool isAutomation) { List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) { if (isAutomation) {
return HumanPresenceHelperFunctions.automationHumanPresenceFunctions( return HumanPresenceHelperFunctions.automationHumanPresenceFunctions(
deviceId, deviceName, functionValue); deviceId, deviceName, functionValue);
@ -87,31 +126,51 @@ mixin SceneOperationsDataHelper {
deviceId, deviceName, functionValue); deviceId, deviceName, functionValue);
} }
static List<SceneStaticFunction> lightBulbFunctions(List<FunctionModel> functions, static List<SceneStaticFunction> lightBulbFunctions(
String deviceId, String deviceName, dynamic functionValue, bool isAutomation) { List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
return []; return [];
} }
static List<SceneStaticFunction> gatewayFunctions(List<FunctionModel> functions, String deviceId, static List<SceneStaticFunction> gatewayFunctions(
String deviceName, dynamic functionValue, bool isAutomation) { List<FunctionModel> functions,
return GatewayHelperFunctions.tabToRunGatewayFunctions(deviceId, deviceName, functionValue); String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
return GatewayHelperFunctions.tabToRunGatewayFunctions(
deviceId, deviceName, functionValue);
} }
static List<SceneStaticFunction> threeGangFunctions(List<FunctionModel> functions, static List<SceneStaticFunction> threeGangFunctions(
String deviceId, String deviceName, dynamic functionValue, bool isAutomation) { List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) { if (isAutomation) {
return ThreeGangHelperFunctions.threeGangAutomationFunctions( return ThreeGangHelperFunctions.threeGangAutomationFunctions(
deviceId, deviceName, functionValue); deviceId, deviceName, functionValue);
} }
return ThreeGangHelperFunctions.threeGangHelperFunctions(deviceId, deviceName, functionValue); return ThreeGangHelperFunctions.threeGangHelperFunctions(
deviceId, deviceName, functionValue);
} }
static List<SceneStaticFunction> acFunctions(List<FunctionModel> functions, String deviceId, static List<SceneStaticFunction> acFunctions(
String deviceName, dynamic functionValue, bool isAutomation) { List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) { if (isAutomation) {
return ACFunctionsHelper.automationAcFunctions(deviceId, deviceName, functionValue); return ACFunctionsHelper.automationAcFunctions(
deviceId, deviceName, functionValue);
} }
return ACFunctionsHelper.tabToRunAcFunctions(deviceId, deviceName, functionValue); return ACFunctionsHelper.tabToRunAcFunctions(
deviceId, deviceName, functionValue);
} }
List<SceneStaticFunction> getTaskListFunctionsFromApi({ List<SceneStaticFunction> getTaskListFunctionsFromApi({
@ -149,8 +208,12 @@ mixin SceneOperationsDataHelper {
SceneStaticFunction( SceneStaticFunction(
deviceId: action.entityId, deviceId: action.entityId,
deviceName: action.name.toString(), deviceName: action.name.toString(),
deviceIcon: action.type == 'automation' ? Assets.player : Assets.handClickIcon, deviceIcon: action.type == 'automation'
icon: action.type == 'automation' ? Assets.player : Assets.handClickIcon, ? Assets.player
: Assets.handClickIcon,
icon: action.type == 'automation'
? Assets.player
: Assets.handClickIcon,
operationName: action.type.toString(), operationName: action.type.toString(),
operationDialogType: OperationDialogType.onOff, operationDialogType: OperationDialogType.onOff,
functionValue: action.actionExecutor, functionValue: action.actionExecutor,
@ -170,7 +233,8 @@ mixin SceneOperationsDataHelper {
), ),
); );
} else { } else {
functions.add(_mapExecutorPropertyToSceneFunction(action, isAutomation)); functions
.add(_mapExecutorPropertyToSceneFunction(action, isAutomation));
} }
} }
@ -206,7 +270,9 @@ mixin SceneOperationsDataHelper {
}) { }) {
final executorProperty = action.executorProperty; final executorProperty = action.executorProperty;
final Map<String, SceneStaticFunction Function(Action, bool, String?, String?)> functionMap = { final Map<String,
SceneStaticFunction Function(Action, bool, String?, String?)>
functionMap = {
'sensitivity': _createSensitivityFunction, 'sensitivity': _createSensitivityFunction,
'normal_open_switch': _createNormalOpenSwitchFunction, 'normal_open_switch': _createNormalOpenSwitchFunction,
'unlock_fingerprint': _createUnlockFingerprintFunction, 'unlock_fingerprint': _createUnlockFingerprintFunction,
@ -282,14 +348,16 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createSensitivityFunction( SceneStaticFunction _createSensitivityFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Presence Sensor', 'Presence Sensor',
Assets.assetsIconsSensors, Assets.assetsIconsSensors,
'Sensitivity', 'Sensitivity',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.listOfOptions, isAutomation
? OperationDialogType.integerSteps
: OperationDialogType.listOfOptions,
isAutomation ? _createIntegerStepsOptions() : _createSensitivityOptions(), isAutomation ? _createIntegerStepsOptions() : _createSensitivityOptions(),
isAutomation, isAutomation,
comparator, comparator,
@ -297,8 +365,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createNormalOpenSwitchFunction( SceneStaticFunction _createNormalOpenSwitchFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -351,8 +419,8 @@ mixin SceneOperationsDataHelper {
]; ];
} }
SceneStaticFunction _createUnlockFingerprintFunction( SceneStaticFunction _createUnlockFingerprintFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -366,8 +434,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createUnlockPasswordFunction( SceneStaticFunction _createUnlockPasswordFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -381,8 +449,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createUnlockCardFunction( SceneStaticFunction _createUnlockCardFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -396,8 +464,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createAlarmLockFunction( SceneStaticFunction _createAlarmLockFunction(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -411,8 +479,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createUnlockRequestFunction( SceneStaticFunction _createUnlockRequestFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -426,8 +494,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createResidualElectricityFunction( SceneStaticFunction _createResidualElectricityFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -441,8 +509,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createReverseLockFunction( SceneStaticFunction _createReverseLockFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -456,8 +524,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createUnlockAppFunction( SceneStaticFunction _createUnlockAppFunction(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -471,8 +539,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createHijackFunction( SceneStaticFunction _createHijackFunction(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -486,8 +554,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createDoorbellFunction( SceneStaticFunction _createDoorbellFunction(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -501,8 +569,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createUnlockTemporaryFunction( SceneStaticFunction _createUnlockTemporaryFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'WIFI LOCK PRO', 'WIFI LOCK PRO',
@ -516,8 +584,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createFarDetectionFunction( SceneStaticFunction _createFarDetectionFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Human Presence Sensor', 'Human Presence Sensor',
@ -531,8 +599,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createMotionSensitivityFunction( SceneStaticFunction _createMotionSensitivityFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Human Presence Sensor', 'Human Presence Sensor',
@ -546,8 +614,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createMotionlessSensitivityFunction( SceneStaticFunction _createMotionlessSensitivityFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Human Presence Sensor', 'Human Presence Sensor',
@ -561,8 +629,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createIndicatorFunction( SceneStaticFunction _createIndicatorFunction(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Human Presence Sensor', 'Human Presence Sensor',
@ -576,8 +644,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createPresenceTimeFunction( SceneStaticFunction _createPresenceTimeFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Human Presence Sensor', 'Human Presence Sensor',
@ -591,8 +659,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createPresenceStateFunction( SceneStaticFunction _createPresenceStateFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Human Presence Sensor', 'Human Presence Sensor',
@ -606,14 +674,16 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createDisCurrentFunction( SceneStaticFunction _createDisCurrentFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Human Presence Sensor', 'Human Presence Sensor',
Assets.assetsIconsSensors, Assets.assetsIconsSensors,
'Current Distance', 'Current Distance',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.countdown, isAutomation
? OperationDialogType.integerSteps
: OperationDialogType.countdown,
_createCurrentDistanceOptions(), _createCurrentDistanceOptions(),
isAutomation, isAutomation,
comparator, comparator,
@ -621,8 +691,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createIlluminanceValueFunction( SceneStaticFunction _createIlluminanceValueFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Human Presence Sensor', 'Human Presence Sensor',
@ -636,8 +706,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createCheckingResultFunction( SceneStaticFunction _createCheckingResultFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Human Presence Sensor', 'Human Presence Sensor',
@ -651,8 +721,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createSwitchFunction( SceneStaticFunction _createSwitchFunction(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Smart AC Thermostat - Grey - Model A', 'Smart AC Thermostat - Grey - Model A',
@ -666,23 +736,27 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createTempSetFunction( SceneStaticFunction _createTempSetFunction(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Smart AC Thermostat - Grey - Model A', 'Smart AC Thermostat - Grey - Model A',
Assets.assetsIconsAC, Assets.assetsIconsAC,
'Set Temperature', 'Set Temperature',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.temperature, isAutomation
isAutomation ? _createAutomationTemperatureOptions() : _createTemperatureOptions(), ? OperationDialogType.integerSteps
: OperationDialogType.temperature,
isAutomation
? _createAutomationTemperatureOptions()
: _createTemperatureOptions(),
isAutomation, isAutomation,
comparator, comparator,
uniqueCustomId, uniqueCustomId,
); );
} }
SceneStaticFunction _createTempCurrentFunction( SceneStaticFunction _createTempCurrentFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Smart AC Thermostat - Grey - Model A', 'Smart AC Thermostat - Grey - Model A',
@ -696,8 +770,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createModeFunction( SceneStaticFunction _createModeFunction(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Smart AC Thermostat - Grey - Model A', 'Smart AC Thermostat - Grey - Model A',
@ -711,8 +785,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createLevelFunction( SceneStaticFunction _createLevelFunction(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Smart AC Thermostat - Grey - Model A', 'Smart AC Thermostat - Grey - Model A',
@ -726,8 +800,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createChildLockFunction( SceneStaticFunction _createChildLockFunction(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Smart AC Thermostat - Grey - Model A', 'Smart AC Thermostat - Grey - Model A',
@ -741,23 +815,38 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createSwitch1Function( SceneStaticFunction _createSwitch1Function(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( switch (action.productType) {
action, case "3G":
'3 Gang Button Switch L-L', return _createSceneFunction(
Assets.assetsIcons3GangSwitch, action,
'Light 1 Switch', '3 Gang Button Switch L-L',
OperationDialogType.onOff, Assets.assetsIcons3GangSwitch,
_createOnOffOptions(), 'Light 1 Switch',
isAutomation, OperationDialogType.onOff,
comparator, _createOnOffOptions(),
uniqueCustomId, isAutomation,
); comparator,
uniqueCustomId,
);
default:
return _createSceneFunction(
action,
'1 Gang Button Switch L-L',
Assets.oneGang,
'Light Switch',
OperationDialogType.onOff,
_createOnOffOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
}
} }
SceneStaticFunction _createSwitch2Function( SceneStaticFunction _createSwitch2Function(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'3 Gang Button Switch L-L', '3 Gang Button Switch L-L',
@ -771,8 +860,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createSwitch3Function( SceneStaticFunction _createSwitch3Function(Action action, bool isAutomation,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'3 Gang Button Switch L-L', '3 Gang Button Switch L-L',
@ -786,53 +875,84 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createCountdown1Function( SceneStaticFunction _createCountdown1Function(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( switch (action.productType) {
action, case "3G":
'3 Gang Button Switch L-L', return _createSceneFunction(
Assets.assetsIcons3GangSwitch, action,
'Light 1 CountDown', '3 Gang Button Switch L-L',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.countdown, Assets.assetsIcons3GangSwitch,
isAutomation ? _createAutomationCountDownOptions() : _createCountdownOptions(), 'Light 1 CountDown',
isAutomation, isAutomation
comparator, ? OperationDialogType.integerSteps
uniqueCustomId, : OperationDialogType.countdown,
); isAutomation
? _createAutomationCountDownOptions()
: _createCountdownOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
default:
return _createSceneFunction(
action,
'1 Gang Button Switch L-L',
Assets.oneGang,
'Light CountDown',
isAutomation
? OperationDialogType.integerSteps
: OperationDialogType.countdown,
isAutomation
? _createAutomationCountDownOptions()
: _createCountdownOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
}
} }
SceneStaticFunction _createCountdown2Function( SceneStaticFunction _createCountdown2Function(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'3 Gang Button Switch L-L', '3 Gang Button Switch L-L',
Assets.assetsIcons3GangSwitch, Assets.assetsIcons3GangSwitch,
'Light 2 CountDown', 'Light 2 CountDown',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.countdown, isAutomation
isAutomation ? _createAutomationCountDownOptions() : _createCountdownOptions(), ? OperationDialogType.integerSteps
: OperationDialogType.countdown,
isAutomation
? _createAutomationCountDownOptions()
: _createCountdownOptions(),
isAutomation, isAutomation,
comparator, comparator,
uniqueCustomId, uniqueCustomId,
); );
} }
SceneStaticFunction _createCountdown3Function( SceneStaticFunction _createCountdown3Function(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'3 Gang Button Switch L-L', '3 Gang Button Switch L-L',
Assets.assetsIcons3GangSwitch, Assets.assetsIcons3GangSwitch,
'Light 3 CountDown', 'Light 3 CountDown',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.countdown, isAutomation
isAutomation ? _createAutomationCountDownOptions() : _createCountdownOptions(), ? OperationDialogType.integerSteps
: OperationDialogType.countdown,
isAutomation
? _createAutomationCountDownOptions()
: _createCountdownOptions(),
isAutomation, isAutomation,
comparator, comparator,
uniqueCustomId, uniqueCustomId,
); );
} }
SceneStaticFunction _createSwitchAlarmSoundFunction( SceneStaticFunction _createSwitchAlarmSoundFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Gateway', 'Gateway',
@ -846,8 +966,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createMasterStateFunction( SceneStaticFunction _createMasterStateFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Gateway', 'Gateway',
@ -861,8 +981,8 @@ mixin SceneOperationsDataHelper {
); );
} }
SceneStaticFunction _createFactoryResetFunction( SceneStaticFunction _createFactoryResetFunction(Action action,
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) { bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction( return _createSceneFunction(
action, action,
'Gateway', 'Gateway',
@ -1180,8 +1300,12 @@ mixin SceneOperationsDataHelper {
uniqueCustomId: taskItem.uniqueCustomId, uniqueCustomId: taskItem.uniqueCustomId,
deviceId: taskItem.deviceId, deviceId: taskItem.deviceId,
deviceName: taskItem.deviceName.toString(), deviceName: taskItem.deviceName.toString(),
deviceIcon: taskItem.operationName == 'automation' ? Assets.player : Assets.handClickIcon, deviceIcon: taskItem.operationName == 'automation'
icon: taskItem.operationName == 'automation' ? Assets.player : Assets.handClickIcon, ? Assets.player
: Assets.handClickIcon,
icon: taskItem.operationName == 'automation'
? Assets.player
: Assets.handClickIcon,
operationName: taskItem.operationName, operationName: taskItem.operationName,
operationDialogType: OperationDialogType.onOff, operationDialogType: OperationDialogType.onOff,
functionValue: taskItem.functionValue == 'rule_enable' ? true : false, functionValue: taskItem.functionValue == 'rule_enable' ? true : false,

View File

@ -74,6 +74,7 @@ class Action {
ExecutorProperty? executorProperty; ExecutorProperty? executorProperty;
String? name; String? name;
String? type; String? type;
String? productType;
Action({ Action({
required this.actionExecutor, required this.actionExecutor,
@ -81,6 +82,7 @@ class Action {
this.executorProperty, this.executorProperty,
this.name, this.name,
this.type, this.type,
this.productType,
}); });
String toRawJson() => json.encode(toJson()); String toRawJson() => json.encode(toJson());
@ -88,10 +90,11 @@ class Action {
static Action? fromJson(Map<String, dynamic> json) { static Action? fromJson(Map<String, dynamic> json) {
if (json['name'] != null && json['type'] != null) { if (json['name'] != null && json['type'] != null) {
return Action( return Action(
actionExecutor: json["actionExecutor"], actionExecutor: json["actionExecutor"] as String,
entityId: json["entityId"], entityId: json["entityId"] as String,
name: json['name'], name: json['name'] as String?,
type: json['type'], type: json['type'] as String?,
productType: json['productType'] as String?,
); );
} }
if (json["executorProperty"] == null) { if (json["executorProperty"] == null) {
@ -99,9 +102,10 @@ class Action {
} }
return Action( return Action(
actionExecutor: json["actionExecutor"], actionExecutor: json["actionExecutor"] as String,
entityId: json["entityId"], entityId: json["entityId"] as String,
executorProperty: ExecutorProperty.fromJson(json["executorProperty"]), executorProperty: ExecutorProperty.fromJson(json["executorProperty"]),
productType: json['productType'] as String?,
); );
} }

View File

@ -20,69 +20,82 @@ class SceneRoomsTabBarDevicesView extends StatefulWidget {
_SceneRoomsTabBarDevicesViewState(); _SceneRoomsTabBarDevicesViewState();
} }
class _SceneRoomsTabBarDevicesViewState extends State<SceneRoomsTabBarDevicesView> class _SceneRoomsTabBarDevicesViewState
extends State<SceneRoomsTabBarDevicesView>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
late final TabController _tabController; late final TabController _tabController;
List<SubSpaceModel>? rooms = [];
late final SpaceModel selectedSpace; late final SpaceModel selectedSpace;
var rooms = <SubSpaceModel>[];
@override @override
void initState() { void initState() {
super.initState(); super.initState();
selectedSpace = HomeCubit.getInstance().selectedSpace!; WidgetsBinding.instance.addPostFrameCallback((_) {
selectedSpace = HomeCubit.getInstance().selectedSpace!;
rooms = List.from(selectedSpace.subspaces); rooms = List.from(selectedSpace.subspaces ?? []);
final defaultSubSpaceModel = SubSpaceModel(
name: 'All Devices',
devices: context.read<DevicesCubit>().allDevices,
id: '-1',
);
if (rooms.isNotEmpty) { if (rooms != null && rooms!.isNotEmpty) {
final isFirstRoomIdValid = rooms[0].id != '-1'; if (rooms![0].id != '-1') {
if (isFirstRoomIdValid) { rooms?.insert(
rooms.insert(0, defaultSubSpaceModel); 0,
SubSpaceModel(
name: 'All Devices',
devices: context.read<DevicesCubit>().allDevices,
id: '-1',
),
);
}
} else {
rooms = [
SubSpaceModel(
name: 'All Devices',
devices: context.read<DevicesCubit>().allDevices,
id: '-1',
)
];
} }
} else {
rooms = [defaultSubSpaceModel];
}
_tabController = TabController(length: rooms.length, vsync: this); _tabController = TabController(length: rooms!.length, vsync: this);
_tabController.addListener(_handleTabSwitched); _tabController.addListener(_handleTabSwitched);
} setState(() {});
});
@override
void dispose() {
super.dispose();
_tabController.removeListener(() {});
_tabController.dispose();
} }
void _handleTabSwitched() { void _handleTabSwitched() {
if (_tabController.indexIsChanging) { if (_tabController.indexIsChanging) {
final index = _tabController.index; final value = _tabController.index;
context.read<TabBarBloc>().add( /// select tab
TabBarTabChangedEvent( context.read<TabBarBloc>().add(TabChanged(
selectedIndex: index, selectedIndex: value,
roomId: rooms[index].id ?? '', roomId: rooms?[value].id ?? '',
unit: selectedSpace, unit: selectedSpace));
),
);
return; return;
} }
} }
@override
void dispose() {
super.dispose();
_tabController.dispose();
_tabController.removeListener(() {});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DefaultScaffold( return DefaultScaffold(
padding: EdgeInsetsDirectional.zero,
leading: IconButton(
onPressed: () => navigateToRoute(context, Routes.sceneTasksRoute),
icon: const Icon(Icons.arrow_back_ios),
),
title: StringsManager.createScene, title: StringsManager.createScene,
padding: EdgeInsets.zero,
leading: IconButton(
onPressed: () {
navigateToRoute(context, Routes.sceneTasksRoute);
},
icon: const Icon(
Icons.arrow_back_ios,
),
),
child: SceneDevicesBody(tabController: _tabController, rooms: rooms), child: SceneDevicesBody(tabController: _tabController, rooms: rooms),
); );
} }

View File

@ -1,5 +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:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_state.dart'; import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_state.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart'; import 'package:syncrow_app/features/devices/model/subspace_model.dart';
@ -7,44 +8,60 @@ import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_bloc.dart'
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_state.dart'; import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_state.dart';
import 'package:syncrow_app/features/scene/enum/create_scene_enum.dart'; import 'package:syncrow_app/features/scene/enum/create_scene_enum.dart';
import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.dart'; import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.dart';
import 'package:syncrow_app/features/scene/widgets/scene_devices/scene_devices_body_tab_bar.dart'; import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart';
import 'package:syncrow_app/features/scene/widgets/scene_devices/scene_devices_list.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/app_loading_indicator.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/navigation/routing_constants.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class SceneDevicesBody extends StatelessWidget { class SceneDevicesBody extends StatelessWidget {
const SceneDevicesBody({ const SceneDevicesBody({
required this.tabController,
required this.rooms,
super.key, super.key,
}); required TabController tabController,
required this.rooms,
}) : _tabController = tabController;
final TabController tabController; final TabController _tabController;
final List<SubSpaceModel> rooms; final List<SubSpaceModel>? rooms;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isAutomationDeviceStatus =
((ModalRoute.of(context)?.settings.arguments as SceneSettingsRouteArguments?)?.sceneType ==
CreateSceneEnum.deviceStatusChanges.name);
return BlocBuilder<TabBarBloc, TabBarState>( return BlocBuilder<TabBarBloc, TabBarState>(
builder: (context, state) { builder: (context, tabState) {
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
SceneDevicesBodyTabBar( TabBar(
tabController: tabController, controller: _tabController,
rooms: rooms, dividerColor: Colors.transparent,
selectedRoomId: state is TabBarTabSelectedState ? state.roomId : '-1', indicatorColor: Colors.transparent,
tabs: [
...rooms!.map((e) => Tab(
child: BodyLarge(
text: e.name ?? '',
textAlign: TextAlign.start,
style: context.bodyLarge.copyWith(
color: (tabState is TabSelected) && tabState.roomId == e.id
? ColorsManager.textPrimaryColor
: ColorsManager.textPrimaryColor.withOpacity(0.2),
),
),
)),
],
isScrollable: true,
tabAlignment: TabAlignment.start,
), ),
Expanded( Expanded(
child: TabBarView( child: TabBarView(
controller: _tabController,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
controller: tabController, children:
children: rooms rooms!.map((e) => _buildRoomTab(e, context, isAutomationDeviceStatus)).toList(),
.map(
(room) => _buildRoomTab(
room,
_isAutomationDeviceStatus(context),
),
)
.toList(),
), ),
), ),
], ],
@ -53,46 +70,52 @@ class SceneDevicesBody extends StatelessWidget {
); );
} }
bool _isAutomationDeviceStatus(BuildContext context) { Widget _buildRoomTab(SubSpaceModel room, BuildContext context, bool isAutomationDeviceStatus) {
final routeArguments =
ModalRoute.of(context)?.settings.arguments as SceneSettingsRouteArguments?;
final deviceStatusChangesScene = CreateSceneEnum.deviceStatusChanges.name;
final sceneType = routeArguments?.sceneType;
return sceneType == deviceStatusChangesScene;
}
Widget _buildRoomTab(
SubSpaceModel room,
bool isAutomationDeviceStatus,
) {
return BlocBuilder<DeviceManagerBloc, DeviceManagerState>( return BlocBuilder<DeviceManagerBloc, DeviceManagerState>(
builder: (context, state) { builder: (context, state) {
final isLoading = state.loading && state.devices == null; if (state.loading && state.devices == null) {
final hasData = return const Center(child: CircularProgressIndicator());
state.devices != null && (state.devices?.isNotEmpty ?? false); } else if (state.devices != null && state.devices!.isNotEmpty) {
final hasError = state.error != null; return ListView.builder(
itemCount: state.devices!.length,
final widgets = <bool, Widget>{ itemBuilder: (context, index) {
isLoading: const AppLoadingIndicator(), final device = state.devices![index];
hasError: Center(child: Text('${state.error}')), return DefaultContainer(
hasData: SceneDevicesList( child: SceneListTile(
devices: state.devices ?? [], minLeadingWidth: 40,
isAutomationDeviceStatus: isAutomationDeviceStatus, leadingWidget: SvgPicture.asset(device.icon ?? ''),
), titleWidget: BodyMedium(
}; text: device.name ?? '',
style: context.titleSmall.copyWith(
final invalidWidgetEntry = MapEntry( color: ColorsManager.secondaryTextColor,
true, fontWeight: FontWeight.w400,
Center(child: Text('This subspace has no devices')), fontSize: 20,
); ),
),
final validWidgetEntry = widgets.entries.firstWhere( trailingWidget: const Icon(
(entry) => entry.key == true, Icons.arrow_forward_ios_rounded,
orElse: () => invalidWidgetEntry, color: ColorsManager.greyColor,
); size: 16,
),
return validWidgetEntry.value; onPressed: () {
Navigator.pushNamed(
context,
Routes.deviceFunctionsRoute,
arguments: {
"device": device,
"isAutomationDeviceStatus": isAutomationDeviceStatus
},
);
},
),
);
},
);
} else if (state.error != null) {
return const Center(child: Text('Something went wrong'));
} else {
return const SizedBox();
}
}, },
); );
} }

View File

@ -1,46 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class SceneDevicesBodyTabBar extends StatelessWidget {
const SceneDevicesBodyTabBar({
required this.tabController,
required this.rooms,
required this.selectedRoomId,
super.key,
});
final String selectedRoomId;
final TabController tabController;
final List<SubSpaceModel> rooms;
@override
Widget build(BuildContext context) {
return TabBar(
controller: tabController,
dividerColor: Colors.transparent,
indicatorColor: Colors.transparent,
isScrollable: true,
tabAlignment: TabAlignment.start,
tabs: rooms.map((e) {
final isSelected = selectedRoomId == e.id;
return Tab(
child: BodyLarge(
text: e.name ?? '',
textAlign: TextAlign.start,
style: context.bodyLarge.copyWith(
color: isSelected
? ColorsManager.textPrimaryColor
: ColorsManager.textPrimaryColor.withValues(
alpha: 0.2,
),
),
),
);
}).toList(),
);
}
}

View File

@ -1,66 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/navigation/routing_constants.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class SceneDevicesList extends StatelessWidget {
const SceneDevicesList({
required this.isAutomationDeviceStatus,
required this.devices,
super.key,
});
final List<DeviceModel> devices;
final bool isAutomationDeviceStatus;
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: devices.length,
itemBuilder: (context, index) => _buildDeviceTile(context, devices[index]),
);
}
Widget _buildDeviceTile(
BuildContext context,
DeviceModel device,
) {
return DefaultContainer(
child: SceneListTile(
minLeadingWidth: 40,
leadingWidget: SvgPicture.asset(device.icon ?? ''),
titleWidget: BodyMedium(
text: device.name ?? '',
style: context.titleSmall.copyWith(
color: ColorsManager.secondaryTextColor,
fontWeight: FontWeight.w400,
fontSize: 20,
),
),
trailingWidget: const Icon(
Icons.arrow_forward_ios_rounded,
color: ColorsManager.greyColor,
size: 16,
),
onPressed: () => _navigateToDeviceFunctions(context, device),
),
);
}
void _navigateToDeviceFunctions(
BuildContext context,
DeviceModel device,
) {
Navigator.of(context).pushNamed(
Routes.deviceFunctionsRoute,
arguments: {
"device": device,
"isAutomationDeviceStatus": isAutomationDeviceStatus,
},
);
}
}

View File

@ -3,8 +3,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/model/community_model.dart'; import 'package:syncrow_app/features/app_layout/model/community_model.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart'; import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/app_layout/view/app_layout.dart'; import 'package:syncrow_app/features/app_layout/view/app_layout.dart';
import 'package:syncrow_app/features/auth/view/login_view.dart';
import 'package:syncrow_app/features/auth/view/otp_view.dart'; import 'package:syncrow_app/features/auth/view/otp_view.dart';
import 'package:syncrow_app/features/auth/view/login_view.dart';
import 'package:syncrow_app/features/auth/view/sign_up_view.dart'; import 'package:syncrow_app/features/auth/view/sign_up_view.dart';
import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart'; import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart';
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart';
@ -17,12 +17,11 @@ import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_bloc.dart'
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart'; import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart';
import 'package:syncrow_app/features/scene/view/device_functions_view.dart'; import 'package:syncrow_app/features/scene/view/device_functions_view.dart';
import 'package:syncrow_app/features/scene/view/scene_auto_settings.dart'; import 'package:syncrow_app/features/scene/view/scene_auto_settings.dart';
import 'package:syncrow_app/features/scene/view/scene_rooms_tabbar.dart';
import 'package:syncrow_app/features/scene/view/scene_tasks_view.dart'; import 'package:syncrow_app/features/scene/view/scene_tasks_view.dart';
import 'package:syncrow_app/features/scene/view/scene_rooms_tabbar.dart';
import 'package:syncrow_app/features/scene/view/scene_view.dart'; import 'package:syncrow_app/features/scene/view/scene_view.dart';
import 'package:syncrow_app/features/scene/view/smart_automation_select_route.dart'; import 'package:syncrow_app/features/scene/view/smart_automation_select_route.dart';
import 'package:syncrow_app/features/splash/view/splash_view.dart'; import 'package:syncrow_app/features/splash/view/splash_view.dart';
import 'routing_constants.dart'; import 'routing_constants.dart';
class Router { class Router {
@ -89,7 +88,7 @@ class Router {
BlocProvider( BlocProvider(
create: (BuildContext context) => create: (BuildContext context) =>
TabBarBloc(context.read<DeviceManagerBloc>()) TabBarBloc(context.read<DeviceManagerBloc>())
..add(TabBarTabChangedEvent( ..add(TabChanged(
selectedIndex: 0, selectedIndex: 0,
roomId: '-1', roomId: '-1',
unit: SpaceModel( unit: SpaceModel(

View File

@ -11,7 +11,7 @@ abstract class ApiEndpoints {
static const String sendOtp = '/authentication/user/send-otp'; static const String sendOtp = '/authentication/user/send-otp';
static const String verifyOtp = '/authentication/user/verify-otp'; static const String verifyOtp = '/authentication/user/verify-otp';
static const String forgetPassword = '/authentication/user/forget-password'; static const String forgetPassword = '/authentication/user/forget-password';
static const String clientLogin = 'client/token';
////////////////////////////////////// Spaces /////////////////////////////////////// ////////////////////////////////////// Spaces ///////////////////////////////////////
///Community Module ///Community Module
@ -111,9 +111,9 @@ abstract class ApiEndpoints {
//POST //POST
static const String addDeviceToRoom = '/device/room'; static const String addDeviceToRoom = '/device/room';
static const String addDeviceToGroup = '/device/group'; static const String addDeviceToGroup = '/device/group';
static const String controlDevice = '/devices/{deviceUuid}/command'; static const String controlDevice = '/device/{deviceUuid}/control';
static const String firmwareDevice = static const String firmwareDevice =
'/devices/{deviceUuid}/firmware/{firmwareVersion}'; '/device/{deviceUuid}/firmware/{firmwareVersion}';
static const String getDevicesByUserId = '/device/user/{userId}'; static const String getDevicesByUserId = '/device/user/{userId}';
static const String getDevicesByUnitId = '/device/unit/{unitUuid}'; static const String getDevicesByUnitId = '/device/unit/{unitUuid}';
static const String openDoorLock = '/door-lock/open/{doorLockUuid}'; static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
@ -121,13 +121,13 @@ abstract class ApiEndpoints {
//GET //GET
static const String deviceByRoom = static const String deviceByRoom =
'/projects/{projectUuid}/communities/{communityUuid}/spaces/{spaceUuid}/subspaces/{subSpaceUuid}/devices'; '/projects/{projectUuid}/communities/{communityUuid}/spaces/{spaceUuid}/subspaces/{subSpaceUuid}/devices';
static const String deviceByUuid = '/devices/{deviceUuid}'; static const String deviceByUuid = '/device/{deviceUuid}';
static const String deviceFunctions = '/devices/{deviceUuid}/functions'; static const String deviceFunctions = '/device/{deviceUuid}/functions';
static const String gatewayApi = '/devices/gateway/{gatewayUuid}/devices'; static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices';
static const String deviceFunctionsStatus = static const String deviceFunctionsStatus =
'/devices/{deviceUuid}/functions/status'; '/device/{deviceUuid}/functions/status';
static const String powerClamp = static const String powerClamp =
'/devices/{deviceUuid}/functions/status'; '/device/{powerClampUuid}/power-clamp/status';
///Device Permission Module ///Device Permission Module
//POST //POST
@ -153,8 +153,7 @@ abstract class ApiEndpoints {
static const String getScene = '/scene/tap-to-run/{sceneId}'; static const String getScene = '/scene/tap-to-run/{sceneId}';
static const String getIconScene = '/scene/icon'; static const String getIconScene = '/scene/icon';
static const String getUnitAutomation = static const String getUnitAutomation = '/projects/{projectId}/communities/{communityId}/spaces/{unitUuid}/automations';
'/projects/{projectId}/communities/{communityId}/spaces/{unitUuid}/automations';
static const String getAutomationDetails = static const String getAutomationDetails =
'/projects/{projectId}/automations/{automationId}'; '/projects/{projectId}/automations/{automationId}';
@ -162,8 +161,7 @@ abstract class ApiEndpoints {
/// PUT /// PUT
static const String updateScene = '/scene/tap-to-run/{sceneId}'; static const String updateScene = '/scene/tap-to-run/{sceneId}';
static const String updateAutomation = static const String updateAutomation = '/projects/{projectId}/automations/{automationId}';
'/projects/{projectId}/automations/{automationId}';
static const String updateAutomationStatus = static const String updateAutomationStatus =
'/projects/{projectId}/automations/{automationId}'; '/projects/{projectId}/automations/{automationId}';
@ -171,8 +169,7 @@ abstract class ApiEndpoints {
/// DELETE /// DELETE
static const String deleteScene = '/scene/tap-to-run/{sceneId}'; static const String deleteScene = '/scene/tap-to-run/{sceneId}';
static const String deleteAutomation = static const String deleteAutomation = '/projects/{projectId}/automations/{automationId}';
'/projects/{projectId}/automations/{automationId}';
//////////////////////Door Lock ////////////////////// //////////////////////Door Lock //////////////////////
//online //online
@ -216,18 +213,18 @@ abstract class ApiEndpoints {
static const String changeSchedule = '/schedule/enable/{deviceUuid}'; static const String changeSchedule = '/schedule/enable/{deviceUuid}';
static const String deleteSchedule = '/schedule/{deviceUuid}/{scheduleId}'; static const String deleteSchedule = '/schedule/{deviceUuid}/{scheduleId}';
static const String reportLogs = static const String reportLogs =
'/devices/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}'; '/device/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}';
static const String controlBatch = '/devices/batch'; static const String controlBatch = '/device/control/batch';
static const String statusBatch = '/devices/batch'; static const String statusBatch = '/device/status/batch';
static const String deviceScene = '/devices/{deviceUuid}/scenes'; static const String deviceScene = '/device/{deviceUuid}/scenes';
static const String fourSceneByName = static const String fourSceneByName =
'/devices/{deviceUuid}/scenes?switchName={switchName}'; '/device/{deviceUuid}/scenes?switchName={switchName}';
static const String resetDevice = '/factory/reset/{deviceUuid}'; static const String resetDevice = '/factory/reset/{deviceUuid}';
static const String unAssignScenesDevice = static const String unAssignScenesDevice =
'/devices/{deviceUuid}/scenes?switchName={switchName}'; '/device/{deviceUuid}/scenes?switchName={switchName}';
static const String getDeviceLogs = '/devices/report-logs/{uuid}?code={code}'; static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
static const String terms = '/terms'; static const String terms = '/terms';
static const String policy = '/policy'; static const String policy = '/policy';
static const String getPermission = '/permission/{roleUuid}'; static const String getPermission = '/permission/{roleUuid}';

View File

@ -25,15 +25,11 @@ class AuthenticationAPI {
return response; return response;
} }
static Future<bool> signUp({ static Future<bool> signUp({required SignUpModel model}) async {
required SignUpModel model,
required String accessToken,
}) async {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.signUp, path: ApiEndpoints.signUp,
body: model.toJson(), body: model.toJson(),
showServerMessage: false, showServerMessage: false,
accessToken: accessToken,
expectedResponseModel: (json) => json['statusCode'] == 201); expectedResponseModel: (json) => json['statusCode'] == 201);
return response; return response;
} }
@ -67,20 +63,4 @@ class AuthenticationAPI {
expectedResponseModel: (json) => json['data']); expectedResponseModel: (json) => json['data']);
return response; return response;
} }
static Future<Map<String, dynamic>> fetchClientToken({
required String clientId,
required String clientSecret,
}) async {
final response = await HTTPService().post(
path: ApiEndpoints.clientLogin,
body: {
'clientId': clientId,
'clientSecret': clientSecret,
},
showServerMessage: false,
expectedResponseModel: (json) => json['data'],
);
return response;
}
} }

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'package:syncrow_app/features/devices/model/device_category_model.dart'; import 'package:syncrow_app/features/devices/model/device_category_model.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart'; import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart';
@ -7,6 +8,7 @@ import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/function_model.dart'; import 'package:syncrow_app/features/devices/model/function_model.dart';
import 'package:syncrow_app/services/api/api_links_endpoints.dart'; import 'package:syncrow_app/services/api/api_links_endpoints.dart';
import 'package:syncrow_app/services/api/http_service.dart'; import 'package:syncrow_app/services/api/http_service.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import '../../features/devices/model/create_temporary_password_model.dart'; import '../../features/devices/model/create_temporary_password_model.dart';
class DevicesAPI { class DevicesAPI {
@ -37,7 +39,7 @@ class DevicesAPI {
path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId),
body: {"deviceName": deviceName}, body: {"deviceName": deviceName},
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['data']; return json;
}, },
); );
return response; return response;
@ -90,7 +92,7 @@ class DevicesAPI {
.replaceAll('{deviceUuid}', deviceId), .replaceAll('{deviceUuid}', deviceId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['data']; return json;
}, },
); );
return response; return response;
@ -99,7 +101,7 @@ class DevicesAPI {
static Future<Map<String, dynamic>> getPowerClampStatus( static Future<Map<String, dynamic>> getPowerClampStatus(
String deviceId) async { String deviceId) async {
final response = await _httpService.get( final response = await _httpService.get(
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{powerClampUuid}', deviceId), path: ApiEndpoints.powerClamp.replaceAll('{powerClampUuid}', deviceId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json; return json;
@ -130,7 +132,7 @@ class DevicesAPI {
path: ApiEndpoints.deviceFunctions.replaceAll('{deviceUuid}', deviceId), path: ApiEndpoints.deviceFunctions.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
final functions = FunctionModel.fromJson(json['data']); final functions = FunctionModel.fromJson(json);
return functions; return functions;
}); });
return response; return response;
@ -186,7 +188,7 @@ class DevicesAPI {
path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['data']; return json;
}); });
return response; return response;
} }
@ -262,7 +264,7 @@ class DevicesAPI {
if (json == null || json.isEmpty || json == []) { if (json == null || json.isEmpty || json == []) {
return devices; return devices;
} }
for (var device in json['data']['devices']) { for (var device in json['devices']) {
devices.add(DeviceModel.fromJson(device)); devices.add(DeviceModel.fromJson(device));
} }
return devices; return devices;
@ -489,12 +491,7 @@ class DevicesAPI {
}) async { }) async {
final response = await _httpService.post( final response = await _httpService.post(
path: ApiEndpoints.controlBatch, path: ApiEndpoints.controlBatch,
body: { body: {"devicesUuid": devicesUuid, "code": code, "value": value},
"devicesUuid": devicesUuid,
"code": code,
"value": value,
"operationType": 'COMMAND',
},
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json; return json;

View File

@ -34,7 +34,7 @@ class HomeManagementAPI {
path: ApiEndpoints.devices.replaceAll("{projectUuid}", projectUuid), path: ApiEndpoints.devices.replaceAll("{projectUuid}", projectUuid),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
json['data'].forEach((value) { json.forEach((value) {
list.add(DeviceModel.fromJson(value)); list.add(DeviceModel.fromJson(value));
}); });
}); });

View File

@ -48,26 +48,13 @@ class HTTPService {
Options? options, Options? options,
dynamic body, dynamic body,
bool showServerMessage = true, bool showServerMessage = true,
String? accessToken,
required T Function(dynamic) expectedResponseModel}) async { required T Function(dynamic) expectedResponseModel}) async {
try { try {
final authOptions = options ??
Options(
headers: accessToken != null
? {
'Authorization': 'Bearer $accessToken',
'Content-Type': 'application/json',
}
: {
'Content-Type': 'application/json',
},
);
final response = await client.post( final response = await client.post(
path, path,
data: body, data: body,
queryParameters: queryParameters, queryParameters: queryParameters,
options: authOptions, options: options,
); );
return expectedResponseModel(response.data); return expectedResponseModel(response.data);
} catch (error) { } catch (error) {