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..c42acd9 --- /dev/null +++ b/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart @@ -0,0 +1,211 @@ +import 'package:dio/dio.dart'; +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/function_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 { + if (state is CurtainsOpening) return; + 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 { + if (state is CurtainsClosing) return; + 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 { + // var response = await DevicesAPI.getDeviceStatus(curtainId); + // List statusModelList = []; + // for (var status in response['status']) { + // print(status); + // statusModelList.add(StatusModel.fromJson(status)); + // } + // openPercentage = double.tryParse(statusModelList[1].value.toString())!; + // emit(CurtainsOpening( + // curtainWidth: curtainWidth , + // blindHeight: blindHeight, + // openPercentage: openPercentage, + // )); + // } catch (e) { + // emit(FailedState()); + // return; + // } + // } + 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']) { + print(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; + } + print('openPercentage fetched: $openPercentage'); + print('Calculated curtainWidth: $curtainWidth'); + print('Calculated blindHeight: $blindHeight'); + // Emit the updated state with calculated values + 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 index dc47d41..3de0ceb 100644 --- a/lib/features/devices/view/widgets/curtains/blind_view.dart +++ b/lib/features/devices/view/widgets/curtains/blind_view.dart @@ -6,158 +6,158 @@ 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, - ), - ), - ), - ], - ), - ], - ), - ], - ), - ); - }, - ), - ); - } -} +// 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/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..35b6fdd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -16,7 +16,7 @@ void main() { //to catch all the errors in the app and send them to firebase runZonedGuarded(() async { //to load the environment variables - const environment = String.fromEnvironment('FLAVOR', defaultValue: 'production'); + const environment = String.fromEnvironment('FLAVOR', defaultValue: 'development'); await dotenv.load(fileName: '.env.$environment'); // //this is to make the app work with the self-signed certificate diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index 5439039..deb6c6a 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -32,11 +32,14 @@ class DevicesAPI { static Future> controlDevice( DeviceControlModel controlModel, String deviceId) async { try { + print('controlDevice====${controlModel.toJson()}'); + print('controlDevice====${deviceId}'); final response = await _httpService.post( path: ApiEndpoints.controlDevice.replaceAll('{deviceUuid}', deviceId), body: controlModel.toJson(), showServerMessage: false, expectedResponseModel: (json) { + print('json====${json}'); return json; }, ); @@ -74,6 +77,7 @@ class DevicesAPI { path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { + print('getDeviceStatus=$json'); return json; }, ); 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 }