mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-03-11 08:51:44 +00:00
Compare commits
13 Commits
forgetpass
...
bugfix/SP-
| Author | SHA1 | Date | |
|---|---|---|---|
| 21c336360c | |||
| fee34703bd | |||
| a92676d6a4 | |||
| 8c5cf2c04e | |||
| 1f02f66916 | |||
| 3ea089425c | |||
| 77d2f54352 | |||
| cff66bb653 | |||
| 022ba53f5d | |||
| bf69399af2 | |||
| a72fc0b466 | |||
| df13840a65 | |||
| 032a28d47a |
14
assets/icons/success-white.svg
Normal file
14
assets/icons/success-white.svg
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g id="Group 284">
|
||||||
|
<g id="Group">
|
||||||
|
<g id="Group_2">
|
||||||
|
<path id="Vector" d="M37.8033 16.3571C37.2313 15.7851 36.3039 15.785 35.7318 16.3572L21.5532 30.5356L14.2681 23.2508C13.6962 22.6788 12.7686 22.6787 12.1966 23.2509C11.6246 23.8229 11.6246 24.7504 12.1966 25.3224L20.5174 33.643C20.8034 33.9291 21.1783 34.072 21.5531 34.072C21.928 34.072 22.3029 33.9291 22.5888 33.6429L37.8033 18.4287C38.3754 17.8567 38.3754 16.9292 37.8033 16.3571Z" fill="white"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g id="Group_3">
|
||||||
|
<g id="Group_4">
|
||||||
|
<path id="Vector_2" d="M42.6776 7.32236C37.9558 2.60049 31.6776 0 25 0C18.3223 0 12.0442 2.60049 7.32236 7.32236C2.60039 12.0443 0 18.3224 0 25C0 31.6778 2.60039 37.9559 7.32236 42.6777C12.0441 47.3996 18.3223 50 25 50C31.6777 50 37.9558 47.3996 42.6776 42.6777C47.3995 37.9559 50 31.6778 50 25C50 18.3224 47.3995 12.0443 42.6776 7.32236ZM25 47.0703C12.8304 47.0703 2.92969 37.1696 2.92969 25C2.92969 12.8304 12.8304 2.92969 25 2.92969C37.1696 2.92969 47.0703 12.8304 47.0703 25C47.0703 37.1696 37.1696 47.0703 25 47.0703Z" fill="white"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -241,14 +241,16 @@ class AuthCubit extends Cubit<AuthState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reSendOtp() async {
|
Future<bool> reSendOtp() async {
|
||||||
try {
|
try {
|
||||||
emit(AuthLoading());
|
emit(AuthLoading());
|
||||||
await AuthenticationAPI.sendOtp(
|
await AuthenticationAPI.sendOtp(
|
||||||
body: {'email': email, 'type': 'VERIFICATION'});
|
body: {'email': email, 'type': 'VERIFICATION'});
|
||||||
emit(ResendOtpSuccess());
|
emit(ResendOtpSuccess());
|
||||||
|
return true;
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
emit(AuthLoginError(message: 'Something went wrong'));
|
emit(AuthLoginError(message: 'Something went wrong'));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import 'package:pin_code_fields/pin_code_fields.dart';
|
|||||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||||
import 'package:syncrow_app/features/auth/view/create_new_password.dart';
|
import 'package:syncrow_app/features/auth/view/create_new_password.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/success_dialog.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||||
@ -40,13 +41,19 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
_lifecycleEventHandler = LifecycleEventHandler(
|
_lifecycleEventHandler = LifecycleEventHandler(
|
||||||
resumeCallBack: () async {
|
resumeCallBack: () async {
|
||||||
SharedPreferencesHelper.saveBoolToSP('timeStampSaved', false);
|
SharedPreferencesHelper.saveBoolToSP('timeStampSaved', false);
|
||||||
String timeStampInBackground = await SharedPreferencesHelper.readStringFromSP('timeStamp');
|
String timeStampInBackground =
|
||||||
int savedCounter = await SharedPreferencesHelper.readIntFromSP('savedCounter');
|
await SharedPreferencesHelper.readStringFromSP('timeStamp');
|
||||||
|
int savedCounter =
|
||||||
|
await SharedPreferencesHelper.readIntFromSP('savedCounter');
|
||||||
DateTime currentTime = DateTime.now();
|
DateTime currentTime = DateTime.now();
|
||||||
int differenceInSeconds = timeStampInBackground.isNotEmpty
|
int differenceInSeconds = timeStampInBackground.isNotEmpty
|
||||||
? currentTime.difference(DateTime.parse(timeStampInBackground)).inSeconds
|
? currentTime
|
||||||
|
.difference(DateTime.parse(timeStampInBackground))
|
||||||
|
.inSeconds
|
||||||
: 0;
|
: 0;
|
||||||
remainingSec = differenceInSeconds > savedCounter ? 0 : savedCounter - differenceInSeconds;
|
remainingSec = differenceInSeconds > savedCounter
|
||||||
|
? 0
|
||||||
|
: savedCounter - differenceInSeconds;
|
||||||
timerStarted = true;
|
timerStarted = true;
|
||||||
startTimer(remainingSec ?? 0);
|
startTimer(remainingSec ?? 0);
|
||||||
return;
|
return;
|
||||||
@ -75,7 +82,8 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleTimerOnBackground() async {
|
handleTimerOnBackground() async {
|
||||||
bool timeStampSaved = await SharedPreferencesHelper.readBoolFromSP('timeStampSaved') ?? false;
|
bool timeStampSaved =
|
||||||
|
await SharedPreferencesHelper.readBoolFromSP('timeStampSaved') ?? false;
|
||||||
if (!timeStampSaved) {
|
if (!timeStampSaved) {
|
||||||
final dateInString = DateTime.now().toString();
|
final dateInString = DateTime.now().toString();
|
||||||
SharedPreferencesHelper.saveIntToSP('savedCounter', remainingSec ?? 0);
|
SharedPreferencesHelper.saveIntToSP('savedCounter', remainingSec ?? 0);
|
||||||
@ -115,7 +123,8 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
String maskedEmail = AuthCubit.get(context).maskEmail(AuthCubit.get(context).email);
|
String maskedEmail =
|
||||||
|
AuthCubit.get(context).maskEmail(AuthCubit.get(context).email);
|
||||||
return BlocConsumer<AuthCubit, AuthState>(
|
return BlocConsumer<AuthCubit, AuthState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is AuthOtpSuccess) {
|
if (state is AuthOtpSuccess) {
|
||||||
@ -199,7 +208,10 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
child: RichText(
|
child: RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
text: 'We have sent the verification code to',
|
text: 'We have sent the verification code to',
|
||||||
style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleSmall!
|
||||||
|
.copyWith(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontWeight: FontsManager.regular,
|
fontWeight: FontsManager.regular,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@ -207,7 +219,10 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
children: [
|
children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: ' $maskedEmail',
|
text: ' $maskedEmail',
|
||||||
style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleSmall!
|
||||||
|
.copyWith(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontWeight: FontsManager.bold,
|
fontWeight: FontsManager.bold,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@ -215,7 +230,10 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
),
|
),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: ' change email?',
|
text: ' change email?',
|
||||||
style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleSmall!
|
||||||
|
.copyWith(
|
||||||
color: const Color(0xFF87C7FF),
|
color: const Color(0xFF87C7FF),
|
||||||
fontWeight: FontsManager.regular,
|
fontWeight: FontsManager.regular,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@ -239,7 +257,8 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
autoFocus: true,
|
autoFocus: true,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
animationDuration: const Duration(milliseconds: 30),
|
animationDuration:
|
||||||
|
const Duration(milliseconds: 30),
|
||||||
beforeTextPaste: (text) {
|
beforeTextPaste: (text) {
|
||||||
// Allow pasting only if all characters are numeric
|
// Allow pasting only if all characters are numeric
|
||||||
return int.tryParse(text!) != null;
|
return int.tryParse(text!) != null;
|
||||||
@ -262,18 +281,27 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
errorBorderWidth: 1,
|
errorBorderWidth: 1,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
errorBorderColor: Colors.red,
|
errorBorderColor: Colors.red,
|
||||||
activeColor: state is AuthLoginError ? Colors.red : Colors.white,
|
activeColor: state is AuthLoginError
|
||||||
inactiveColor:
|
? Colors.red
|
||||||
state is AuthLoginError ? Colors.red : Colors.white,
|
: Colors.white,
|
||||||
activeFillColor:
|
inactiveColor: state is AuthLoginError
|
||||||
state is AuthLoginError ? Colors.red : Colors.white,
|
? Colors.red
|
||||||
inactiveFillColor:
|
: Colors.white,
|
||||||
state is AuthLoginError ? Colors.red : Colors.white,
|
activeFillColor: state is AuthLoginError
|
||||||
selectedFillColor:
|
? Colors.red
|
||||||
state is AuthLoginError ? Colors.red : Colors.white,
|
: Colors.white,
|
||||||
|
inactiveFillColor: state is AuthLoginError
|
||||||
|
? Colors.red
|
||||||
|
: Colors.white,
|
||||||
|
selectedFillColor: state is AuthLoginError
|
||||||
|
? Colors.red
|
||||||
|
: Colors.white,
|
||||||
disabledColor: Colors.white,
|
disabledColor: Colors.white,
|
||||||
fieldHeight: 56,
|
fieldHeight: 56,
|
||||||
fieldWidth: MediaQuery.sizeOf(context).width > 340 ? 40 : 20,
|
fieldWidth:
|
||||||
|
MediaQuery.sizeOf(context).width > 340
|
||||||
|
? 40
|
||||||
|
: 20,
|
||||||
// fieldWidth: 40,
|
// fieldWidth: 40,
|
||||||
selectedColor: Colors.white,
|
selectedColor: Colors.white,
|
||||||
shape: PinCodeFieldShape.box,
|
shape: PinCodeFieldShape.box,
|
||||||
@ -295,10 +323,12 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
isDone: state is AuthLoginSuccess,
|
isDone: state is AuthLoginSuccess,
|
||||||
isLoading: state is AuthLoading,
|
isLoading: state is AuthLoading,
|
||||||
customButtonStyle: ButtonStyle(
|
customButtonStyle: ButtonStyle(
|
||||||
backgroundColor: MaterialStateProperty.all(
|
backgroundColor:
|
||||||
|
MaterialStateProperty.all(
|
||||||
Colors.black.withOpacity(.25),
|
Colors.black.withOpacity(.25),
|
||||||
),
|
),
|
||||||
foregroundColor: MaterialStateProperty.all(
|
foregroundColor:
|
||||||
|
MaterialStateProperty.all(
|
||||||
Colors.white,
|
Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -307,7 +337,8 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if ((state is! AuthLoading)) {
|
if ((state is! AuthLoading)) {
|
||||||
AuthCubit.get(context).verifyOtp(widget.isForgetPage);
|
AuthCubit.get(context)
|
||||||
|
.verifyOtp(widget.isForgetPage);
|
||||||
FocusScope.of(context).unfocus();
|
FocusScope.of(context).unfocus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -321,10 +352,12 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
isDone: state is AuthLoginSuccess,
|
isDone: state is AuthLoginSuccess,
|
||||||
isLoading: state is AuthLoading,
|
isLoading: state is AuthLoading,
|
||||||
customButtonStyle: ButtonStyle(
|
customButtonStyle: ButtonStyle(
|
||||||
backgroundColor: MaterialStateProperty.all(
|
backgroundColor:
|
||||||
|
MaterialStateProperty.all(
|
||||||
Colors.black.withOpacity(.25),
|
Colors.black.withOpacity(.25),
|
||||||
),
|
),
|
||||||
foregroundColor: MaterialStateProperty.all(
|
foregroundColor:
|
||||||
|
MaterialStateProperty.all(
|
||||||
Colors.white,
|
Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -341,8 +374,20 @@ class _OtpViewState extends State<OtpView> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((state is! AuthLoading)) {
|
if ((state is! AuthLoading)) {
|
||||||
await AuthCubit.get(context).reSendOtp();
|
bool success = await AuthCubit.get(context)
|
||||||
|
.reSendOtp();
|
||||||
FocusScope.of(context).unfocus();
|
FocusScope.of(context).unfocus();
|
||||||
|
if(success){
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (_) => SuccessDialog(
|
||||||
|
key: ValueKey('SuccessDialog'),
|
||||||
|
message: 'New OTP sent!',));
|
||||||
|
}
|
||||||
|
Future.delayed(Duration(seconds: 2),
|
||||||
|
() {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,184 +0,0 @@
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_event.dart';
|
|
||||||
import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_state.dart';
|
|
||||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
|
||||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
|
||||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
|
||||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
|
||||||
|
|
||||||
class CurtainBloc extends Bloc<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 {
|
|
||||||
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 {
|
|
||||||
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 {
|
|
||||||
emit(CurtainLoadingState());
|
|
||||||
// Fetch the status from the API
|
|
||||||
var response = await DevicesAPI.getDeviceStatus(curtainId);
|
|
||||||
List<StatusModel> statusModelList = [];
|
|
||||||
for (var status in response['status']) {
|
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
|
||||||
}
|
|
||||||
// Get the open percentage from the response
|
|
||||||
openPercentage = double.tryParse(statusModelList[1].value.toString())!;
|
|
||||||
// Calculate curtain width and blind height based on the open percentage
|
|
||||||
if (openPercentage != null) {
|
|
||||||
curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace;
|
|
||||||
blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace;
|
|
||||||
}
|
|
||||||
emit(CurtainsOpening(
|
|
||||||
curtainWidth: curtainWidth,
|
|
||||||
blindHeight: blindHeight,
|
|
||||||
openPercentage: openPercentage,
|
|
||||||
));
|
|
||||||
} catch (e) {
|
|
||||||
emit(FailedState());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 {}
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
// 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];
|
|
||||||
}
|
|
||||||
@ -87,10 +87,10 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
return const DoorsListView();
|
return const DoorsListView();
|
||||||
case DeviceType.Curtain:
|
case DeviceType.Curtain:
|
||||||
return const CurtainListView();
|
return const CurtainListView();
|
||||||
// case DeviceType.ThreeGang:
|
// case DeviceType.ThreeGang:
|
||||||
// return const ThreeGangSwitchesView();
|
// return const ThreeGangSwitchesView();
|
||||||
// case DeviceType.Gateway:
|
// case DeviceType.Gateway:
|
||||||
// return const GateWayView();
|
// return const GateWayView();
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -308,10 +308,10 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
|
|
||||||
emitSafe(GetDevicesLoading());
|
emitSafe(GetDevicesLoading());
|
||||||
int roomIndex =
|
int roomIndex =
|
||||||
HomeCubit.getInstance().selectedSpace!.rooms!.indexWhere((element) => element.id == roomId);
|
HomeCubit.getInstance().selectedSpace!.rooms!.indexWhere((element) => element.id == roomId);
|
||||||
try {
|
try {
|
||||||
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices =
|
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices =
|
||||||
await DevicesAPI.getDevicesByRoomId(roomId);
|
await DevicesAPI.getDevicesByRoomId(roomId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emitSafe(GetDevicesError(e.toString()));
|
emitSafe(GetDevicesError(e.toString()));
|
||||||
return;
|
return;
|
||||||
@ -397,7 +397,87 @@ 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 {
|
||||||
|
|||||||
@ -54,7 +54,6 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
bool isStartEndTime = true;
|
bool isStartEndTime = true;
|
||||||
DateTime? startTime;
|
DateTime? startTime;
|
||||||
DateTime? endTime;
|
DateTime? endTime;
|
||||||
int unlockRequest = 0;
|
|
||||||
List<TemporaryPassword>? temporaryPasswords = [];
|
List<TemporaryPassword>? temporaryPasswords = [];
|
||||||
List<OfflinePasswordModel>? oneTimePasswords = [];
|
List<OfflinePasswordModel>? oneTimePasswords = [];
|
||||||
List<OfflinePasswordModel>? timeLimitPasswords = [];
|
List<OfflinePasswordModel>? timeLimitPasswords = [];
|
||||||
@ -129,7 +128,6 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_doorLockUpdated(DoorLockUpdated event, Emitter<SmartDoorState> emit) {
|
_doorLockUpdated(DoorLockUpdated event, Emitter<SmartDoorState> emit) {
|
||||||
unlockRequest = deviceStatus.unlockRequest;
|
|
||||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
163
lib/features/devices/view/widgets/curtains/blind_view.dart
Normal file
163
lib/features/devices/view/widgets/curtains/blind_view.dart
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||||
|
|
||||||
|
class BlindsView extends StatelessWidget {
|
||||||
|
const BlindsView({
|
||||||
|
super.key,
|
||||||
|
this.blind,
|
||||||
|
});
|
||||||
|
final DeviceModel? blind;
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) => DevicesCubit.getInstance(),
|
||||||
|
child: BlocBuilder<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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
// import 'package:flutter/material.dart';
|
||||||
|
// import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||||
|
// import 'package:syncrow_app/generated2/assets.dart';
|
||||||
|
|
||||||
|
// class BlindsBottons extends StatelessWidget {
|
||||||
|
// const BlindsBottons({
|
||||||
|
// super.key,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
// children: [
|
||||||
|
// DecoratedBox(
|
||||||
|
// decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [
|
||||||
|
// BoxShadow(
|
||||||
|
// color: Colors.grey.withOpacity(0.5),
|
||||||
|
// spreadRadius: 1,
|
||||||
|
// blurRadius: 5,
|
||||||
|
// offset: const Offset(3, 3),
|
||||||
|
// ),
|
||||||
|
// ]),
|
||||||
|
// child: InkWell(
|
||||||
|
// overlayColor: MaterialStateProperty.all(Colors.transparent),
|
||||||
|
// onTap: () {
|
||||||
|
// // DevicesCubit.get(context).setHight(false);
|
||||||
|
// DevicesCubit.get(context).closeCurtain();
|
||||||
|
// },
|
||||||
|
// child: Image.asset(
|
||||||
|
// Assets.assetsImagesUp,
|
||||||
|
// width: 60,
|
||||||
|
// height: 60,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// DecoratedBox(
|
||||||
|
// decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [
|
||||||
|
// BoxShadow(
|
||||||
|
// color: Colors.grey.withOpacity(0.5),
|
||||||
|
// spreadRadius: 1,
|
||||||
|
// blurRadius: 5,
|
||||||
|
// offset: const Offset(3, 3),
|
||||||
|
// ),
|
||||||
|
// ]),
|
||||||
|
// child: InkWell(
|
||||||
|
// overlayColor: MaterialStateProperty.all(Colors.transparent),
|
||||||
|
// onTap: () {
|
||||||
|
// // DevicesCubit.get(context).setHight(false);
|
||||||
|
// },
|
||||||
|
// child: Image.asset(
|
||||||
|
// Assets.assetsImagesPause,
|
||||||
|
// width: 60,
|
||||||
|
// height: 60,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// DecoratedBox(
|
||||||
|
// decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [
|
||||||
|
// BoxShadow(
|
||||||
|
// color: Colors.grey.withOpacity(0.5),
|
||||||
|
// spreadRadius: 1,
|
||||||
|
// blurRadius: 5,
|
||||||
|
// offset: const Offset(3, 3),
|
||||||
|
// ),
|
||||||
|
// ]),
|
||||||
|
// child: InkWell(
|
||||||
|
// overlayColor: MaterialStateProperty.all(Colors.transparent),
|
||||||
|
// onTap: () {
|
||||||
|
// // DevicesCubit.get(context).setHight(true);
|
||||||
|
// DevicesCubit.get(context).openCurtain();
|
||||||
|
// },
|
||||||
|
// child: Image.asset(
|
||||||
|
// Assets.assetsImagesDown,
|
||||||
|
// width: 60,
|
||||||
|
// height: 60,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@ -1,73 +1,114 @@
|
|||||||
|
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: [
|
||||||
_buildButton(
|
Stack(
|
||||||
onTap: () => context.read<CurtainBloc>().add(OpenCurtain(curtain.productType!)),
|
alignment: Alignment.center,
|
||||||
iconPath: Assets.assetsIconsCurtainsIconOpenCurtain,
|
children: [
|
||||||
),
|
DecoratedBox(
|
||||||
_buildButton(
|
decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [
|
||||||
onTap: () => context.read<CurtainBloc>().add(PauseCurtain()),
|
BoxShadow(
|
||||||
iconPath: Assets.assetsImagesPause,
|
color: Colors.grey.withOpacity(0.5),
|
||||||
isSvg: false,
|
spreadRadius: 1,
|
||||||
),
|
blurRadius: 5,
|
||||||
_buildButton(
|
offset: const Offset(3, 3),
|
||||||
onTap: () => context.read<CurtainBloc>().add(CloseCurtain(curtain.productType!)),
|
),
|
||||||
iconPath: Assets.assetsIconsCurtainsIconCloseCurtain,
|
]),
|
||||||
),
|
child: InkWell(
|
||||||
],
|
overlayColor: MaterialStateProperty.all(Colors.transparent),
|
||||||
);
|
onTap: () {
|
||||||
}
|
DevicesCubit.get(context).openCurtain(curtain.productType!);
|
||||||
|
},
|
||||||
Widget _buildButton({
|
child: const SizedBox.square(
|
||||||
required VoidCallback onTap,
|
dimension: 60,
|
||||||
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),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
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(
|
child: InkWell(
|
||||||
overlayColor: MaterialStateProperty.all(Colors.transparent),
|
overlayColor: MaterialStateProperty.all(Colors.transparent),
|
||||||
onTap: onTap,
|
onTap: () {
|
||||||
child: const SizedBox.square(dimension: 60),
|
DevicesCubit.get(context).pauseCurtain();
|
||||||
|
},
|
||||||
|
child: Image.asset(
|
||||||
|
Assets.assetsImagesPause,
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Stack(
|
||||||
padding: const EdgeInsets.only(right: 5, bottom: 5),
|
alignment: Alignment.center,
|
||||||
child: InkWell(
|
children: [
|
||||||
overlayColor: MaterialStateProperty.all(Colors.transparent),
|
DecoratedBox(
|
||||||
onTap: onTap,
|
decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [
|
||||||
child: isSvg
|
BoxShadow(
|
||||||
? SvgPicture.asset(iconPath, width: 110, height: 110)
|
color: Colors.grey.withOpacity(0.5),
|
||||||
: Image.asset(iconPath, width: 60, height: 60),
|
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,99 +1,86 @@
|
|||||||
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/curtain_bloc/curtain_bloc.dart';
|
import 'package:syncrow_app/features/devices/bloc/devices_cubit.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) => CurtainBloc(curtain.uuid!)..add(InitCurtain()),
|
create: (context) => DevicesCubit.getInstance(),
|
||||||
child: BlocBuilder<CurtainBloc, CurtainState>(
|
child: BlocBuilder<DevicesCubit, DevicesState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) => DefaultScaffold(
|
||||||
double curtainWidth = 270;
|
title: curtain.name,
|
||||||
double blindHeight = 310;
|
child: Column(
|
||||||
if (state is CurtainsOpening) {
|
children: [
|
||||||
curtainWidth = state.curtainWidth;
|
Stack(
|
||||||
blindHeight = state.blindHeight;
|
alignment: Alignment.centerLeft,
|
||||||
} else if (state is CurtainsClosing) {
|
children: [
|
||||||
curtainWidth = state.curtainWidth;
|
Container(
|
||||||
blindHeight = state.blindHeight;
|
height: 340,
|
||||||
} else if (state is CurtainsPaused) {
|
width: 365,
|
||||||
curtainWidth = state.curtainWidth;
|
decoration: const BoxDecoration(
|
||||||
blindHeight = state.blindHeight;
|
image: DecorationImage(
|
||||||
}
|
image: AssetImage(
|
||||||
return DefaultScaffold(
|
Assets.assetsImagesWindow,
|
||||||
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),
|
Padding(
|
||||||
child: AnimatedContainer(
|
padding: const EdgeInsets.all(40),
|
||||||
duration: const Duration(milliseconds: 200),
|
child: AnimatedContainer(
|
||||||
curve: Curves.linear,
|
duration: const Duration(milliseconds: 200),
|
||||||
height: 310,
|
curve: Curves.linear,
|
||||||
width: curtainWidth,
|
height: 310,
|
||||||
child: Stack(
|
width: DevicesCubit.getInstance().curtainWidth,
|
||||||
children: List.generate(
|
child: Stack(
|
||||||
10, (index) {
|
children: List.generate(
|
||||||
double spacing = curtainWidth / 9;
|
10,
|
||||||
double leftMostPosition = index * spacing;
|
(index) {
|
||||||
return AnimatedPositioned(
|
double spacing =
|
||||||
duration: const Duration(milliseconds: 200),
|
DevicesCubit.getInstance().curtainWidth / 9;
|
||||||
curve: Curves.linear,
|
double leftMostPosition = index * spacing;
|
||||||
left: leftMostPosition,
|
return AnimatedPositioned(
|
||||||
child: SizedBox(
|
duration: const Duration(milliseconds: 200),
|
||||||
height: 320,
|
curve: Curves.linear,
|
||||||
width: 32,
|
left: leftMostPosition,
|
||||||
child: SvgPicture.asset(
|
child: SizedBox(
|
||||||
Assets.assetsIconsCurtainsIconVerticalBlade,
|
height: 320,
|
||||||
fit: BoxFit.fill,
|
width: 32,
|
||||||
),
|
child: SvgPicture.asset(
|
||||||
|
Assets.assetsIconsCurtainsIconVerticalBlade,
|
||||||
|
fit: BoxFit.fill,
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
);
|
||||||
),
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
),
|
||||||
|
Positioned(
|
||||||
top: 27,
|
top: 27,
|
||||||
left: 43,
|
left: 43,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.assetsIconsCurtainsIconCurtainHolder,
|
Assets.assetsIconsCurtainsIconCurtainHolder)),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
const SizedBox(height: 80),
|
||||||
),
|
CurtainButtons(
|
||||||
const SizedBox(height: 80),
|
curtain: curtain,
|
||||||
CurtainButtons(curtain: curtain),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,6 @@ 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,
|
||||||
|
|||||||
@ -8,7 +8,6 @@ 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';
|
||||||
@ -103,11 +102,6 @@ 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;
|
||||||
|
|||||||
@ -31,36 +31,47 @@ class _DoorLockButtonState extends State<DoorLockButton> with SingleTickerProvid
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
_animationController = AnimationController(
|
_animationController = AnimationController(
|
||||||
vsync: this,
|
vsync: this,
|
||||||
value: context.read<SmartDoorBloc>().unlockRequest > 0 ? 1 : 0,
|
value: smartDoorModel.unlockRequest > 0 ? 1 : 0,
|
||||||
duration: Duration(seconds: context.read<SmartDoorBloc>().unlockRequest),
|
duration: Duration(seconds: smartDoorModel.unlockRequest),
|
||||||
);
|
);
|
||||||
if (context.read<SmartDoorBloc>().unlockRequest > 0) {
|
if (smartDoorModel.unlockRequest > 0) {
|
||||||
_animationController.reverse();
|
_animationController.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
_animation = Tween<double>(begin: 0, end: 1).animate(_animationController)
|
_animation = Tween<double>(begin: 0, end: 1).animate(_animationController)
|
||||||
..addListener(() {
|
..addListener(() {
|
||||||
|
// if (_animation.status == AnimationStatus.completed) {
|
||||||
|
// if (widget.doorLock.status
|
||||||
|
// .firstWhere((element) => element.code == 'normal_open_switch')
|
||||||
|
// .value !=
|
||||||
|
// true) {
|
||||||
|
// DevicesCubit.getInstance().deviceControl(
|
||||||
|
// DeviceControlModel(
|
||||||
|
// deviceId: widget.doorLock.uuid, code: 'normal_open_switch', value: true),
|
||||||
|
// widget.doorLock.uuid ?? "");
|
||||||
|
// }
|
||||||
|
// BlocProvider.of<SmartDoorBloc>(context)
|
||||||
|
// .add(UpdateLockEvent(value: smartDoorModel.normalOpenSwitch));
|
||||||
|
// _animationController.reverse();
|
||||||
|
// }
|
||||||
|
// } else if (_animation.status == AnimationStatus.dismissed) {
|
||||||
|
// // if (widget.doorLock.status
|
||||||
|
// // .firstWhere((element) => element.code == 'normal_open_switch')
|
||||||
|
// // .value !=
|
||||||
|
// // false) {
|
||||||
|
// DevicesCubit.getInstance().deviceControl(
|
||||||
|
// DeviceControlModel(
|
||||||
|
// deviceId: widget.doorLock.uuid, code: 'normal_open_switch', value: false),
|
||||||
|
// widget.doorLock.uuid ?? "");
|
||||||
|
// // }
|
||||||
|
// _animationController.forward();
|
||||||
|
// }
|
||||||
setState(() {});
|
setState(() {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void didUpdateWidget(DoorLockButton oldWidget) {
|
|
||||||
super.didUpdateWidget(oldWidget);
|
|
||||||
|
|
||||||
if (_animationController.status == AnimationStatus.dismissed) {
|
|
||||||
if (context.read<SmartDoorBloc>().unlockRequest > 0) {
|
|
||||||
_animationController.value = 1;
|
|
||||||
_animationController.duration =
|
|
||||||
Duration(seconds: context.read<SmartDoorBloc>().unlockRequest);
|
|
||||||
_animationController.reverse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_animationController.dispose();
|
_animationController.dispose();
|
||||||
@ -89,7 +100,7 @@ class _DoorLockButtonState extends State<DoorLockButton> with SingleTickerProvid
|
|||||||
// } else if (_animationController.status == AnimationStatus.reverse) {
|
// } else if (_animationController.status == AnimationStatus.reverse) {
|
||||||
// _animationController.forward();
|
// _animationController.forward();
|
||||||
// }
|
// }
|
||||||
if (context.read<SmartDoorBloc>().unlockRequest > 0) {
|
if (smartDoorModel.unlockRequest > 0) {
|
||||||
BlocProvider.of<SmartDoorBloc>(context)
|
BlocProvider.of<SmartDoorBloc>(context)
|
||||||
.add(UpdateLockEvent(value: smartDoorModel.normalOpenSwitch));
|
.add(UpdateLockEvent(value: smartDoorModel.normalOpenSwitch));
|
||||||
}
|
}
|
||||||
|
|||||||
45
lib/features/shared_widgets/success_dialog.dart
Normal file
45
lib/features/shared_widgets/success_dialog.dart
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
|
||||||
|
class SuccessDialog extends StatelessWidget {
|
||||||
|
final double dialogWidth;
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
const SuccessDialog(
|
||||||
|
{super.key, this.dialogWidth = 160, required this.message});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Dialog(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||||
|
child: Container(
|
||||||
|
width: dialogWidth,
|
||||||
|
height: 120,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.blackColor.withOpacity(0.7),
|
||||||
|
borderRadius: BorderRadius.circular(15),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.assetsSuccessWhite,
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
BodySmall(
|
||||||
|
text: message,
|
||||||
|
fontColor: ColorsManager.onPrimaryColor,
|
||||||
|
fontSize: FontSize.s16),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -733,6 +733,10 @@ class Assets {
|
|||||||
static const String playIcon = "assets/icons/play_ic.svg";
|
static const String playIcon = "assets/icons/play_ic.svg";
|
||||||
static const String gatewayIcon = "assets/icons/gateway_icon.svg";
|
static const String gatewayIcon = "assets/icons/gateway_icon.svg";
|
||||||
|
|
||||||
|
//assets/icons/success-white.svg
|
||||||
|
//assets for success white image
|
||||||
|
static const String assetsSuccessWhite ="assets/icons/success-white.svg";
|
||||||
|
|
||||||
/// Assets for assetsImagesAutomation
|
/// Assets for assetsImagesAutomation
|
||||||
/// assets/images/automation.jpg
|
/// assets/images/automation.jpg
|
||||||
static const String assetsImagesAutomation = "assets/images/automation.jpg";
|
static const String assetsImagesAutomation = "assets/images/automation.jpg";
|
||||||
@ -1029,4 +1033,5 @@ class Assets {
|
|||||||
|
|
||||||
static const String assetsPresenceState =
|
static const String assetsPresenceState =
|
||||||
"assets/icons/functions_icons/automation_functions/presence_state.svg";
|
"assets/icons/functions_icons/automation_functions/presence_state.svg";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,9 @@ import 'package:syncrow_app/firebase_options.dart';
|
|||||||
import 'package:syncrow_app/services/locator.dart';
|
import 'package:syncrow_app/services/locator.dart';
|
||||||
import 'package:syncrow_app/utils/bloc_observer.dart';
|
import 'package:syncrow_app/utils/bloc_observer.dart';
|
||||||
import 'package:syncrow_app/utils/helpers/localization_helpers.dart';
|
import 'package:syncrow_app/utils/helpers/localization_helpers.dart';
|
||||||
|
|
||||||
import 'my_app.dart';
|
import 'my_app.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
//to observe the state of the blocs in the output console
|
//to observe the state of the blocs in the output console
|
||||||
Bloc.observer = MyBlocObserver();
|
Bloc.observer = MyBlocObserver();
|
||||||
|
|||||||
@ -32,7 +32,6 @@ 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 {
|
||||||
|
|
||||||
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(),
|
||||||
@ -214,6 +213,7 @@ class DevicesAPI {
|
|||||||
"effectiveTime": effectiveTime,
|
"effectiveTime": effectiveTime,
|
||||||
"invalidTime": invalidTime,
|
"invalidTime": invalidTime,
|
||||||
};
|
};
|
||||||
|
print('createPassword =$body');
|
||||||
if (scheduleList != null) {
|
if (scheduleList != null) {
|
||||||
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,7 +68,6 @@ 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: [
|
||||||
@ -175,21 +174,6 @@ 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 }
|
||||||
|
|||||||
Reference in New Issue
Block a user