diff --git a/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart b/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart new file mode 100644 index 0000000..1dea664 --- /dev/null +++ b/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart @@ -0,0 +1,184 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_event.dart'; +import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_state.dart'; +import 'package:syncrow_app/features/devices/model/device_control_model.dart'; +import 'package:syncrow_app/features/devices/model/status_model.dart'; +import 'package:syncrow_app/services/api/devices_api.dart'; +import 'package:syncrow_app/utils/resource_manager/constants.dart'; + +class CurtainBloc extends Bloc { + double curtainWidth = 270; + double curtainOpeningSpace = 195; + double blindHeight = 310; + double blindOpeningSpace = 245; + double openPercentage = 0; + bool isMoving = false; + final String curtainId; + + CurtainBloc( + this.curtainId, + ) : super(CurtainInitial()) { + on(_fetchStatus); + on(_onOpenCurtain); + on(_onCloseCurtain); + on(_onPauseCurtain); + } + + Future _onOpenCurtain( + OpenCurtain event, + Emitter emit) async { + isMoving = true; + while (openPercentage < 100.0) { + if (state is CurtainsClosing) { + _pauseCurtain(emit); + break; + } + emit(CurtainsOpening( + curtainWidth: curtainWidth, + blindHeight: blindHeight, + openPercentage: openPercentage, + )); + if (isMoving) { + await Future.delayed(const Duration(milliseconds: 200), () async { + openPercentage += 10.0; + event.deviceType == DeviceType.Curtain + ? curtainWidth -= curtainOpeningSpace / 10 + : blindHeight -= blindOpeningSpace / 10; + if (openPercentage >= 100.0) { + _pauseCurtain(emit); + } + }); + if (openPercentage >=100.0) { + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: curtainId, + code: 'control', + value: 'close', + ), + curtainId, + ); + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: curtainId, + code: 'percent_control', + value: 100, + ), + curtainId, + ); + } + } else { + _pauseCurtain(emit); + break; + } + } + } + + Future _onCloseCurtain( + CloseCurtain event, Emitter emit) async { + isMoving = true; + while (openPercentage > 0.0) { + if (state is CurtainsOpening) { + _pauseCurtain(emit); + break; + } + emit(CurtainsClosing( + curtainWidth: curtainWidth, + blindHeight: blindHeight, + openPercentage: openPercentage, + )); + if (isMoving) { + await Future.delayed(const Duration(milliseconds: 200), () async { + openPercentage -= 10.0; + event.deviceType == DeviceType.Curtain + ? curtainWidth += curtainOpeningSpace / 10 + : blindHeight += blindOpeningSpace / 10; + if (openPercentage <= 0.0) { + _pauseCurtain(emit); + } + }); + if (openPercentage == 0.0) { + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: curtainId, + code: 'percent_control', + value: 0, + ), + curtainId, + ); + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: curtainId, + code: 'control', + value: 'open', + ), + curtainId, + ); + } + } else { + _pauseCurtain(emit); + break; + } + } + } + + Future _onPauseCurtain( + PauseCurtain event, Emitter emit) async { + _pauseCurtain(emit); + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: curtainId, + code: 'control', + value: 'stop', + ), + curtainId, + ); + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: curtainId, + code: 'percent_control', + value: openPercentage.ceil(), + ), + curtainId, + ); + } + + Future _pauseCurtain(Emitter emit) async { + isMoving = false; + emit(CurtainsPaused( + curtainWidth: curtainWidth, + blindHeight: blindHeight, + openPercentage: openPercentage, + )); + } + + + + + void _fetchStatus(InitCurtain event, Emitter emit) async { + try { + emit(CurtainLoadingState()); + // Fetch the status from the API + var response = await DevicesAPI.getDeviceStatus(curtainId); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + // Get the open percentage from the response + openPercentage = double.tryParse(statusModelList[1].value.toString())!; + // Calculate curtain width and blind height based on the open percentage + if (openPercentage != null) { + curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace; + blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace; + } + emit(CurtainsOpening( + curtainWidth: curtainWidth, + blindHeight: blindHeight, + openPercentage: openPercentage, + )); + } catch (e) { + emit(FailedState()); + return; + } + } + +} diff --git a/lib/features/devices/bloc/curtain_bloc/curtain_event.dart b/lib/features/devices/bloc/curtain_bloc/curtain_event.dart new file mode 100644 index 0000000..799946e --- /dev/null +++ b/lib/features/devices/bloc/curtain_bloc/curtain_event.dart @@ -0,0 +1,34 @@ + + + +import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/utils/resource_manager/constants.dart'; + +abstract class CurtainEvent extends Equatable { + const CurtainEvent(); + + @override + List get props => []; +} + +class OpenCurtain extends CurtainEvent { + final DeviceType deviceType; + + const OpenCurtain(this.deviceType); + + @override + List get props => [deviceType]; +} + +class CloseCurtain extends CurtainEvent { + final DeviceType deviceType; + + const CloseCurtain(this.deviceType); + + @override + List get props => [deviceType]; +} + +class InitCurtain extends CurtainEvent {} +class PauseCurtain extends CurtainEvent {} +class useCurtainEvent extends CurtainEvent {} \ No newline at end of file diff --git a/lib/features/devices/bloc/curtain_bloc/curtain_state.dart b/lib/features/devices/bloc/curtain_bloc/curtain_state.dart new file mode 100644 index 0000000..fd94ab1 --- /dev/null +++ b/lib/features/devices/bloc/curtain_bloc/curtain_state.dart @@ -0,0 +1,76 @@ +// curtain_state.dart +import 'package:equatable/equatable.dart'; + +abstract class CurtainState extends Equatable { + const CurtainState(); + + @override + List get props => []; +} + +class CurtainInitial extends CurtainState {} + +class UpdateCurtain extends CurtainState { + + final double curtainWidth; + final double blindHeight; + final double openPercentage; + + const UpdateCurtain({ + required this.curtainWidth, + required this.blindHeight, + required this.openPercentage, + }); + + @override + List get props => [curtainWidth, blindHeight, openPercentage]; +} + +class FailedState extends CurtainState {} + +class CurtainLoadingState extends CurtainState {} + +class CurtainsOpening extends CurtainState { + final double curtainWidth; + final double blindHeight; + final double openPercentage; + + const CurtainsOpening({ + required this.curtainWidth, + required this.blindHeight, + required this.openPercentage, + }); + + @override + List get props => [curtainWidth, blindHeight, openPercentage]; +} + +class CurtainsClosing extends CurtainState { + final double curtainWidth; + final double blindHeight; + final double openPercentage; + + const CurtainsClosing({ + required this.curtainWidth, + required this.blindHeight, + required this.openPercentage, + }); + + @override + List get props => [curtainWidth, blindHeight, openPercentage]; +} + +class CurtainsPaused extends CurtainState { + final double curtainWidth; + final double blindHeight; + final double openPercentage; + + const CurtainsPaused({ + required this.curtainWidth, + required this.blindHeight, + required this.openPercentage, + }); + + @override + List get props => [curtainWidth, blindHeight, openPercentage]; +} \ No newline at end of file diff --git a/lib/features/devices/bloc/devices_cubit.dart b/lib/features/devices/bloc/devices_cubit.dart index 7d64d45..48e9ca0 100644 --- a/lib/features/devices/bloc/devices_cubit.dart +++ b/lib/features/devices/bloc/devices_cubit.dart @@ -87,10 +87,10 @@ class DevicesCubit extends Cubit { return const DoorsListView(); case DeviceType.Curtain: return const CurtainListView(); - // case DeviceType.ThreeGang: - // return const ThreeGangSwitchesView(); - // case DeviceType.Gateway: - // return const GateWayView(); + // case DeviceType.ThreeGang: + // return const ThreeGangSwitchesView(); + // case DeviceType.Gateway: + // return const GateWayView(); default: return null; } @@ -308,10 +308,10 @@ class DevicesCubit extends Cubit { emitSafe(GetDevicesLoading()); int roomIndex = - HomeCubit.getInstance().selectedSpace!.rooms!.indexWhere((element) => element.id == roomId); + HomeCubit.getInstance().selectedSpace!.rooms!.indexWhere((element) => element.id == roomId); try { HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices = - await DevicesAPI.getDevicesByRoomId(roomId); + await DevicesAPI.getDevicesByRoomId(roomId); } catch (e) { emitSafe(GetDevicesError(e.toString())); return; @@ -397,87 +397,7 @@ class DevicesCubit extends Cubit { // } // } -//////////////////////////////////CURTAINS////////////////////////////////////// - double curtainWidth = 270; - double curtainOpeningSpace = 195; - double blindWindowHight = 310; - double blindOpeningSpace = 245; - double _openPercentage = 0; - bool isMoving = false; - openCurtain(DeviceType type) async { - if (state is CurtainsIsOpening) { - return; - } - - isMoving = true; - while (_openPercentage < 100.0) { - if (state is CurtainsIsClosing) { - //listen to interruption by the closing process - pauseCurtain(); - break; - } - - emit(CurtainsIsOpening()); - - if (isMoving) { - await Future.delayed(const Duration(milliseconds: 200), () { - _openPercentage += 10.0; - //25.5 is the 10% of the curtain opening space, its used to update the - // animated container of thecurtain - - type == DeviceType.Curtain - ? curtainWidth -= curtainOpeningSpace / 10 - : blindWindowHight -= blindOpeningSpace / 10; - if (_openPercentage >= 100.0) { - pauseCurtain(); - } - }); - } else { - pauseCurtain(); - break; - } - } - } - - closeCurtain(DeviceType type) async { - if (state is CurtainsIsClosing) { - return; - } - - isMoving = true; - while (_openPercentage > 0.0) { - if (state is CurtainsIsOpening) { - // interrupted by the opening process - pauseCurtain(); - break; - } - - emit(CurtainsIsClosing()); - - if (isMoving) { - await Future.delayed(const Duration(milliseconds: 200), () { - _openPercentage -= 10.0; - //25.5 is the 10% of the curtain opening space, its used to update the - type == DeviceType.Curtain - ? curtainWidth += curtainOpeningSpace / 10 - : blindWindowHight += 24.5; - - if (_openPercentage <= 0.0) { - pauseCurtain(); - } - }); - } else { - pauseCurtain(); - break; - } - } - } - - pauseCurtain() { - isMoving = false; - emit(CurtainsStopped()); - } } enum LightMode { diff --git a/lib/features/devices/view/widgets/curtains/blind_view.dart b/lib/features/devices/view/widgets/curtains/blind_view.dart deleted file mode 100644 index dc47d41..0000000 --- a/lib/features/devices/view/widgets/curtains/blind_view.dart +++ /dev/null @@ -1,163 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart'; -import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; -import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/constants.dart'; - -class BlindsView extends StatelessWidget { - const BlindsView({ - super.key, - this.blind, - }); - final DeviceModel? blind; - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => DevicesCubit.getInstance(), - child: BlocBuilder( - builder: (context, state) { - return DefaultScaffold( - title: blind?.name ?? 'Blinds', - child: Column( - children: [ - Column( - children: [ - Stack( - alignment: Alignment.topCenter, - children: [ - Container( - height: 340, - width: 365, - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage( - Assets.assetsImagesWindow, - ), - ), - ), - ), - Padding( - padding: const EdgeInsets.only(top: 15, bottom: 10), - child: AnimatedContainer( - duration: const Duration(milliseconds: 200), - curve: Curves.linear, - height: DevicesCubit.get(context).blindWindowHight, - width: 270, - child: Stack( - children: List.generate( - 25, - (index) { - double spacing = DevicesCubit.get(context) - .blindWindowHight / - 24; - double topPosition = index * spacing; - return AnimatedPositioned( - duration: const Duration(milliseconds: 200), - curve: Curves.linear, - top: topPosition, - child: SizedBox( - height: 10, - width: 270, - child: Image.asset( - Assets.assetsImagesHorizintalBlade, - fit: BoxFit.fill, - ), - ), - ); - }, - ), - ), - ), - ), - ], - ), - const SizedBox(height: 80), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - DecoratedBox( - decoration: - BoxDecoration(shape: BoxShape.circle, boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 1, - blurRadius: 5, - offset: const Offset(3, 3), - ), - ]), - child: InkWell( - overlayColor: - MaterialStateProperty.all(Colors.transparent), - onTap: () { - // DevicesCubit.get(context).setHight(false); - DevicesCubit.get(context).openCurtain( - blind?.productType! ?? DeviceType.Blind); - }, - child: Image.asset( - Assets.assetsImagesUp, - width: 60, - height: 60, - ), - ), - ), - DecoratedBox( - decoration: - BoxDecoration(shape: BoxShape.circle, boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 1, - blurRadius: 5, - offset: const Offset(3, 3), - ), - ]), - child: InkWell( - overlayColor: - MaterialStateProperty.all(Colors.transparent), - onTap: () { - DevicesCubit.get(context).pauseCurtain(); - }, - child: Image.asset( - Assets.assetsImagesPause, - width: 60, - height: 60, - ), - ), - ), - DecoratedBox( - decoration: - BoxDecoration(shape: BoxShape.circle, boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 1, - blurRadius: 5, - offset: const Offset(3, 3), - ), - ]), - child: InkWell( - overlayColor: - MaterialStateProperty.all(Colors.transparent), - onTap: () { - DevicesCubit.get(context).closeCurtain( - blind?.productType! ?? DeviceType.Blind); - }, - child: Image.asset( - Assets.assetsImagesDown, - width: 60, - height: 60, - ), - ), - ), - ], - ), - ], - ), - ], - ), - ); - }, - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/curtains/blinds_bottons.dart b/lib/features/devices/view/widgets/curtains/blinds_bottons.dart deleted file mode 100644 index c6e1886..0000000 --- a/lib/features/devices/view/widgets/curtains/blinds_bottons.dart +++ /dev/null @@ -1,83 +0,0 @@ -// import 'package:flutter/material.dart'; -// import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart'; -// import 'package:syncrow_app/generated2/assets.dart'; - -// class BlindsBottons extends StatelessWidget { -// const BlindsBottons({ -// super.key, -// }); - -// @override -// Widget build(BuildContext context) { -// return Row( -// mainAxisAlignment: MainAxisAlignment.spaceEvenly, -// children: [ -// DecoratedBox( -// decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [ -// BoxShadow( -// color: Colors.grey.withOpacity(0.5), -// spreadRadius: 1, -// blurRadius: 5, -// offset: const Offset(3, 3), -// ), -// ]), -// child: InkWell( -// overlayColor: MaterialStateProperty.all(Colors.transparent), -// onTap: () { -// // DevicesCubit.get(context).setHight(false); -// DevicesCubit.get(context).closeCurtain(); -// }, -// child: Image.asset( -// Assets.assetsImagesUp, -// width: 60, -// height: 60, -// ), -// ), -// ), -// DecoratedBox( -// decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [ -// BoxShadow( -// color: Colors.grey.withOpacity(0.5), -// spreadRadius: 1, -// blurRadius: 5, -// offset: const Offset(3, 3), -// ), -// ]), -// child: InkWell( -// overlayColor: MaterialStateProperty.all(Colors.transparent), -// onTap: () { -// // DevicesCubit.get(context).setHight(false); -// }, -// child: Image.asset( -// Assets.assetsImagesPause, -// width: 60, -// height: 60, -// ), -// ), -// ), -// DecoratedBox( -// decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [ -// BoxShadow( -// color: Colors.grey.withOpacity(0.5), -// spreadRadius: 1, -// blurRadius: 5, -// offset: const Offset(3, 3), -// ), -// ]), -// child: InkWell( -// overlayColor: MaterialStateProperty.all(Colors.transparent), -// onTap: () { -// // DevicesCubit.get(context).setHight(true); -// DevicesCubit.get(context).openCurtain(); -// }, -// child: Image.asset( -// Assets.assetsImagesDown, -// width: 60, -// height: 60, -// ), -// ), -// ), -// ], -// ); -// } -// } diff --git a/lib/features/devices/view/widgets/curtains/curtain_buttons.dart b/lib/features/devices/view/widgets/curtains/curtain_buttons.dart index 356023c..d1e0a06 100644 --- a/lib/features/devices/view/widgets/curtains/curtain_buttons.dart +++ b/lib/features/devices/view/widgets/curtains/curtain_buttons.dart @@ -1,114 +1,73 @@ -part of "curtain_view.dart"; + +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/curtain_bloc/curtain_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_event.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/generated/assets.dart'; class CurtainButtons extends StatelessWidget { const CurtainButtons({super.key, required this.curtain}); final DeviceModel curtain; + @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - Stack( - alignment: Alignment.center, - children: [ - DecoratedBox( - decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 1, - blurRadius: 5, - offset: const Offset(3, 3), - ), - ]), - child: InkWell( - overlayColor: MaterialStateProperty.all(Colors.transparent), - onTap: () { - DevicesCubit.get(context).openCurtain(curtain.productType!); - }, - child: const SizedBox.square( - dimension: 60, - ), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 5, bottom: 5), - child: InkWell( - overlayColor: MaterialStateProperty.all(Colors.transparent), - onTap: () { - DevicesCubit.get(context).openCurtain(curtain.productType!); - }, - child: SvgPicture.asset( - Assets.assetsIconsCurtainsIconOpenCurtain, - width: 110, - height: 110, - ), - ), - ) - ], + _buildButton( + onTap: () => context.read().add(OpenCurtain(curtain.productType!)), + iconPath: Assets.assetsIconsCurtainsIconOpenCurtain, ), + _buildButton( + onTap: () => context.read().add(PauseCurtain()), + iconPath: Assets.assetsImagesPause, + isSvg: false, + ), + _buildButton( + onTap: () => context.read().add(CloseCurtain(curtain.productType!)), + iconPath: Assets.assetsIconsCurtainsIconCloseCurtain, + ), + ], + ); + } + + Widget _buildButton({ + required VoidCallback onTap, + required String iconPath, + bool isSvg = true, + }) { + return Stack( + alignment: Alignment.center, + children: [ DecoratedBox( - decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 1, - blurRadius: 5, - offset: const Offset(3, 3), - ), - ]), + decoration: BoxDecoration( + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 1, + blurRadius: 5, + offset: const Offset(3, 3), + ), + ], + ), child: InkWell( overlayColor: MaterialStateProperty.all(Colors.transparent), - onTap: () { - DevicesCubit.get(context).pauseCurtain(); - }, - child: Image.asset( - Assets.assetsImagesPause, - width: 60, - height: 60, - ), + onTap: onTap, + child: const SizedBox.square(dimension: 60), ), ), - Stack( - alignment: Alignment.center, - children: [ - DecoratedBox( - decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 1, - blurRadius: 5, - offset: const Offset(3, 3), - ), - ]), - child: const SizedBox.square( - dimension: 60, - ), - // InkWell( - // overlayColor: MaterialStateProperty.all(Colors.transparent), - // onTap: () { - // DevicesCubit.get(context).closeCurtain(curtain.productType!); - // }, - // child: SvgPicture.asset( - // Assets.assetsIconsCurtainsIconCloseCurtain, - // width: 60, - // height: 60, - // ), - // ), - ), - Padding( - padding: const EdgeInsets.only(right: 5, bottom: 5), - child: InkWell( - overlayColor: MaterialStateProperty.all(Colors.transparent), - onTap: () { - DevicesCubit.get(context).closeCurtain(curtain.productType!); - }, - child: SvgPicture.asset( - Assets.assetsIconsCurtainsIconCloseCurtain, - width: 110, - height: 110, - ), - ), - ) - ], + Padding( + padding: const EdgeInsets.only(right: 5, bottom: 5), + child: InkWell( + overlayColor: MaterialStateProperty.all(Colors.transparent), + onTap: onTap, + child: isSvg + ? SvgPicture.asset(iconPath, width: 110, height: 110) + : Image.asset(iconPath, width: 60, height: 60), + ), ), ], ); diff --git a/lib/features/devices/view/widgets/curtains/curtain_view.dart b/lib/features/devices/view/widgets/curtains/curtain_view.dart index 8815cb2..153bce8 100644 --- a/lib/features/devices/view/widgets/curtains/curtain_view.dart +++ b/lib/features/devices/view/widgets/curtains/curtain_view.dart @@ -1,86 +1,99 @@ import 'package:flutter/material.dart'; -import 'package:flutter/widgets.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/bloc/curtain_bloc/curtain_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_event.dart'; +import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_buttons.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; import 'package:syncrow_app/generated/assets.dart'; -part "curtain_buttons.dart"; - class CurtainView extends StatelessWidget { const CurtainView({super.key, required this.curtain}); final DeviceModel curtain; + @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => DevicesCubit.getInstance(), - child: BlocBuilder( - builder: (context, state) => DefaultScaffold( - title: curtain.name, - child: Column( - children: [ - Stack( - alignment: Alignment.centerLeft, - children: [ - Container( - height: 340, - width: 365, - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage( - Assets.assetsImagesWindow, + create: (context) => CurtainBloc(curtain.uuid!)..add(InitCurtain()), + child: BlocBuilder( + builder: (context, state) { + double curtainWidth = 270; + double blindHeight = 310; + if (state is CurtainsOpening) { + curtainWidth = state.curtainWidth; + blindHeight = state.blindHeight; + } else if (state is CurtainsClosing) { + curtainWidth = state.curtainWidth; + blindHeight = state.blindHeight; + } else if (state is CurtainsPaused) { + curtainWidth = state.curtainWidth; + blindHeight = state.blindHeight; + } + return DefaultScaffold( + title: curtain.name, + child: Column( + children: [ + Stack( + alignment: Alignment.centerLeft, + children: [ + Container( + height: 340, + width: 365, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage( + Assets.assetsImagesWindow, + ), ), ), ), - ), - Padding( - padding: const EdgeInsets.all(40), - child: AnimatedContainer( - duration: const Duration(milliseconds: 200), - curve: Curves.linear, - height: 310, - width: DevicesCubit.getInstance().curtainWidth, - child: Stack( - children: List.generate( - 10, - (index) { - double spacing = - DevicesCubit.getInstance().curtainWidth / 9; - double leftMostPosition = index * spacing; - return AnimatedPositioned( - duration: const Duration(milliseconds: 200), - curve: Curves.linear, - left: leftMostPosition, - child: SizedBox( - height: 320, - width: 32, - child: SvgPicture.asset( - Assets.assetsIconsCurtainsIconVerticalBlade, - fit: BoxFit.fill, + Padding( + padding: const EdgeInsets.all(40), + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + curve: Curves.linear, + height: 310, + width: curtainWidth, + child: Stack( + children: List.generate( + 10, (index) { + double spacing = curtainWidth / 9; + double leftMostPosition = index * spacing; + return AnimatedPositioned( + duration: const Duration(milliseconds: 200), + curve: Curves.linear, + left: leftMostPosition, + child: SizedBox( + height: 320, + width: 32, + child: SvgPicture.asset( + Assets.assetsIconsCurtainsIconVerticalBlade, + fit: BoxFit.fill, + ), ), - ), - ); - }, + ); + }, + ), ), ), ), - ), - Positioned( + Positioned( top: 27, left: 43, child: SvgPicture.asset( - Assets.assetsIconsCurtainsIconCurtainHolder)), - ], - ), - const SizedBox(height: 80), - CurtainButtons( - curtain: curtain, - ), - ], - ), - ), + Assets.assetsIconsCurtainsIconCurtainHolder, + ), + ), + ], + ), + const SizedBox(height: 80), + CurtainButtons(curtain: curtain), + ], + ), + ); + }, ), ); } diff --git a/lib/features/devices/view/widgets/devices_view_body.dart b/lib/features/devices/view/widgets/devices_view_body.dart index 765bf2b..9ee89a6 100644 --- a/lib/features/devices/view/widgets/devices_view_body.dart +++ b/lib/features/devices/view/widgets/devices_view_body.dart @@ -66,6 +66,7 @@ class DevicesViewBody extends StatelessWidget { const SizedBox( height: 10, ), + Expanded( child: PageView( controller: HomeCubit.getInstance().devicesPageController, diff --git a/lib/features/devices/view/widgets/room_page_switch.dart b/lib/features/devices/view/widgets/room_page_switch.dart index d6efc2f..980de66 100644 --- a/lib/features/devices/view/widgets/room_page_switch.dart +++ b/lib/features/devices/view/widgets/room_page_switch.dart @@ -8,6 +8,7 @@ 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_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart'; +import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface.dart'; import 'package:syncrow_app/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart'; @@ -102,6 +103,11 @@ void showDeviceInterface(DeviceModel device, BuildContext context) { // navigateToInterface(CeilingSensorInterface(ceilingSensor: device), context); break; case DeviceType.Curtain: + Navigator.push( + context, + PageRouteBuilder( + pageBuilder: (context, animation1, animation2) => + CurtainView(curtain: device,))); break; case DeviceType.Blind: break; diff --git a/lib/main.dart b/lib/main.dart index ec2a3ea..05f1875 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,9 +7,7 @@ import 'package:syncrow_app/firebase_options.dart'; import 'package:syncrow_app/services/locator.dart'; import 'package:syncrow_app/utils/bloc_observer.dart'; import 'package:syncrow_app/utils/helpers/localization_helpers.dart'; - import 'my_app.dart'; - void main() { //to observe the state of the blocs in the output console Bloc.observer = MyBlocObserver(); diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index 5439039..f347cdd 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -32,6 +32,7 @@ class DevicesAPI { static Future> controlDevice( DeviceControlModel controlModel, String deviceId) async { try { + final response = await _httpService.post( path: ApiEndpoints.controlDevice.replaceAll('{deviceUuid}', deviceId), body: controlModel.toJson(), @@ -213,7 +214,6 @@ class DevicesAPI { "effectiveTime": effectiveTime, "invalidTime": invalidTime, }; - print('createPassword =$body'); if (scheduleList != null) { body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList(); } diff --git a/lib/utils/resource_manager/constants.dart b/lib/utils/resource_manager/constants.dart index 9e0563f..774f726 100644 --- a/lib/utils/resource_manager/constants.dart +++ b/lib/utils/resource_manager/constants.dart @@ -68,6 +68,7 @@ Map devicesTypesMap = { "DL": DeviceType.DoorLock, "WPS": DeviceType.WallSensor, "3G": DeviceType.ThreeGang, + "CUR": DeviceType.Curtain, }; Map> devicesFunctionsMap = { DeviceType.AC: [ @@ -174,6 +175,21 @@ Map> devicesFunctionsMap = { type: functionTypesMap['Integer'], values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), ], + DeviceType.Curtain: [ + FunctionModel( + code: 'control', + type: functionTypesMap['Enum'], + values: ValueModel.fromJson( + {"range": ["open","stop","close"]} + ) + ), + FunctionModel( + code: 'percent_control', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson( + {"unit": "%", "min": 0, "max": 100, "scale": 0, "step": 1}) + ), + ], }; enum TempModes { hot, cold, wind }