diff --git a/lib/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart b/lib/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart index d749fb3..54e4730 100644 --- a/lib/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart +++ b/lib/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart @@ -149,7 +149,6 @@ class SmartDoorBloc extends Bloc { _streamSubscription = null; return super.close(); } - _doorLockUpdated(DoorLockUpdated event, Emitter emit) { unlockRequest = deviceStatus.unlockRequest; @@ -254,7 +253,10 @@ class SmartDoorBloc extends Bloc { } void _updateLock(UpdateLockEvent event, Emitter emit) async { - emit(LoadingNewSate(smartDoorModel: deviceStatus)); + // emit(LoadingNewSate(smartDoorModel: deviceStatus)); + final oldValue = deviceStatus.normalOpenSwitch; + deviceStatus = deviceStatus.copyWith(normalOpenSwitch: !oldValue); + emit(UpdateState(smartDoorModel: deviceStatus)); try { // final response = await DevicesAPI.controlDevice( // DeviceControlModel(deviceId: deviceId, code: 'normal_open_switch', value: !event.value), @@ -262,10 +264,36 @@ class SmartDoorBloc extends Bloc { final response = await DevicesAPI.openDoorLock(deviceId); - if (response) { - deviceStatus.normalOpenSwitch = !event.value; + if (!response) { + _revertValueAndEmit(deviceId, 'normal_open_switch', oldValue, emit); } - } catch (_) {} + } catch (_) { + _revertValueAndEmit(deviceId, 'normal_open_switch', oldValue, emit); + } + } + + void _revertValueAndEmit(String deviceId, String code, dynamic oldValue, + Emitter emit) { + _updateLocalValue(code, oldValue); + emit(UpdateState(smartDoorModel: deviceStatus)); + emit(const FailedState(errorMessage: 'Failed to control the device.')); + } + + void _updateLocalValue(String code, dynamic value) { + switch (code) { + case 'normal_open_switch': + if (value is bool) { + deviceStatus = deviceStatus.copyWith(normalOpenSwitch: value); + } + break; + case 'reverse_lock': + if (value is bool) { + deviceStatus = deviceStatus.copyWith(reverseLock: value); + } + break; + default: + break; + } emit(UpdateState(smartDoorModel: deviceStatus)); } diff --git a/lib/features/devices/model/smart_door_model.dart b/lib/features/devices/model/smart_door_model.dart index a215d0c..8a324c6 100644 --- a/lib/features/devices/model/smart_door_model.dart +++ b/lib/features/devices/model/smart_door_model.dart @@ -113,4 +113,44 @@ class SmartDoorModel { remoteNoDpKey: _remoteNoDpKey, normalOpenSwitch: _normalOpenSwitch); } + SmartDoorModel copyWith({ + String? uuid, + int? unlockFingerprint, + int? unlockPassword, + int? unlockTemporary, + int? unlockCard, + String? alarmLock, + int? unlockRequest, + int? residualElectricity, + bool? reverseLock, + int? unlockApp, + bool? hijack, + bool? doorbell, + String? unlockOfflinePd, + String? unlockOfflineClear, + String? unlockDoubleKit, + String? remoteNoPdSetkey, + String? remoteNoDpKey, + bool? normalOpenSwitch, + }) { + return SmartDoorModel( + unlockAlarm: alarmLock ?? unlockAlarm, + unlockFingerprint: unlockFingerprint ?? this.unlockFingerprint, + unlockPassword: unlockPassword ?? this.unlockPassword, + unlockTemporary: unlockTemporary ?? this.unlockTemporary, + unlockCard: unlockCard ?? this.unlockCard, + unlockRequest: unlockRequest ?? this.unlockRequest, + residualElectricity: residualElectricity ?? this.residualElectricity, + reverseLock: reverseLock ?? this.reverseLock, + unlockApp: unlockApp ?? this.unlockApp, + hijack: hijack ?? this.hijack, + doorbell: doorbell ?? this.doorbell, + unlockOfflinePd: unlockOfflinePd ?? this.unlockOfflinePd, + unlockOfflineClear: unlockOfflineClear ?? this.unlockOfflineClear, + unlockDoubleKit: unlockDoubleKit ?? this.unlockDoubleKit, + remoteNoPdSetkey: remoteNoPdSetkey ?? this.remoteNoPdSetkey, + remoteNoDpKey: remoteNoDpKey ?? this.remoteNoDpKey, + normalOpenSwitch: normalOpenSwitch ?? this.normalOpenSwitch, + ); + } } diff --git a/lib/features/devices/view/widgets/smart_door/door_button.dart b/lib/features/devices/view/widgets/smart_door/door_button.dart index 92e924d..6704a5c 100644 --- a/lib/features/devices/view/widgets/smart_door/door_button.dart +++ b/lib/features/devices/view/widgets/smart_door/door_button.dart @@ -9,7 +9,7 @@ import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/context_extension.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class DoorLockButton extends StatefulWidget { +class DoorLockButton extends StatelessWidget { const DoorLockButton({ super.key, required this.doorLock, @@ -18,157 +18,175 @@ class DoorLockButton extends StatefulWidget { final DeviceModel doorLock; final SmartDoorModel smartDoorModel; - @override - State createState() => _DoorLockButtonState(smartDoorModel: smartDoorModel); -} -class _DoorLockButtonState extends State with SingleTickerProviderStateMixin { - late AnimationController _animationController; - late Animation _animation; - SmartDoorModel smartDoorModel; - _DoorLockButtonState({required this.smartDoorModel}); - - @override - void initState() { - super.initState(); - - _animationController = AnimationController( - vsync: this, - value: context.read().unlockRequest > 0 ? 1 : 0, - duration: Duration(seconds: context.read().unlockRequest), - ); - if (context.read().unlockRequest > 0) { - _animationController.reverse(); - } - - _animation = Tween(begin: 0, end: 1).animate(_animationController) - ..addListener(() { - setState(() {}); - }); - } - - @override - void didUpdateWidget(DoorLockButton oldWidget) { - super.didUpdateWidget(oldWidget); - - if (_animationController.status == AnimationStatus.dismissed) { - if (context.read().unlockRequest > 0) { - _animationController.value = 1; - _animationController.duration = - Duration(seconds: context.read().unlockRequest); - _animationController.reverse(); - } - } - } - - @override - void dispose() { - _animationController.dispose(); - super.dispose(); + double _calculateProgress() { + final value = smartDoorModel.unlockRequest; + if (value <= 0 || value > 30) return 0; + return value / 30.0; } @override Widget build(BuildContext context) { - return Padding( - padding: EdgeInsets.only( - right: context.width * 0.25 / 2, - left: context.width * 0.25 / 2, - bottom: context.width * 0.2 / 2, - ), + final progress = _calculateProgress(); + final isEnabled = smartDoorModel.unlockRequest > 0; + + return SizedBox( + width: 255, + height: 255, child: InkWell( - overlayColor: - WidgetStateProperty.all(ColorsManager.primaryColorWithOpacity.withOpacity(0.1)), - borderRadius: BorderRadius.circular(999), - onTapDown: (details) { - // if (_animationController.status == AnimationStatus.dismissed) { - // _animationController.forward(); - // } else if (_animationController.status == AnimationStatus.completed) { - // _animationController.reverse(); - // } else if (_animationController.status == AnimationStatus.forward) { - // _animationController.reverse(); - // } else if (_animationController.status == AnimationStatus.reverse) { - // _animationController.forward(); - // } - if (context.read().unlockRequest > 0) { - BlocProvider.of(context) - .add(UpdateLockEvent(value: smartDoorModel.normalOpenSwitch)); - } - }, - onTapUp: (details) { - // if (_animationController.status == AnimationStatus.forward) { - // _animationController.reverse(); - // } else if (_animationController.status == AnimationStatus.reverse) { - // _animationController.forward(); - // } - }, + onTap: isEnabled + ? () { + BlocProvider.of(context).add( + UpdateLockEvent(value: !smartDoorModel.normalOpenSwitch), + ); + } + : null, child: Container( - width: context.width * 06, - height: context.width * 0.6, - margin: const EdgeInsets.all(10), - decoration: const BoxDecoration( + width: 255, + height: 255, + decoration: BoxDecoration( + color: const Color(0xFFEBECED), + shape: BoxShape.circle, boxShadow: [ BoxShadow( - color: Colors.grey, + color: Colors.grey.withOpacity(0.5), blurRadius: 18, - // offset: Offset(6, 7), blurStyle: BlurStyle.outer, ), ], - color: Color(0xFFEBECED), - borderRadius: BorderRadius.all(Radius.circular(999)), ), - child: Padding( - padding: const EdgeInsets.all(25), - child: Stack( - alignment: Alignment.center, - children: [ - Container( - margin: const EdgeInsets.all(8), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(999), - boxShadow: [ - BoxShadow( - color: Colors.white.withOpacity(0.5), - blurRadius: 30, - offset: const Offset(-5, -5), - blurStyle: BlurStyle.outer, - ), - BoxShadow( - color: Colors.black.withOpacity(0.14), - blurRadius: 25, - offset: const Offset(5, 5), - blurStyle: BlurStyle.outer, - ), - BoxShadow( - color: Colors.black.withOpacity(0.14), - blurRadius: 30, - offset: const Offset(5, 5), - blurStyle: BlurStyle.inner, - ), - ], - ), - child: Center( - child: SvgPicture.asset( - smartDoorModel.normalOpenSwitch - ? Assets.doorUnlockIcon - : Assets.assetsIconsDoorlockAssetsLockIcon, - ), + child: Stack( + alignment: Alignment.center, + children: [ + Container( + margin: const EdgeInsets.all(30), + decoration: const BoxDecoration( + color: Color(0xFFF9F9F9), + shape: BoxShape.circle, + ), + child: Center( + child: SvgPicture.asset( + smartDoorModel.normalOpenSwitch + ? Assets.doorUnlockIcon + : Assets.assetsIconsDoorlockAssetsLockIcon, + width: 60, + height: 60, ), ), - SizedBox.expand( + ), + if (progress > 0) + Container( + decoration: BoxDecoration(shape: BoxShape.circle), + height: 250, + width: 250, child: CircularProgressIndicator( - value: _animation.value, - strokeWidth: 15, + value: progress, + strokeWidth: 8, backgroundColor: Colors.transparent, - valueColor: const AlwaysStoppedAnimation(ColorsManager.primaryColor), + valueColor: const AlwaysStoppedAnimation( + ColorsManager.primaryColor), ), - ) - ], - ), + ), + ], ), ), ), ); } } + +/** + 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/all_devices/models/devices_model.dart'; +import 'package:syncrow_web/pages/device_managment/door_lock/bloc/door_lock_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/door_lock/bloc/door_lock_event.dart'; +import 'package:syncrow_web/pages/device_managment/door_lock/models/door_lock_status_model.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/constants/assets.dart'; + +class DoorLockButton extends StatelessWidget { + const DoorLockButton({ + super.key, + required this.doorLock, + required this.smartDoorModel, + }); + + final DeviceModel doorLock; + final SmartDoorModel smartDoorModel; + + double _calculateProgress() { + final value = smartDoorModel.unlockRequest; + if (value <= 0 || value > 30) return 0; + return value / 30.0; + } + + @override + Widget build(BuildContext context) { + final progress = _calculateProgress(); + final isEnabled = smartDoorModel.unlockRequest > 0; + + return SizedBox( + width: 255, + height: 255, + child: InkWell( + onTap: isEnabled + ? () { + BlocProvider.of(context).add( + UpdateLockEvent(value: !smartDoorModel.normalOpenSwitch), + ); + } + : null, + child: Container( + width: 255, + height: 255, + decoration: BoxDecoration( + color: const Color(0xFFEBECED), + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + blurRadius: 18, + blurStyle: BlurStyle.outer, + ), + ], + ), + child: Stack( + alignment: Alignment.center, + children: [ + Container( + margin: const EdgeInsets.all(30), + decoration: const BoxDecoration( + color: Color(0xFFF9F9F9), + shape: BoxShape.circle, + ), + child: Center( + child: SvgPicture.asset( + smartDoorModel.normalOpenSwitch + ? Assets.doorUnlock + : Assets.lockIcon, + width: 60, + height: 60, + ), + ), + ), + if (progress > 0) + SizedBox.expand( + child: CircularProgressIndicator( + value: progress, + strokeWidth: 8, + backgroundColor: Colors.transparent, + valueColor: const AlwaysStoppedAnimation( + ColorsManager.primaryColor), + ), + ), + ], + ), + ), + ), + ); + } +} + + */