mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-14 17:25:47 +00:00
curtain changes
This commit is contained in:
211
lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart
Normal file
211
lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
34
lib/features/devices/bloc/curtain_bloc/curtain_event.dart
Normal file
34
lib/features/devices/bloc/curtain_bloc/curtain_event.dart
Normal 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 {}
|
76
lib/features/devices/bloc/curtain_bloc/curtain_state.dart
Normal file
76
lib/features/devices/bloc/curtain_bloc/curtain_state.dart
Normal 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];
|
||||
}
|
@ -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 {
|
||||
|
@ -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<DevicesCubit, DevicesState>(
|
||||
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<DevicesCubit, DevicesState>(
|
||||
// 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,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
@ -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 {
|
||||
const CurtainButtons({super.key, required this.curtain});
|
||||
final DeviceModel curtain;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
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,
|
||||
children: [
|
||||
DecoratedBox(
|
||||
decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [
|
||||
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,
|
||||
),
|
||||
onTap: onTap,
|
||||
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,
|
||||
onTap: onTap,
|
||||
child: isSvg
|
||||
? SvgPicture.asset(iconPath, width: 110, height: 110)
|
||||
: Image.asset(iconPath, 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -1,23 +1,37 @@
|
||||
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<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) => DefaultScaffold(
|
||||
create: (context) => CurtainBloc(curtain.uuid!)..add(InitCurtain()),
|
||||
child: BlocBuilder<CurtainBloc, CurtainState>(
|
||||
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: [
|
||||
@ -41,13 +55,11 @@ class CurtainView extends StatelessWidget {
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.linear,
|
||||
height: 310,
|
||||
width: DevicesCubit.getInstance().curtainWidth,
|
||||
width: curtainWidth,
|
||||
child: Stack(
|
||||
children: List.generate(
|
||||
10,
|
||||
(index) {
|
||||
double spacing =
|
||||
DevicesCubit.getInstance().curtainWidth / 9;
|
||||
10, (index) {
|
||||
double spacing = curtainWidth / 9;
|
||||
double leftMostPosition = index * spacing;
|
||||
return AnimatedPositioned(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
@ -71,16 +83,17 @@ class CurtainView extends StatelessWidget {
|
||||
top: 27,
|
||||
left: 43,
|
||||
child: SvgPicture.asset(
|
||||
Assets.assetsIconsCurtainsIconCurtainHolder)),
|
||||
Assets.assetsIconsCurtainsIconCurtainHolder,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 80),
|
||||
CurtainButtons(
|
||||
curtain: curtain,
|
||||
),
|
||||
CurtainButtons(curtain: curtain),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ class DevicesViewBody extends StatelessWidget {
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: PageView(
|
||||
controller: HomeCubit.getInstance().devicesPageController,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -32,11 +32,14 @@ class DevicesAPI {
|
||||
static Future<Map<String, dynamic>> 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;
|
||||
},
|
||||
);
|
||||
|
@ -68,6 +68,7 @@ Map<String, DeviceType> devicesTypesMap = {
|
||||
"DL": DeviceType.DoorLock,
|
||||
"WPS": DeviceType.WallSensor,
|
||||
"3G": DeviceType.ThreeGang,
|
||||
"CUR": DeviceType.Curtain,
|
||||
};
|
||||
Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
DeviceType.AC: [
|
||||
@ -174,6 +175,21 @@ Map<DeviceType, List<FunctionModel>> 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 }
|
||||
|
Reference in New Issue
Block a user