curtain changes

This commit is contained in:
mohammad
2024-08-29 16:54:43 +03:00
parent dcc98445d7
commit 9c23ab1399
12 changed files with 638 additions and 398 deletions

View File

@ -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<CurtainEvent, CurtainState> {
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<InitCurtain>(_fetchStatus);
on<OpenCurtain>(_onOpenCurtain);
on<CloseCurtain>(_onCloseCurtain);
on<PauseCurtain>(_onPauseCurtain);
}
Future<void> _onOpenCurtain(
OpenCurtain event,
Emitter<CurtainState> 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<void> _onCloseCurtain(
CloseCurtain event, Emitter<CurtainState> 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<void> _onPauseCurtain(
PauseCurtain event, Emitter<CurtainState> 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<void> _pauseCurtain(Emitter<CurtainState> emit) async {
isMoving = false;
emit(CurtainsPaused(
curtainWidth: curtainWidth,
blindHeight: blindHeight,
openPercentage: openPercentage,
));
}
// void _fetchStatus(InitCurtain event, Emitter<CurtainState> emit) async {
// try {
// var response = await DevicesAPI.getDeviceStatus(curtainId);
// List<StatusModel> 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<CurtainState> emit) async {
try {
emit(CurtainLoadingState());
// Fetch the status from the API
var response = await DevicesAPI.getDeviceStatus(curtainId);
List<StatusModel> 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;
}
}
}

View File

@ -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<Object?> get props => [];
}
class OpenCurtain extends CurtainEvent {
final DeviceType deviceType;
const OpenCurtain(this.deviceType);
@override
List<Object?> get props => [deviceType];
}
class CloseCurtain extends CurtainEvent {
final DeviceType deviceType;
const CloseCurtain(this.deviceType);
@override
List<Object?> get props => [deviceType];
}
class InitCurtain extends CurtainEvent {}
class PauseCurtain extends CurtainEvent {}
class useCurtainEvent extends CurtainEvent {}

View File

@ -0,0 +1,76 @@
// curtain_state.dart
import 'package:equatable/equatable.dart';
abstract class CurtainState extends Equatable {
const CurtainState();
@override
List<Object?> 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<Object?> 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<Object?> 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<Object?> 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<Object?> get props => [curtainWidth, blindHeight, openPercentage];
}

View File

