From ce861efa3f4969aed43c46950cde76fa9d1e8313 Mon Sep 17 00:00:00 2001 From: ashrafzarkanisala Date: Sun, 8 Sep 2024 20:12:51 +0300 Subject: [PATCH] connect curtain controller --- lib/pages/common/curtain_toggle.dart | 39 +++++----- .../helper/route_controls_based_code.dart | 4 +- .../curtain/bloc/curtain_bloc.dart | 71 ++++++++++++++++--- .../curtain/bloc/curtain_event.dart | 1 - .../curtain/bloc/curtain_state.dart | 1 - .../curtain/model/curtain_model.dart | 2 +- ..._control.dart => curtain_status_view.dart} | 61 +++++++--------- 7 files changed, 110 insertions(+), 69 deletions(-) rename lib/pages/device_managment/curtain/view/{curtain_control.dart => curtain_status_view.dart} (53%) diff --git a/lib/pages/common/curtain_toggle.dart b/lib/pages/common/curtain_toggle.dart index 3c8bf5b1..371f8833 100644 --- a/lib/pages/common/curtain_toggle.dart +++ b/lib/pages/common/curtain_toggle.dart @@ -1,11 +1,9 @@ - - - import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_event.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; @@ -40,15 +38,16 @@ class CurtainToggle extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ ClipOval( - child: Container( - color: ColorsManager.whiteColors, - child: SvgPicture.asset( - Assets.curtainIcon, - width: 60, - height: 60, - fit: BoxFit.cover, - ), - )), + child: Container( + color: ColorsManager.whiteColors, + child: SvgPicture.asset( + Assets.curtainIcon, + width: 60, + height: 60, + fit: BoxFit.cover, + ), + ), + ), SizedBox( height: 20, width: 35, @@ -56,13 +55,13 @@ class CurtainToggle extends StatelessWidget { value: value, activeColor: ColorsManager.dialogBlueTitle, onChanged: (newValue) { - context.read().add( - LivingRoomControl( - deviceId: deviceId, - code: code, - value: newValue, - ), - ); + context.read().add( + CurtainControl( + deviceId: deviceId, + code: code, + value: newValue, + ), + ); }, ), ), diff --git a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart index 8c3941db..3b228192 100644 --- a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart +++ b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/device_managment/ac/view/ac_device_control.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; import 'package:syncrow_web/pages/device_managment/ceiling_sensor/view/ceiling_sensor_controls.dart'; -import 'package:syncrow_web/pages/device_managment/curtain/view/curtain_control.dart'; +import 'package:syncrow_web/pages/device_managment/curtain/view/curtain_status_view.dart'; import 'package:syncrow_web/pages/device_managment/door_lock/view/door_lock_status_view.dart'; import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_view.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_device_control.dart'; @@ -29,7 +29,7 @@ mixin RouteControlsBasedCode { device: device, ); case 'CUR': - return CurtainControl( + return CurtainStatusView( deviceId: device.uuid!, ); case 'AC': diff --git a/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart b/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart index a969b2c2..fe6dd0b8 100644 --- a/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart +++ b/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart @@ -1,7 +1,6 @@ - - import 'dart:async'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_event.dart'; import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_state.dart'; import 'package:syncrow_web/services/devices_mang_api.dart'; @@ -9,32 +8,84 @@ import 'package:syncrow_web/services/devices_mang_api.dart'; class CurtainBloc extends Bloc { late bool deviceStatus; final String deviceId; + Timer? _timer; CurtainBloc({required this.deviceId}) : super(CurtainInitial()) { on(_onFetchDeviceStatus); + on(_onCurtainControl); } FutureOr _onFetchDeviceStatus( CurtainFetchDeviceStatus event, Emitter emit) async { emit(CurtainStatusLoading()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); - deviceStatus =checkStatus(status.status[0].value) ; // Assuming this is a Map + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); + + deviceStatus = _checkStatus(status.status[0].value); + emit(CurtainStatusLoaded(deviceStatus)); } catch (e) { emit(CurtainError(e.toString())); } } - bool checkStatus(String command) { - if (command.toLowerCase() == 'open') { - return true; - } else { - return false; - } + FutureOr _onCurtainControl( + CurtainControl event, Emitter emit) async { + final oldValue = deviceStatus; + + _updateLocalValue(event.value, emit); + + emit(CurtainStatusLoaded(deviceStatus)); + + await _runDebounce( + deviceId: event.deviceId, + code: event.code, + value: event.value, + oldValue: oldValue, + emit: emit, + ); } + Future _runDebounce({ + required String deviceId, + required String code, + required bool value, + required bool oldValue, + required Emitter emit, + }) async { + if (_timer != null) { + _timer!.cancel(); + } + _timer = Timer(const Duration(seconds: 1), () async { + try { + final controlValue = value ? 'open' : 'stop'; + final response = await DevicesManagementApi() + .deviceControl(deviceId, Status(code: code, value: controlValue)); + if (!response) { + _revertValueAndEmit(deviceId, oldValue, emit); + } + } catch (e) { + _revertValueAndEmit(deviceId, oldValue, emit); + } + }); + } + void _revertValueAndEmit( + String deviceId, bool oldValue, Emitter emit) { + _updateLocalValue(oldValue, emit); + emit(CurtainStatusLoaded(deviceStatus)); + emit(const CurtainControlError('Failed to control the device.')); + } + + void _updateLocalValue(bool value, Emitter emit) { + deviceStatus = value; + emit(CurtainStatusLoaded(deviceStatus)); + } + + bool _checkStatus(String command) { + return command.toLowerCase() == 'open'; + } } diff --git a/lib/pages/device_managment/curtain/bloc/curtain_event.dart b/lib/pages/device_managment/curtain/bloc/curtain_event.dart index 386addf8..23bb2e45 100644 --- a/lib/pages/device_managment/curtain/bloc/curtain_event.dart +++ b/lib/pages/device_managment/curtain/bloc/curtain_event.dart @@ -1,6 +1,5 @@ import 'package:equatable/equatable.dart'; -import 'package:flutter/material.dart'; sealed class CurtainEvent extends Equatable { diff --git a/lib/pages/device_managment/curtain/bloc/curtain_state.dart b/lib/pages/device_managment/curtain/bloc/curtain_state.dart index 70fa154b..dfe11c2a 100644 --- a/lib/pages/device_managment/curtain/bloc/curtain_state.dart +++ b/lib/pages/device_managment/curtain/bloc/curtain_state.dart @@ -1,6 +1,5 @@ import 'package:equatable/equatable.dart'; -import 'package:syncrow_web/pages/device_managment/curtain/model/curtain_model.dart'; sealed class CurtainState extends Equatable { const CurtainState(); diff --git a/lib/pages/device_managment/curtain/model/curtain_model.dart b/lib/pages/device_managment/curtain/model/curtain_model.dart index 426f4fe5..908415d5 100644 --- a/lib/pages/device_managment/curtain/model/curtain_model.dart +++ b/lib/pages/device_managment/curtain/model/curtain_model.dart @@ -26,7 +26,7 @@ class CurtainModel { return { 'productUuid': productUuid, 'productType': productType, - 'status': status.map((s) => s!.toJson()).toList(), + 'status': status.map((s) => s.toJson()).toList(), }; } } diff --git a/lib/pages/device_managment/curtain/view/curtain_control.dart b/lib/pages/device_managment/curtain/view/curtain_status_view.dart similarity index 53% rename from lib/pages/device_managment/curtain/view/curtain_control.dart rename to lib/pages/device_managment/curtain/view/curtain_status_view.dart index c7c06681..c9af04fb 100644 --- a/lib/pages/device_managment/curtain/view/curtain_control.dart +++ b/lib/pages/device_managment/curtain/view/curtain_status_view.dart @@ -1,27 +1,21 @@ - - import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/curtain_toggle.dart'; import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_bloc.dart'; import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_event.dart'; import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_state.dart'; -import 'package:syncrow_web/pages/device_managment/curtain/model/curtain_model.dart'; -import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; -import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/living_room_model.dart'; -import 'package:syncrow_web/pages/device_managment/three_gang_switch/widgets/living_toggle_widget.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class CurtainControl extends StatelessWidget with HelperResponsiveLayout { +class CurtainStatusView extends StatelessWidget with HelperResponsiveLayout { final String deviceId; - const CurtainControl({super.key, required this.deviceId}); + const CurtainStatusView({super.key, required this.deviceId}); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - CurtainBloc(deviceId: deviceId)..add(CurtainFetchDeviceStatus(deviceId)), + create: (context) => CurtainBloc(deviceId: deviceId) + ..add(CurtainFetchDeviceStatus(deviceId)), child: BlocBuilder( builder: (context, state) { if (state is CurtainStatusLoading) { @@ -42,31 +36,30 @@ class CurtainControl extends StatelessWidget with HelperResponsiveLayout { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); - return Container( - child: GridView( - padding: const EdgeInsets.symmetric(horizontal: 50), - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: isLarge || isExtraLarge - ? 3 - : isMedium - ? 2 - : 1, - mainAxisExtent: 140, - crossAxisSpacing: 12, - mainAxisSpacing: 12, - ), - children: [ - CurtainToggle( - value: status, - code: 'Curtains', - deviceId: deviceId, - label: 'Curtains', - ), - - ], + return GridView( + padding: const EdgeInsets.symmetric(horizontal: 50), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: isLarge || isExtraLarge + ? 3 + : isMedium + ? 2 + : 1, + mainAxisExtent: 140, + crossAxisSpacing: 12, + mainAxisSpacing: 12, ), + children: [ + const SizedBox.shrink(), + CurtainToggle( + value: status, + code: 'control', + deviceId: deviceId, + label: 'Curtains', + ), + const SizedBox.shrink(), + ], ); } }