diff --git a/lib/features/devices/bloc/devices_cubit.dart b/lib/features/devices/bloc/devices_cubit.dart index db7794b..6449d93 100644 --- a/lib/features/devices/bloc/devices_cubit.dart +++ b/lib/features/devices/bloc/devices_cubit.dart @@ -23,7 +23,7 @@ import 'package:syncrow_app/utils/resource_manager/constants.dart'; part 'devices_state.dart'; class DevicesCubit extends Cubit { - DevicesCubit() : super(DevicesInitial()) { + DevicesCubit._() : super(DevicesInitial()) { if (HomeCubit.getInstance().selectedSpace != null) { fetchGroups(HomeCubit.getInstance().selectedSpace!.id!); for (var room in HomeCubit.getInstance().selectedSpace!.rooms!) { @@ -33,16 +33,19 @@ class DevicesCubit extends Cubit { } bool _isClosed = false; - // static DevicesCubit? _instance; - // static DevicesCubit.get(context) { - // // If an instance already exists, return it - // _instance ??= DevicesCubit._(); - // return _instance!; - // } + static DevicesCubit? _instance; + static DevicesCubit getInstance() { + // If an instance already exists, return it + _instance ??= DevicesCubit._(); + return _instance!; + } + + DeviceModel? selectedDevice; @override Future close() { _isClosed = true; + _instance = null; return super.close(); } @@ -246,11 +249,28 @@ class DevicesCubit extends Cubit { emitSafe(DevicesCategoryChanged()); } - deviceControl(DeviceControlModel control) async { - emitSafe(DeviceControlLoading()); +///////////////////////// API CALLS ////////////////////////// + deviceControl(DeviceControlModel control, String deviceId) async { + emitSafe(DeviceControlLoading( + code: control.code, + )); try { - await DevicesAPI.controlDevice(control); - emitSafe(DeviceControlSuccess()); + await DevicesAPI.controlDevice(control).then((value) { + emitSafe(DeviceControlSuccess( + code: control.code, + )); + if (value['result'] ?? false) { + Future.delayed(const Duration(milliseconds: 400), () { + getDevicesStatues( + deviceId, + HomeCubit.getInstance().selectedSpace!.rooms!.indexOf( + HomeCubit.getInstance().selectedRoom!, + ), + code: control.code, + ); + }); + } + }); } on DioException catch (e) { emitSafe(DeviceControlError(ServerFailure.fromDioError(e).errMessage)); } @@ -297,11 +317,11 @@ class DevicesCubit extends Cubit { } } - getDevicesStatues(String deviceId, int roomIndex) async { + getDevicesStatues(String deviceId, int roomIndex, {String? code}) async { if (_isClosed) return; try { - emitSafe(GetDeviceStatusLoading()); + emitSafe(GetDeviceStatusLoading(code: code)); int deviceIndex = HomeCubit.getInstance() .selectedSpace! .rooms![roomIndex] @@ -310,7 +330,8 @@ class DevicesCubit extends Cubit { List statuses = []; var response = await DevicesAPI.getDeviceStatus(deviceId); - print('response : $response'); + // if (response['result']['status'].length > 4) + // print('response : ${response['result']['status'][4]}'); for (var status in response['result']['status']) { statuses.add(StatusModel.fromJson(status)); @@ -321,7 +342,7 @@ class DevicesCubit extends Cubit { .rooms![roomIndex] .devices![deviceIndex] .status = statuses; - emitSafe(GetDeviceStatusSuccess()); + emitSafe(GetDeviceStatusSuccess(code: code)); } on DioException catch (error) { emitSafe( GetDeviceStatusError(ServerFailure.fromDioError(error).errMessage), diff --git a/lib/features/devices/bloc/devices_state.dart b/lib/features/devices/bloc/devices_state.dart index 3375450..4f89268 100644 --- a/lib/features/devices/bloc/devices_state.dart +++ b/lib/features/devices/bloc/devices_state.dart @@ -15,9 +15,17 @@ class ChangeIndex extends DevicesState {} // Devices -class GetDeviceStatusLoading extends DevicesState {} +class GetDeviceStatusLoading extends DevicesState { + final String? code; -class GetDeviceStatusSuccess extends DevicesState {} + GetDeviceStatusLoading({this.code}); +} + +class GetDeviceStatusSuccess extends DevicesState { + final String? code; + + GetDeviceStatusSuccess({this.code}); +} class GetDeviceStatusError extends DevicesState { final String errorMsg; @@ -44,9 +52,17 @@ class DeviceSwitchChanged extends DevicesState {} class DeviceSelected extends DevicesState {} // Device Control -class DeviceControlLoading extends DevicesState {} +class DeviceControlLoading extends DevicesState { + final String? code; -class DeviceControlSuccess extends DevicesState {} + DeviceControlLoading({this.code}); +} + +class DeviceControlSuccess extends DevicesState { + final String? code; + + DeviceControlSuccess({this.code}); +} class DeviceControlError extends DevicesState { final String errorMsg; diff --git a/lib/features/devices/model/device_control_model.dart b/lib/features/devices/model/device_control_model.dart index 8f9edf7..58a6476 100644 --- a/lib/features/devices/model/device_control_model.dart +++ b/lib/features/devices/model/device_control_model.dart @@ -1,7 +1,7 @@ class DeviceControlModel { String? deviceId; String? code; - bool? value; + dynamic value; DeviceControlModel({ required this.deviceId, diff --git a/lib/features/devices/view/widgets/ACs/ac_interface.dart b/lib/features/devices/view/widgets/ACs/ac_interface.dart index 0bf1fb1..c0ac062 100644 --- a/lib/features/devices/view/widgets/ACs/ac_interface.dart +++ b/lib/features/devices/view/widgets/ACs/ac_interface.dart @@ -24,65 +24,78 @@ class AcInterface extends StatelessWidget { statusBarIconBrightness: Brightness.light, ), child: SafeArea( - child: Scaffold( - backgroundColor: ColorsManager.backgroundColor, - extendBodyBehindAppBar: true, - extendBody: true, - appBar: AppBar( - backgroundColor: Colors.transparent, - centerTitle: true, - title: BodyLarge( - text: deviceModel.name ?? "", - fontColor: ColorsManager.primaryColor, - fontWeight: FontsManager.bold, - ), - ), - body: Container( - width: MediaQuery.sizeOf(context).width, - height: MediaQuery.sizeOf(context).height, - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage( - Assets.imagesBackground, + child: BlocConsumer( + listener: (context, state) { + if (state is DeviceControlError) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(state.errorMsg), ), - fit: BoxFit.cover, - opacity: 0.4, - ), - ), - child: Padding( - padding: EdgeInsets.only( - top: Constants.appBarHeight, - left: Constants.defaultPadding, - right: Constants.defaultPadding, - ), - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - ConstrainedBox( - constraints: const BoxConstraints( - maxHeight: 380, - ), - child: AcInterfaceTempUnit( - deviceModel: deviceModel, - ), - ), - const SizedBox( - height: 10, - ), - ConstrainedBox( - constraints: const BoxConstraints( - maxHeight: 120, - ), - child: AcInterfaceControls( - deviceModel: deviceModel, - ), - ), - ], + ); + } + }, + builder: (context, state) { + return Scaffold( + backgroundColor: ColorsManager.backgroundColor, + extendBodyBehindAppBar: true, + extendBody: true, + appBar: AppBar( + backgroundColor: Colors.transparent, + centerTitle: true, + title: BodyLarge( + text: deviceModel.name ?? "", + fontColor: ColorsManager.primaryColor, + fontWeight: FontsManager.bold, ), ), - ), - ), + body: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage( + Assets.imagesBackground, + ), + fit: BoxFit.cover, + opacity: 0.4, + ), + ), + child: Padding( + padding: EdgeInsets.only( + top: Constants.appBarHeight, + left: Constants.defaultPadding, + right: Constants.defaultPadding, + ), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 380, + ), + child: AcInterfaceTempUnit( + deviceModel: deviceModel, + ), + ), + const SizedBox( + height: 10, + ), + ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 120, + ), + child: AcInterfaceControls( + deviceModel: deviceModel, + ), + ), + ], + ), + ), + ), + ), + ); + }, ), ), ); 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 b82e685..1260eec 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 @@ -1,79 +1,96 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_app/features/devices/bloc/devices_cubit.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/shared_widgets/default_container.dart'; - -import '../../../../../generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/constants.dart'; class ACModeControlUnit extends StatefulWidget { const ACModeControlUnit({ super.key, - required this.model, + required this.acDevice, }); - final DeviceModel model; + final DeviceModel acDevice; @override State createState() => _ACModeControlUnitState(); } class _ACModeControlUnitState extends State { - Map fanSpeedsMap = { - 'auto': Assets.iconsFan0, - 'iconsFan1': Assets.iconsFan1, - 'iconsFan2': Assets.iconsFan2, - 'iconsFan3': Assets.iconsFan3, - }; - - Map tempModesMap = { - 'sunny': Assets.iconsSunnyMode, - 'cold': Assets.iconsColdMode, - 'windy': Assets.iconsWindyMode, - }; - @override Widget build(BuildContext context) { - //TODO Move the fanSpeeds and tempModes to the Cubit - return Row( - children: [ - Flexible( - child: InkWell( - onTap: () { - setState(() { - // widget.model.fanSpeed = - // widget.model.fanSpeed == 3 ? 0 : widget.model.fanSpeed + 1; - }); - }, - child: DefaultContainer( - height: 55, - child: Center( - child: SvgPicture.asset(fanSpeedsMap[widget.model.status - .firstWhere((element) => element.code == 'level') - .value]!), + return BlocBuilder( + builder: (context, state) { + FanSpeeds fanSpeed = fanSpeedsMap[widget.acDevice.status + .firstWhere((element) => element.code == 'level') + .value]!; + TempModes tempMode = tempModesMap[widget.acDevice.status + .firstWhere((element) => element.code == 'mode') + .value]!; + return Row( + children: [ + Flexible( + child: InkWell( + onTap: () { + // print( + // '\n\ncurrentFanSpeed:$fanSpeed \nchanged to:\t${fanSpeedsMap[getNextFanSpeedKey(fanSpeed)]!}\nKey:\t\t\"${reversedFanSpeedsMap[fanSpeedsMap[getNextFanSpeedKey(fanSpeed)]!]!}\"'); + + fanSpeed = fanSpeedsMap[getNextFanSpeedKey(fanSpeed)]!; + + DevicesCubit.getInstance().deviceControl( + DeviceControlModel( + deviceId: widget.acDevice.id, + code: 'level', + value: reversedFanSpeedsMap[fanSpeed]!), + widget.acDevice.id!); + }, + child: DefaultContainer( + height: 55, + child: Center( + child: state is GetDeviceStatusLoading && + state.code == 'level' || + state is DeviceControlSuccess && + state.code == 'level' || + state is DeviceControlLoading && + state.code == 'level' + ? const CircularProgressIndicator() + : SvgPicture.asset(fanSpeedsIconMap[fanSpeed]!)), + ), ), ), - ), - ), - const SizedBox(width: 10), - Flexible( - child: InkWell( - onTap: () { - setState(() { - // widget.model.tempMode = - // widget.model.tempMode == 2 ? 0 : widget.model.tempMode + 1; - }); - }, - child: DefaultContainer( - height: 55, - child: Center( - child: SvgPicture.asset(tempModesMap[widget.model.status - .firstWhere((element) => element.code == 'mode') - .value]!), + const SizedBox(width: 10), + Flexible( + child: InkWell( + onTap: () { + tempMode = tempModesMap[getNextItem(tempModesMap, tempMode)]!; + DevicesCubit.getInstance().deviceControl( + DeviceControlModel( + deviceId: widget.acDevice.id, + code: 'mode', + value: reversedTempModesMap[tempMode]!), + widget.acDevice.id!); + }, + child: DefaultContainer( + height: 55, + child: Center( + child: state is GetDeviceStatusLoading && + state.code == 'mode' || + state is DeviceControlSuccess && + state.code == 'mode' || + state is DeviceControlLoading && + state.code == 'mode' + ? const CircularProgressIndicator() + : SvgPicture.asset(tempModesIconMap[tempMode]!), + ), + ), ), ), - ), - ), - ], + ], + ); + }, ); } }