@ -397,87 +397,7 @@ class DevicesCubit extends Cubit<DevicesState> {
// } // }
// } // }
//////////////////////////////////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 { enum LightMode {

View File

@ -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/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart';
class BlindsView extends StatelessWidget { // class BlindsView extends StatelessWidget {
const BlindsView({ // const BlindsView({
super.key, // super.key,
this.blind, // this.blind,
}); // });
final DeviceModel? blind; // final DeviceModel? blind;
@override // @override
Widget build(BuildContext context) { // Widget build(BuildContext context) {
return BlocProvider( // return BlocProvider(
create: (context) => DevicesCubit.getInstance(), // create: (context) => DevicesCubit.getInstance(),
child: BlocBuilder<DevicesCubit, DevicesState>( // child: BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) { // builder: (context, state) {
return DefaultScaffold( // return DefaultScaffold(
title: blind?.name ?? 'Blinds', // title: blind?.name ?? 'Blinds',
child: Column( // child: Column(
children: [ // children: [
Column( // Column(
children: [ // children: [
Stack( // Stack(
alignment: Alignment.topCenter, // alignment: Alignment.topCenter,
children: [ // children: [
Container( // Container(
height: 340, // height: 340,
width: 365, // width: 365,
decoration: const BoxDecoration( // decoration: const BoxDecoration(
image: DecorationImage( // image: DecorationImage(
image: AssetImage( // image: AssetImage(
Assets.assetsImagesWindow, // Assets.assetsImagesWindow,
), // ),
), // ),
), // ),
), // ),
Padding( // Padding(
padding: const EdgeInsets.only(top: 15, bottom: 10), // padding: const EdgeInsets.only(top: 15, bottom: 10),
child: AnimatedContainer( // child: AnimatedContainer(
duration: const Duration(milliseconds: 200), // duration: const Duration(milliseconds: 200),
curve: Curves.linear, // curve: Curves.linear,
height: DevicesCubit.get(context).blindWindowHight, // height: DevicesCubit.get(context).blindWindowHight,
width: 270, // width: 270,
child: Stack( // child: Stack(
children: List.generate( // children: List.generate(
25, // 25,
(index) { // (index) {
double spacing = DevicesCubit.get(context) // double spacing = DevicesCubit.get(context)
.blindWindowHight / // .blindWindowHight /
24; // 24;
double topPosition = index * spacing; // double topPosition = index * spacing;
return AnimatedPositioned( // return AnimatedPositioned(
duration: const Duration(milliseconds: 200), // duration: const Duration(milliseconds: 200),
curve: Curves.linear, // curve: Curves.linear,
top: topPosition, // top: topPosition,
child: SizedBox( // child: SizedBox(
height: 10, // height: 10,
width: 270, // width: 270,
child: Image.asset( // child: Image.asset(
Assets.assetsImagesHorizintalBlade, // Assets.assetsImagesHorizintalBlade,
fit: BoxFit.fill, // fit: BoxFit.fill,
), // ),
), // ),
); // );
}, // },
), // ),
), // ),
), // ),
), // ),
], // ],
), // ),
const SizedBox(height: 80), // const SizedBox(height: 80),
Row( // Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ // children: [
DecoratedBox( // DecoratedBox(
decoration: // decoration:
BoxDecoration(shape: BoxShape.circle, boxShadow: [ // BoxDecoration(shape: BoxShape.circle, boxShadow: [
BoxShadow( // BoxShadow(
color: Colors.grey.withOpacity(0.5), // color: Colors.grey.withOpacity(0.5),
spreadRadius: 1, // spreadRadius: 1,
blurRadius: 5, // blurRadius: 5,
offset: const Offset(3, 3), // offset: const Offset(3, 3),
), // ),
]), // ]),
child: InkWell( // child: InkWell(
overlayColor: // overlayColor:
MaterialStateProperty.all(Colors.transparent), // MaterialStateProperty.all(Colors.transparent),
onTap: () { // onTap: () {
// DevicesCubit.get(context).setHight(false); // // DevicesCubit.get(context).setHight(false);
DevicesCubit.get(context).openCurtain( // DevicesCubit.get(context).openCurtain(
blind?.productType! ?? DeviceType.Blind); // blind?.productType! ?? DeviceType.Blind);
}, // },
child: Image.asset( // child: Image.asset(
Assets.assetsImagesUp, // Assets.assetsImagesUp,
width: 60, // width: 60,
height: 60, // height: 60,
), // ),
), // ),
), // ),
DecoratedBox( // DecoratedBox(
decoration: // decoration:
BoxDecoration(shape: BoxShape.circle, boxShadow: [ // BoxDecoration(shape: BoxShape.circle, boxShadow: [
BoxShadow( // BoxShadow(
color: Colors.grey.withOpacity(0.5), // color: Colors.grey.withOpacity(0.5),
spreadRadius: 1, // spreadRadius: 1,
blurRadius: 5, // blurRadius: 5,
offset: const Offset(3, 3), // offset: const Offset(3, 3),
), // ),
]), // ]),
child: InkWell( // child: InkWell(
overlayColor: // overlayColor:
MaterialStateProperty.all(Colors.transparent), // MaterialStateProperty.all(Colors.transparent),
onTap: () { // onTap: () {
DevicesCubit.get(context).pauseCurtain(); // DevicesCubit.get(context).pauseCurtain();
}, // },
child: Image.asset( // child: Image.asset(
Assets.assetsImagesPause, // Assets.assetsImagesPause,
width: 60, // width: 60,
height: 60, // height: 60,
), // ),
), // ),
), // ),
DecoratedBox( // DecoratedBox(
decoration: // decoration:
BoxDecoration(shape: BoxShape.circle, boxShadow: [ // BoxDecoration(shape: BoxShape.circle, boxShadow: [
BoxShadow( // BoxShadow(
color: Colors.grey.withOpacity(0.5), // color: Colors.grey.withOpacity(0.5),
spreadRadius: 1, // spreadRadius: 1,
blurRadius: 5, // blurRadius: 5,
offset: const Offset(3, 3), // offset: const Offset(3, 3),
), // ),
]), // ]),
child: InkWell( // child: InkWell(
overlayColor: // overlayColor:
MaterialStateProperty.all(Colors.transparent), // MaterialStateProperty.all(Colors.transparent),
onTap: () { // onTap: () {
DevicesCubit.get(context).closeCurtain( // DevicesCubit.get(context).closeCurtain(
blind?.productType! ?? DeviceType.Blind); // blind?.productType! ?? DeviceType.Blind);
}, // },
child: Image.asset( // child: Image.asset(
Assets.assetsImagesDown, // Assets.assetsImagesDown,
width: 60, // width: 60,
height: 60, // height: 60,
), // ),
), // ),
), // ),
], // ],
), // ),
], // ],
), // ),
], // ],
), // ),
); // );
}, // },
), // ),
); // );
} // }
} // }

