From 980d1017ebb9e49c34fb956d281c8441caf894f2 Mon Sep 17 00:00:00 2001 From: Abdullah Alassaf Date: Sun, 21 Jul 2024 02:10:04 +0300 Subject: [PATCH] Improved the performance of the AC device --- ios/Podfile.lock | 2 +- lib/features/auth/bloc/auth_cubit.dart | 3 +- .../devices/bloc/acs_bloc/acs_bloc.dart | 440 +++++++++++------- .../devices/bloc/acs_bloc/acs_event.dart | 23 +- .../devices/bloc/acs_bloc/acs_state.dart | 6 +- lib/features/devices/model/ac_model.dart | 7 +- lib/features/devices/model/device_model.dart | 34 +- .../view/widgets/ACs/ac_interface.dart | 8 +- .../widgets/ACs/ac_mode_control_unit.dart | 20 +- .../view/widgets/ACs/ac_temp_widget.dart | 16 +- .../devices/view/widgets/ACs/acs_list.dart | 145 +++--- .../view/widgets/ACs/universal_ac_temp.dart | 8 +- 12 files changed, 404 insertions(+), 308 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 8c3f26a..6afeade 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -291,4 +291,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: cf86fcba3fb3dbd505936bc190bb0b8fe3dd2498 -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2 diff --git a/lib/features/auth/bloc/auth_cubit.dart b/lib/features/auth/bloc/auth_cubit.dart index 2b9f14b..efe9794 100644 --- a/lib/features/auth/bloc/auth_cubit.dart +++ b/lib/features/auth/bloc/auth_cubit.dart @@ -62,7 +62,8 @@ class AuthCubit extends Cubit { return 'Please enter your password'; } if (value.isNotEmpty) { - if (!RegExp(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$') + if (!RegExp( + r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!"#$%&()*+,-./:;<=>?@[\]^_`{|}~])[A-Za-z\d!"#$%&()*+,-./:;<=>?@[\]^_`{|}~]{8,}$') .hasMatch(value)) { return 'Password must contain at least:\n - one uppercase letter.\n - one lowercase letter.\n - one number. \n - special character'; } diff --git a/lib/features/devices/bloc/acs_bloc/acs_bloc.dart b/lib/features/devices/bloc/acs_bloc/acs_bloc.dart index b8dad95..8603f98 100644 --- a/lib/features/devices/bloc/acs_bloc/acs_bloc.dart +++ b/lib/features/devices/bloc/acs_bloc/acs_bloc.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart'; @@ -12,6 +14,7 @@ import 'package:syncrow_app/utils/resource_manager/constants.dart'; class ACsBloc extends Bloc { final String acId; AcStatusModel deviceStatus = AcStatusModel( + uuid: '', acSwitch: true, modeString: 'hot', tempSet: 300, @@ -24,6 +27,7 @@ class ACsBloc extends Bloc { bool allAcsOn = true; bool allTempSame = true; int globalTemp = 25; + Timer? _timer; ACsBloc({required this.acId}) : super(AcsInitialState()) { on(_fetchAcsStatus); @@ -56,11 +60,11 @@ class ACsBloc extends Bloc { for (var status in response['status']) { statusModelList.add(StatusModel.fromJson(status)); } - deviceStatus = AcStatusModel.fromJson(statusModelList); + deviceStatus = AcStatusModel.fromJson(response['productUuid'], statusModelList); emit(GetAcStatusState(acStatusModel: deviceStatus)); } } catch (e) { - emit(AcsFailedState(error: e.toString())); + emit(AcsFailedState(errorMessage: e.toString())); return; } } @@ -68,8 +72,6 @@ class ACsBloc extends Bloc { _getAllAcs() async { deviceStatusList = []; devicesList = []; - allAcsOn = true; - allTempSame = true; devicesList = await DevicesAPI.getDeviceByGroupName( HomeCubit.getInstance().selectedSpace?.id ?? '', 'AC'); @@ -79,8 +81,210 @@ class ACsBloc extends Bloc { for (var status in response['status']) { statusModelList.add(StatusModel.fromJson(status)); } - deviceStatusList.add(AcStatusModel.fromJson(statusModelList)); + deviceStatusList.add(AcStatusModel.fromJson(response['productUuid'], statusModelList)); } + _setAllAcsTempsAndSwitches(); + } + + void _changeAcSwitch(AcSwitch event, Emitter emit) async { + final acSwitchValue = !event.acSwitch; + if (allAcsPage) { + emit(AcsLoadingState()); + for (AcStatusModel ac in deviceStatusList) { + if (ac.uuid == event.productId) { + ac.acSwitch = acSwitchValue; + } + } + _setAllAcsTempsAndSwitches(); + _emitAcsStatus(emit); + } else { + emit(AcChangeLoading(acStatusModel: deviceStatus)); + deviceStatus.acSwitch = acSwitchValue; + emit(AcModifyingState(acStatusModel: deviceStatus)); + } + + await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'switch', value: acSwitchValue); + } + + void _changeAllAcSwitch(ChangeAllSwitch event, Emitter emit) async { + emit(AcsLoadingState()); + if (deviceStatusList.length == devicesList.length) { + for (int i = 0; i < deviceStatusList.length; i++) { + deviceStatusList[i].acSwitch = event.value; + } + } + _setAllAcsTempsAndSwitches(); + _emitAcsStatus(emit); + _runDeBouncerForAllAcs(code: 'switch', value: event.value); + } + + void _increaseAllTemp(IncreaseAllTemp event, Emitter emit) async { + emit(AcsLoadingState()); + double tempValue = event.value + 0.5; + int value = (tempValue * 10).toInt(); + + if (!_checkTemperatureValue(tempValue, emit)) { + return; + } + + if (deviceStatusList.length == devicesList.length) { + for (int i = 0; i < deviceStatusList.length; i++) { + deviceStatusList[i].tempSet = value; + } + } + _setAllAcsTempsAndSwitches(); + _emitAcsStatus(emit); + _runDeBouncerForAllAcs(code: 'temp_set', value: value); + } + + void _decreaseAllTemp(DecreaseAllTemp event, Emitter emit) async { + emit(AcsLoadingState()); + + double tempValue = event.value - 0.5; + int value = (tempValue * 10).toInt(); + + if (!_checkTemperatureValue(tempValue, emit)) { + return; + } + + if (deviceStatusList.length == devicesList.length) { + for (int i = 0; i < deviceStatusList.length; i++) { + deviceStatusList[i].tempSet = value; + } + } + _setAllAcsTempsAndSwitches(); + _emitAcsStatus(emit); + _runDeBouncerForAllAcs(code: 'temp_set', value: value); + } + + void _changeLockValue(ChangeLock event, Emitter emit) async { + emit(AcChangeLoading(acStatusModel: deviceStatus)); + + final lockValue = !event.lockBool; + deviceStatus.childLock = lockValue; + emit(AcModifyingState(acStatusModel: deviceStatus)); + + _runDeBouncerForOneDevice(deviceId: acId, code: 'child_lock', value: lockValue); + } + + void _increaseCoolTo(IncreaseCoolToTemp event, Emitter emit) async { + emit(AcChangeLoading(acStatusModel: deviceStatus)); + + double tempValue = event.value + 0.5; + int value = (tempValue * 10).toInt(); + + if (!_checkTemperatureValue(tempValue, emit)) { + return; + } + + if (allAcsPage) { + emit(AcsLoadingState()); + for (AcStatusModel ac in deviceStatusList) { + if (ac.uuid == event.productId) { + ac.tempSet = value; + } + } + _setAllAcsTempsAndSwitches(); + _emitAcsStatus(emit); + } else { + emit(AcChangeLoading(acStatusModel: deviceStatus)); + deviceStatus.tempSet = value; + emit(AcModifyingState(acStatusModel: deviceStatus)); + } + + await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'temp_set', value: value); + } + + void _decreaseCoolTo(DecreaseCoolToTemp event, Emitter emit) async { + emit(AcChangeLoading(acStatusModel: deviceStatus)); + + double tempValue = event.value - 0.5; + int value = (tempValue * 10).toInt(); + + if (!_checkTemperatureValue(tempValue, emit)) { + return; + } + + if (allAcsPage) { + emit(AcsLoadingState()); + for (AcStatusModel ac in deviceStatusList) { + if (ac.uuid == event.productId) { + ac.tempSet = value; + } + } + _setAllAcsTempsAndSwitches(); + _emitAcsStatus(emit); + } else { + emit(AcChangeLoading(acStatusModel: deviceStatus)); + deviceStatus.tempSet = value; + emit(AcModifyingState(acStatusModel: deviceStatus)); + } + + await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'temp_set', value: value); + } + + void _changeAcMode(ChangeAcMode event, Emitter emit) async { + final tempMode = tempModesMap[getNextItem(tempModesMap, event.tempModes)]!; + if (allAcsPage) { + emit(AcsLoadingState()); + for (AcStatusModel ac in deviceStatusList) { + if (ac.uuid == event.productId) { + ac.modeString = getACModeString(tempMode); + ac.acMode = AcStatusModel.getACMode(getACModeString(tempMode)); + } + } + _emitAcsStatus(emit); + } else { + emit(AcChangeLoading(acStatusModel: deviceStatus)); + deviceStatus.modeString = getACModeString(tempMode); + deviceStatus.acMode = AcStatusModel.getACMode(getACModeString(tempMode)); + emit(AcModifyingState(acStatusModel: deviceStatus)); + } + + await _runDeBouncerForOneDevice( + deviceId: event.deviceId, code: 'mode', value: getACModeString(tempMode)); + } + + void _changeFanSpeed(ChangeFanSpeed event, Emitter emit) async { + emit(AcChangeLoading(acStatusModel: deviceStatus)); + + final fanSpeed = event.fanSpeeds; + + if (allAcsPage) { + emit(AcsLoadingState()); + for (AcStatusModel ac in deviceStatusList) { + if (ac.uuid == event.productId) { + ac.fanSpeedsString = getNextFanSpeedKey(fanSpeed); + ac.acFanSpeed = AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed)); + } + } + _emitAcsStatus(emit); + } else { + emit(AcChangeLoading(acStatusModel: deviceStatus)); + deviceStatus.fanSpeedsString = getNextFanSpeedKey(fanSpeed); + deviceStatus.acFanSpeed = AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed)); + emit(AcModifyingState(acStatusModel: deviceStatus)); + } + + await _runDeBouncerForOneDevice( + deviceId: event.deviceId, code: 'level', value: getNextFanSpeedKey(fanSpeed)); + } + + String getACModeString(TempModes value) { + if (value == TempModes.cold) { + return 'cold'; + } else if (value == TempModes.hot) { + return 'hot'; + } else if (value == TempModes.wind) { + return 'wind'; + } else { + return 'cold'; + } + } + + void _setAllAcsTempsAndSwitches() { + allAcsOn = true; + allTempSame = true; if (deviceStatusList.isNotEmpty) { int temp = deviceStatusList[0].tempSet; deviceStatusList.firstWhere((element) { @@ -99,195 +303,71 @@ class ACsBloc extends Bloc { } } - void _changeAcSwitch(AcSwitch event, Emitter emit) async { - emit(AcChangeLoading(acStatusModel: deviceStatus)); - - final acSwitchValue = !event.acSwitch; - try { - final response = await DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: allAcsPage ? event.deviceId : acId, code: 'switch', value: acSwitchValue), - allAcsPage ? event.deviceId : acId); - - if (response['success'] ?? false) { - deviceStatus.acSwitch = acSwitchValue; - } - } catch (_) {} - if (allAcsPage) { - await Future.delayed(const Duration(seconds: 1)); - add(const AcsInitial(allAcs: true)); - } else { - emit(AcModifyingState(acStatusModel: deviceStatus)); + _runDeBouncerForAllAcs({required String code, required dynamic value}) { + if (_timer != null) { + _timer!.cancel(); } - } - - void _changeAllAcSwitch(ChangeAllSwitch event, Emitter emit) async { - emit(AcsLoadingState()); - try { + _timer = Timer(const Duration(seconds: 1), () async { if (deviceStatusList.length == devicesList.length) { for (int i = 0; i < deviceStatusList.length; i++) { - await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: devicesList[i].uuid, code: 'switch', value: event.value), - devicesList[i].uuid ?? ''); + try { + await DevicesAPI.controlDevice( + DeviceControlModel(deviceId: devicesList[i].uuid, code: code, value: value), + devicesList[i].uuid ?? ''); + } catch (_) { + await Future.delayed(const Duration(milliseconds: 500)); + add(const AcsInitial(allAcs: true)); + } } } - } catch (_) {} - await Future.delayed(const Duration(seconds: 1)); - add(const AcsInitial(allAcs: true)); + }); } - void _increaseAllTemp(IncreaseAllTemp event, Emitter emit) async { - emit(AcsLoadingState()); - try { - double tempValue = event.value + 0.5; - int value = (tempValue * 10).toInt(); - if (deviceStatusList.length == devicesList.length) { - for (int i = 0; i < deviceStatusList.length; i++) { - await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: devicesList[i].uuid, code: 'temp_set', value: value), - devicesList[i].uuid ?? ''); + _runDeBouncerForOneDevice({ + required String deviceId, + required String code, + required dynamic value, + }) { + if (_timer != null) { + _timer!.cancel(); + } + _timer = Timer(const Duration(seconds: 1), () async { + try { + final response = await DevicesAPI.controlDevice( + DeviceControlModel(deviceId: allAcsPage ? deviceId : acId, code: code, value: value), + allAcsPage ? deviceId : acId); + + if (!response['success']) { + add(AcsInitial(allAcs: allAcsPage)); } + } catch (_) { + await Future.delayed(const Duration(milliseconds: 500)); + add(AcsInitial(allAcs: allAcsPage)); } - } catch (_) {} - await Future.delayed(const Duration(seconds: 1)); - add(const AcsInitial(allAcs: true)); + }); } - void _decreaseAllTemp(DecreaseAllTemp event, Emitter emit) async { - emit(AcsLoadingState()); - try { - double tempValue = event.value - 0.5; - int value = (tempValue * 10).toInt(); - if (deviceStatusList.length == devicesList.length) { - for (int i = 0; i < deviceStatusList.length; i++) { - await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: devicesList[i].uuid, code: 'temp_set', value: value), - devicesList[i].uuid ?? ''); - } - } - } catch (_) {} - await Future.delayed(const Duration(seconds: 1)); - add(const AcsInitial(allAcs: true)); - } - - void _changeLockValue(ChangeLock event, Emitter emit) async { - emit(AcChangeLoading(acStatusModel: deviceStatus)); - - final lockValue = !event.lockBool; - try { - final response = await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: acId, code: 'child_lock', value: lockValue), acId); - - if (response['success'] ?? false) { - deviceStatus.childLock = lockValue; - } - } catch (_) {} - emit(AcModifyingState(acStatusModel: deviceStatus)); - } - - void _increaseCoolTo(IncreaseCoolToTemp event, Emitter emit) async { - emit(AcChangeLoading(acStatusModel: deviceStatus)); - double tempValue = event.value + 0.5; - int value = (tempValue * 10).toInt(); - try { - final response = await DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: allAcsPage ? event.deviceId : acId, code: 'temp_set', value: value), - allAcsPage ? event.deviceId : acId); - - if (response['success'] ?? false) { - deviceStatus.tempSet = value; - } - } catch (_) {} - if (allAcsPage) { - await Future.delayed(const Duration(seconds: 1)); - add(const AcsInitial(allAcs: true)); + bool _checkTemperatureValue(double value, Emitter emit) { + if (value >= 20 && value <= 30) { + return true; } else { - emit(AcModifyingState(acStatusModel: deviceStatus)); + emit(const AcsFailedState(errorMessage: 'The temperature must be between 20 and 30')); + emit(GetAllAcsStatusState( + allAcsStatues: deviceStatusList, + allAcs: devicesList, + allOn: allAcsOn, + allTempSame: allTempSame, + temp: globalTemp)); + return false; } } - void _decreaseCoolTo(DecreaseCoolToTemp event, Emitter emit) async { - emit(AcChangeLoading(acStatusModel: deviceStatus)); - - double tempValue = event.value - 0.5; - int value = (tempValue * 10).toInt(); - try { - final response = await DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: allAcsPage ? event.deviceId : acId, code: 'temp_set', value: value), - allAcsPage ? event.deviceId : acId); - - if (response['success'] ?? false) { - deviceStatus.tempSet = value; - } - } catch (_) {} - if (allAcsPage) { - await Future.delayed(const Duration(seconds: 1)); - add(const AcsInitial(allAcs: true)); - } else { - emit(AcModifyingState(acStatusModel: deviceStatus)); - } - } - - void _changeAcMode(ChangeAcMode event, Emitter emit) async { - emit(AcChangeLoading(acStatusModel: deviceStatus)); - final tempMode = tempModesMap[getNextItem(tempModesMap, event.tempModes)]!; - try { - final response = await DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: allAcsPage ? event.deviceId : acId, - code: 'mode', - value: getACModeString(tempMode)), - allAcsPage ? event.deviceId : acId); - - if (response['success'] ?? false) { - deviceStatus.modeString = getACModeString(tempMode); - deviceStatus.acMode = AcStatusModel.getACMode(getACModeString(tempMode)); - } - } catch (_) {} - if (allAcsPage) { - await Future.delayed(const Duration(seconds: 1)); - add(const AcsInitial(allAcs: true)); - } else { - emit(AcModifyingState(acStatusModel: deviceStatus)); - } - } - - void _changeFanSpeed(ChangeFanSpeed event, Emitter emit) async { - emit(AcChangeLoading(acStatusModel: deviceStatus)); - - final fanSpeed = event.fanSpeeds; - final response = await DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: allAcsPage ? event.deviceId : acId, - code: 'level', - value: getNextFanSpeedKey(fanSpeed)), - allAcsPage ? event.deviceId : acId); - - try { - if (response['success'] ?? false) { - deviceStatus.fanSpeedsString = getNextFanSpeedKey(fanSpeed); - deviceStatus.acFanSpeed = AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed)); - } - } catch (_) {} - if (allAcsPage) { - await Future.delayed(const Duration(seconds: 1)); - add(const AcsInitial(allAcs: true)); - } else { - emit(AcModifyingState(acStatusModel: deviceStatus)); - } - } - - String getACModeString(TempModes value) { - if (value == TempModes.cold) { - return 'cold'; - } else if (value == TempModes.hot) { - return 'hot'; - } else if (value == TempModes.wind) { - return 'wind'; - } else { - return 'cold'; - } + _emitAcsStatus(Emitter emit) { + emit(GetAllAcsStatusState( + allAcsStatues: deviceStatusList, + allAcs: devicesList, + allOn: allAcsOn, + allTempSame: allTempSame, + temp: globalTemp)); } } diff --git a/lib/features/devices/bloc/acs_bloc/acs_event.dart b/lib/features/devices/bloc/acs_bloc/acs_event.dart index 806e878..966f69b 100644 --- a/lib/features/devices/bloc/acs_bloc/acs_event.dart +++ b/lib/features/devices/bloc/acs_bloc/acs_event.dart @@ -13,10 +13,11 @@ class AcsLoading extends AcsEvent {} class AcSwitch extends AcsEvent { final bool acSwitch; final String deviceId; - const AcSwitch({required this.acSwitch, this.deviceId = ''}); + final String productId; + const AcSwitch({required this.acSwitch, this.deviceId = '', this.productId = ''}); @override - List get props => [acSwitch, deviceId]; + List get props => [acSwitch, deviceId, productId]; } class AcsInitial extends AcsEvent { @@ -31,7 +32,8 @@ class ACsChangeStatus extends AcsEvent {} class IncreaseCoolToTemp extends AcsEvent { final double value; final String deviceId; - const IncreaseCoolToTemp({required this.value, this.deviceId = ''}); + final String productId; + const IncreaseCoolToTemp({required this.value, this.deviceId = '', this.productId = ''}); @override List get props => [value, deviceId]; @@ -40,7 +42,9 @@ class IncreaseCoolToTemp extends AcsEvent { class DecreaseCoolToTemp extends AcsEvent { final double value; final String deviceId; - const DecreaseCoolToTemp({required this.value, this.deviceId = ''}); + final String productId; + + const DecreaseCoolToTemp({required this.value, this.deviceId = '', this.productId = ''}); @override List get props => [value, deviceId]; @@ -49,19 +53,22 @@ class DecreaseCoolToTemp extends AcsEvent { class ChangeAcMode extends AcsEvent { final TempModes tempModes; final String deviceId; - const ChangeAcMode({required this.tempModes, this.deviceId = ''}); + final String productId; + const ChangeAcMode({required this.tempModes, this.deviceId = '', this.productId = ''}); @override - List get props => [tempModes, deviceId]; + List get props => [tempModes, deviceId, productId]; } class ChangeFanSpeed extends AcsEvent { final FanSpeeds fanSpeeds; final String deviceId; - const ChangeFanSpeed({required this.fanSpeeds, this.deviceId = ''}); + final String productId; + + const ChangeFanSpeed({required this.fanSpeeds, this.deviceId = '', this.productId = ''}); @override - List get props => [fanSpeeds, deviceId]; + List get props => [fanSpeeds, deviceId, productId]; } class ChangeLock extends AcsEvent { diff --git a/lib/features/devices/bloc/acs_bloc/acs_state.dart b/lib/features/devices/bloc/acs_bloc/acs_state.dart index fe3d8e5..231da9a 100644 --- a/lib/features/devices/bloc/acs_bloc/acs_state.dart +++ b/lib/features/devices/bloc/acs_bloc/acs_state.dart @@ -56,10 +56,10 @@ class GetAllAcsStatusState extends AcsState { } class AcsFailedState extends AcsState { - final String error; + final String errorMessage; - const AcsFailedState({required this.error}); + const AcsFailedState({required this.errorMessage}); @override - List get props => [error]; + List get props => [errorMessage]; } diff --git a/lib/features/devices/model/ac_model.dart b/lib/features/devices/model/ac_model.dart index 0106ad1..9f9e06f 100644 --- a/lib/features/devices/model/ac_model.dart +++ b/lib/features/devices/model/ac_model.dart @@ -2,6 +2,7 @@ import 'package:syncrow_app/features/devices/model/status_model.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; class AcStatusModel { + String uuid; bool acSwitch; String modeString; int tempSet; @@ -12,7 +13,8 @@ class AcStatusModel { late FanSpeeds acFanSpeed; AcStatusModel( - {required this.acSwitch, + {required this.uuid, + required this.acSwitch, required this.modeString, required this.tempSet, required this.currentTemp, @@ -22,7 +24,7 @@ class AcStatusModel { acFanSpeed = getFanSpeed(fanSpeedsString); } - factory AcStatusModel.fromJson(List jsonList) { + factory AcStatusModel.fromJson(String id, List jsonList) { late bool _acSwitch; late String _mode; late int _tempSet; @@ -45,6 +47,7 @@ class AcStatusModel { } } return AcStatusModel( + uuid: id, acSwitch: _acSwitch, modeString: _mode, tempSet: _tempSet, diff --git a/lib/features/devices/model/device_model.dart b/lib/features/devices/model/device_model.dart index 24cd95e..4a822be 100644 --- a/lib/features/devices/model/device_model.dart +++ b/lib/features/devices/model/device_model.dart @@ -17,12 +17,13 @@ class DeviceModel { String? timeZone; int? updateTime; String? uuid; + String? productUuid; DeviceType? productType; bool isSelected = false; late List functions; DeviceModel( {this.activeTime, - // this.id, + this.productUuid, this.localKey, this.model, this.name, @@ -60,27 +61,26 @@ class DeviceModel { tempIcon = Assets.assetsIconsLogo; } return DeviceModel( - icon: tempIcon, - activeTime: json['activeTime'], - // id: json['id'], - localKey: json['localKey'], - model: json['model'], - name: json['name'], - isOnline: json['online'], - productName: json['productName'], - timeZone: json['timeZone'], - updateTime: json['updateTime'], - uuid: json['uuid'], - productType: type, - type: json['productType'], - status: [], - ); + icon: tempIcon, + activeTime: json['activeTime'], + // id: json['id'], + localKey: json['localKey'], + model: json['model'], + name: json['name'], + isOnline: json['online'], + productName: json['productName'], + timeZone: json['timeZone'], + updateTime: json['updateTime'], + uuid: json['uuid'], + productType: type, + type: json['productType'], + status: [], + productUuid: json['productUuid']); } Map toJson() { return { 'activeTime': activeTime, - // 'id': id, 'localKey': localKey, 'model': model, 'name': name, diff --git a/lib/features/devices/view/widgets/ACs/ac_interface.dart b/lib/features/devices/view/widgets/ACs/ac_interface.dart index 852c3e6..02dee8d 100644 --- a/lib/features/devices/view/widgets/ACs/ac_interface.dart +++ b/lib/features/devices/view/widgets/ACs/ac_interface.dart @@ -11,6 +11,7 @@ import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface_temp_ import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/helpers/snack_bar.dart'; class AcInterface extends StatelessWidget { const AcInterface({super.key, required this.ac}); @@ -22,15 +23,12 @@ class AcInterface extends StatelessWidget { return BlocConsumer( listener: (context, state) { if (state is AcsFailedState) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(state.error), - ), - ); + CustomSnackBar.displaySnackBar(state.errorMessage); } }, builder: (context, state) { AcStatusModel statusModel = AcStatusModel( + uuid: ac.uuid ?? '', acSwitch: true, modeString: 'hot', tempSet: 300, diff --git a/lib/features/devices/view/widgets/ACs/ac_mode_control_unit.dart b/lib/features/devices/view/widgets/ACs/ac_mode_control_unit.dart index 96698bc..24f1737 100644 --- a/lib/features/devices/view/widgets/ACs/ac_mode_control_unit.dart +++ b/lib/features/devices/view/widgets/ACs/ac_mode_control_unit.dart @@ -9,14 +9,12 @@ import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; class ACModeControlUnit extends StatelessWidget { - const ACModeControlUnit({ - super.key, - required this.acStatus, - required this.deviceId, - }); + const ACModeControlUnit( + {super.key, required this.acStatus, required this.deviceId, this.productId = ''}); final AcStatusModel acStatus; final String deviceId; + final String? productId; @override Widget build(BuildContext context) { @@ -28,8 +26,10 @@ class ACModeControlUnit extends StatelessWidget { child: GestureDetector( onTap: () { if (state is! AcChangeLoading && state is! AcsLoadingState) { - BlocProvider.of(context) - .add(ChangeFanSpeed(fanSpeeds: acStatus.acFanSpeed, deviceId: deviceId)); + BlocProvider.of(context).add(ChangeFanSpeed( + fanSpeeds: acStatus.acFanSpeed, + deviceId: deviceId, + productId: productId ?? '')); } // else if (state is AcModifyingState) { // BlocProvider.of(context) @@ -54,8 +54,10 @@ class ACModeControlUnit extends StatelessWidget { // .add(ChangeAcMode(tempModes: state.acStatusModel.acMode)); // } if (state is! AcChangeLoading && state is! AcsLoadingState) { - BlocProvider.of(context) - .add(ChangeAcMode(tempModes: acStatus.acMode, deviceId: deviceId)); + BlocProvider.of(context).add(ChangeAcMode( + tempModes: acStatus.acMode, + deviceId: deviceId, + productId: productId ?? '')); } }, child: DefaultContainer( diff --git a/lib/features/devices/view/widgets/ACs/ac_temp_widget.dart b/lib/features/devices/view/widgets/ACs/ac_temp_widget.dart index 3368898..d56ba22 100644 --- a/lib/features/devices/view/widgets/ACs/ac_temp_widget.dart +++ b/lib/features/devices/view/widgets/ACs/ac_temp_widget.dart @@ -35,10 +35,10 @@ class ACTempWidget extends StatelessWidget { child: InkWell( onTap: () { double tempC = temp / 10; - if (tempC > 20) { - BlocProvider.of(context) - .add(DecreaseCoolToTemp(value: tempC, deviceId: deviceModel.uuid ?? '')); - } + BlocProvider.of(context).add(DecreaseCoolToTemp( + value: tempC, + deviceId: deviceModel.uuid ?? '', + productId: deviceModel.productUuid ?? '')); }, child: SvgPicture.asset( Assets.assetsIconsMinus, @@ -57,10 +57,10 @@ class ACTempWidget extends StatelessWidget { child: InkWell( onTap: () { double tempC = temp / 10; - if (tempC < 30) { - BlocProvider.of(context) - .add(IncreaseCoolToTemp(value: tempC, deviceId: deviceModel.uuid ?? '')); - } + BlocProvider.of(context).add(IncreaseCoolToTemp( + value: tempC, + deviceId: deviceModel.uuid ?? '', + productId: deviceModel.productUuid ?? '')); }, child: SvgPicture.asset( Assets.assetsIconsPlus, diff --git a/lib/features/devices/view/widgets/ACs/acs_list.dart b/lib/features/devices/view/widgets/ACs/acs_list.dart index fd35cb4..e58f679 100644 --- a/lib/features/devices/view/widgets/ACs/acs_list.dart +++ b/lib/features/devices/view/widgets/ACs/acs_list.dart @@ -9,9 +9,9 @@ import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_mode_control_un import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_temp_widget.dart'; import 'package:syncrow_app/features/devices/view/widgets/ACs/universal_ac_temp.dart'; import 'package:syncrow_app/features/devices/view/widgets/universal_switch.dart'; -import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/utils/helpers/snack_bar.dart'; class ACsList extends StatelessWidget { const ACsList({ @@ -20,7 +20,12 @@ class ACsList extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( + return BlocConsumer( + listener: (context, state) { + if (state is AcsFailedState) { + CustomSnackBar.displaySnackBar(state.errorMessage); + } + }, builder: (context, state) { List devicesStatuesList = []; List devicesList = []; @@ -35,74 +40,78 @@ class ACsList extends StatelessWidget { temperature = state.temp; } return SingleChildScrollView( - child: state is AcChangeLoading || state is AcsLoadingState - ? const Center( - child: - DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()), - ) - : Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - // universal AC controller - const SizedBox(height: 10), - const BodySmall(text: "All ACs"), - const SizedBox(height: 5), - UniversalSwitch( - allOn: allOn, - ), - const SizedBox(height: 10), - UniversalACTemp( - allTempSame: allTempSame, - temp: temperature, - ), - const SizedBox(height: 10), + child: + // state is AcChangeLoading || state is AcsLoadingState + // ? const Center( + // child: + // DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()), + // ) + // : + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // universal AC controller + const SizedBox(height: 10), + const BodySmall(text: "All ACs"), + const SizedBox(height: 5), + UniversalSwitch( + allOn: allOn, + ), + const SizedBox(height: 10), + UniversalACTemp( + allTempSame: allTempSame, + temp: temperature, + ), + const SizedBox(height: 10), - // other ACs controls - ListView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - itemCount: devicesList.length, - itemBuilder: (context, index) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 10, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - BodySmall(text: devicesList[index].name ?? ''), - ], - ), - const SizedBox(height: 5), - DevicesDefaultSwitch( - switchValue: devicesStatuesList[index].acSwitch, - action: () { - BlocProvider.of(context).add(AcSwitch( - acSwitch: devicesStatuesList[index].acSwitch, - deviceId: devicesList[index].uuid ?? '')); - }, - ), - const SizedBox(height: 10), - ACTempWidget( - deviceModel: devicesList[index], - temp: devicesStatuesList[index].tempSet, - ), - const SizedBox(height: 10), - ACModeControlUnit( - acStatus: devicesStatuesList[index], + // other ACs controls + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + padding: const EdgeInsets.all(0), + itemCount: devicesList.length, + itemBuilder: (context, index) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 10, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + BodySmall(text: devicesList[index].name ?? ''), + ], + ), + const SizedBox(height: 5), + DevicesDefaultSwitch( + switchValue: devicesStatuesList[index].acSwitch, + action: () { + BlocProvider.of(context).add(AcSwitch( + acSwitch: devicesStatuesList[index].acSwitch, deviceId: devicesList[index].uuid ?? '', - ), - const SizedBox(height: 10), - ], - ); - }, - ), - ], - ), + productId: devicesList[index].productUuid ?? '')); + }, + ), + const SizedBox(height: 10), + ACTempWidget( + deviceModel: devicesList[index], + temp: devicesStatuesList[index].tempSet, + ), + const SizedBox(height: 10), + ACModeControlUnit( + acStatus: devicesStatuesList[index], + deviceId: devicesList[index].uuid ?? '', + productId: devicesList[index].productUuid ?? '', + ), + const SizedBox(height: 10), + ], + ); + }, + ), + ], + ), ); }, ); diff --git a/lib/features/devices/view/widgets/ACs/universal_ac_temp.dart b/lib/features/devices/view/widgets/ACs/universal_ac_temp.dart index 5a6e735..37779b6 100644 --- a/lib/features/devices/view/widgets/ACs/universal_ac_temp.dart +++ b/lib/features/devices/view/widgets/ACs/universal_ac_temp.dart @@ -29,9 +29,7 @@ class UniversalACTemp extends StatelessWidget { child: InkWell( onTap: () { double temperature = temp / 10; - if (temperature < 30) { - BlocProvider.of(context).add(DecreaseAllTemp(value: temperature)); - } + BlocProvider.of(context).add(DecreaseAllTemp(value: temperature)); }, child: SvgPicture.asset( Assets.assetsIconsMinus, @@ -50,9 +48,7 @@ class UniversalACTemp extends StatelessWidget { child: InkWell( onTap: () { double temperature = temp / 10; - if (temperature > 20) { - BlocProvider.of(context).add(IncreaseAllTemp(value: temperature)); - } + BlocProvider.of(context).add(IncreaseAllTemp(value: temperature)); }, child: SvgPicture.asset( Assets.assetsIconsPlus,