View File

@ -1,115 +1,74 @@
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 { class CurtainButtons extends StatelessWidget {
const CurtainButtons({super.key, required this.curtain}); const CurtainButtons({super.key, required this.curtain});
final DeviceModel curtain; final DeviceModel curtain;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
Stack( _buildButton(
onTap: () => context.read<CurtainBloc>().add(OpenCurtain(curtain.productType!)),
iconPath: Assets.assetsIconsCurtainsIconOpenCurtain,
),
_buildButton(
onTap: () => context.read<CurtainBloc>().add(PauseCurtain()),
iconPath: Assets.assetsImagesPause,
isSvg: false,
),
_buildButton(
onTap: () => context.read<CurtainBloc>().add(CloseCurtain(curtain.productType!)),
iconPath: Assets.assetsIconsCurtainsIconCloseCurtain,
),
],
);
}
Widget _buildButton({
required VoidCallback onTap,
required String iconPath,
bool isSvg = true,
}) {
return Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
DecoratedBox( DecoratedBox(
decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [ decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [
BoxShadow( BoxShadow(
color: Colors.grey.withOpacity(0.5), color: Colors.grey.withOpacity(0.5),
spreadRadius: 1, spreadRadius: 1,
blurRadius: 5, blurRadius: 5,
offset: const Offset(3, 3), offset: const Offset(3, 3),
), ),
]), ],
),
child: InkWell( child: InkWell(
overlayColor: MaterialStateProperty.all(Colors.transparent), overlayColor: MaterialStateProperty.all(Colors.transparent),
onTap: () { onTap: onTap,
DevicesCubit.get(context).openCurtain(curtain.productType!); child: const SizedBox.square(dimension: 60),
},
child: const SizedBox.square(
dimension: 60,
),
), ),
), ),
Padding( Padding(
padding: const EdgeInsets.only(right: 5, bottom: 5), padding: const EdgeInsets.only(right: 5, bottom: 5),
child: InkWell( child: InkWell(
overlayColor: MaterialStateProperty.all(Colors.transparent), overlayColor: MaterialStateProperty.all(Colors.transparent),
onTap: () { onTap: onTap,
DevicesCubit.get(context).openCurtain(curtain.productType!); child: isSvg
}, ? SvgPicture.asset(iconPath, width: 110, height: 110)
child: SvgPicture.asset( : Image.asset(iconPath, width: 60, height: 60),
Assets.assetsIconsCurtainsIconOpenCurtain,
width: 110,
height: 110,
), ),
), ),
)
],
),
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,
),
),
),
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,
),
),
)
],
),
], ],
); );
} }

View File

@ -1,23 +1,37 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.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/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/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/generated/assets.dart';
part "curtain_buttons.dart";
class CurtainView extends StatelessWidget { class CurtainView extends StatelessWidget {
const CurtainView({super.key, required this.curtain}); const CurtainView({super.key, required this.curtain});
final DeviceModel curtain; final DeviceModel curtain;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => DevicesCubit.getInstance(), create: (context) => CurtainBloc(curtain.uuid!)..add(InitCurtain()),
child: BlocBuilder<DevicesCubit, DevicesState>( child: BlocBuilder<CurtainBloc, CurtainState>(
builder: (context, state) => DefaultScaffold( 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, title: curtain.name,
child: Column( child: Column(
children: [ children: [
@ -41,13 +55,11 @@ class CurtainView extends StatelessWidget {
duration: const Duration(milliseconds: 200), duration: const Duration(milliseconds: 200),
curve: Curves.linear, curve: Curves.linear,
height: 310, height: 310,
width: DevicesCubit.getInstance().curtainWidth, width: curtainWidth,
child: Stack( child: Stack(
children: List.generate( children: List.generate(
10, 10, (index) {
(index) { double spacing = curtainWidth / 9;
double spacing =
DevicesCubit.getInstance().curtainWidth / 9;
double leftMostPosition = index * spacing; double leftMostPosition = index * spacing;
return AnimatedPositioned( return AnimatedPositioned(
duration: const Duration(milliseconds: 200), duration: const Duration(milliseconds: 200),
@ -71,16 +83,17 @@ class CurtainView extends StatelessWidget {
top: 27, top: 27,
left: 43, left: 43,
child: SvgPicture.asset( child: SvgPicture.asset(
Assets.assetsIconsCurtainsIconCurtainHolder)), Assets.assetsIconsCurtainsIconCurtainHolder,
),
),
], ],
), ),
const SizedBox(height: 80), const SizedBox(height: 80),
CurtainButtons( CurtainButtons(curtain: curtain),
curtain: curtain,
),
], ],
), ),
), );
},
), ),
); );
} }

View File

@ -66,6 +66,7 @@ class DevicesViewBody extends StatelessWidget {
const SizedBox( const SizedBox(
height: 10, height: 10,
), ),
Expanded( Expanded(
child: PageView( child: PageView(
controller: HomeCubit.getInstance().devicesPageController, controller: HomeCubit.getInstance().devicesPageController,

View File

@ -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/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/device_model.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/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/gateway/gateway_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface.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'; 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); // navigateToInterface(CeilingSensorInterface(ceilingSensor: device), context);
break; break;
case DeviceType.Curtain: case DeviceType.Curtain:
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
CurtainView(curtain: device,)));
break; break;
case DeviceType.Blind: case DeviceType.Blind:
break; break;

View File

@ -16,7 +16,7 @@ void main() {
//to catch all the errors in the app and send them to firebase //to catch all the errors in the app and send them to firebase
runZonedGuarded(() async { runZonedGuarded(() async {
//to load the environment variables //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'); await dotenv.load(fileName: '.env.$environment');
// //this is to make the app work with the self-signed certificate // //this is to make the app work with the self-signed certificate

View File

@ -32,11 +32,14 @@ class DevicesAPI {
static Future<Map<String, dynamic>> controlDevice( static Future<Map<String, dynamic>> controlDevice(
DeviceControlModel controlModel, String deviceId) async { DeviceControlModel controlModel, String deviceId) async {
try { try {
print('controlDevice====${controlModel.toJson()}');
print('controlDevice====${deviceId}');
final response = await _httpService.post( final response = await _httpService.post(
path: ApiEndpoints.controlDevice.replaceAll('{deviceUuid}', deviceId), path: ApiEndpoints.controlDevice.replaceAll('{deviceUuid}', deviceId),
body: controlModel.toJson(), body: controlModel.toJson(),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
print('json====${json}');
return json; return json;
}, },
); );
@ -74,6 +77,7 @@ class DevicesAPI {
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId), path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
print('getDeviceStatus=$json');
return json; return json;
}, },
); );

View File

@ -68,6 +68,7 @@ Map<String, DeviceType> devicesTypesMap = {
"DL": DeviceType.DoorLock, "DL": DeviceType.DoorLock,
"WPS": DeviceType.WallSensor, "WPS": DeviceType.WallSensor,
"3G": DeviceType.ThreeGang, "3G": DeviceType.ThreeGang,
"CUR": DeviceType.Curtain,
}; };
Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = { Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
DeviceType.AC: [ DeviceType.AC: [
@ -174,6 +175,21 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
type: functionTypesMap['Integer'], type: functionTypesMap['Integer'],
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), 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 } enum TempModes { hot, cold, wind }