mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-16 18:16:21 +00:00
count_down_ac
This commit is contained in:
@ -1,4 +1,5 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
@ -55,7 +56,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
Future fetchUserInfo() async {
|
Future fetchUserInfo() async {
|
||||||
try {
|
try {
|
||||||
var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
var uuid =
|
||||||
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||||
user = await ProfileApi().fetchUserInfo(uuid);
|
user = await ProfileApi().fetchUserInfo(uuid);
|
||||||
emit(HomeUserInfoLoaded(user!)); // Emit state after fetching user info
|
emit(HomeUserInfoLoaded(user!)); // Emit state after fetching user info
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -123,7 +125,9 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var userUuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ?? '';
|
var userUuid =
|
||||||
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ??
|
||||||
|
'';
|
||||||
if (userUuid.isNotEmpty) {
|
if (userUuid.isNotEmpty) {
|
||||||
await OneSignal.login(userUuid);
|
await OneSignal.login(userUuid);
|
||||||
}
|
}
|
||||||
@ -219,7 +223,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
//////////////////////////////////////// API ////////////////////////////////////////
|
//////////////////////////////////////// API ////////////////////////////////////////
|
||||||
generateInvitation(SpaceModel unit) async {
|
generateInvitation(SpaceModel unit) async {
|
||||||
try {
|
try {
|
||||||
final invitationCode = await SpacesAPI.generateInvitationCode(unit.id, unit.community.uuid);
|
final invitationCode =
|
||||||
|
await SpacesAPI.generateInvitationCode(unit.id, unit.community.uuid);
|
||||||
if (invitationCode.isNotEmpty) {
|
if (invitationCode.isNotEmpty) {
|
||||||
Share.share('The invitation code is $invitationCode');
|
Share.share('The invitation code is $invitationCode');
|
||||||
CustomSnackBar.displaySnackBar(
|
CustomSnackBar.displaySnackBar(
|
||||||
@ -235,7 +240,9 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
Future<bool> joinAUnit(String code) async {
|
Future<bool> joinAUnit(String code) async {
|
||||||
try {
|
try {
|
||||||
var userUuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ?? '';
|
var userUuid =
|
||||||
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ??
|
||||||
|
'';
|
||||||
Map<String, String> body = {'inviteCode': code};
|
Map<String, String> body = {'inviteCode': code};
|
||||||
|
|
||||||
final success = await SpacesAPI.joinUnit(userUuid, body);
|
final success = await SpacesAPI.joinUnit(userUuid, body);
|
||||||
@ -271,7 +278,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
fetchRoomsByUnitId(SpaceModel space) async {
|
fetchRoomsByUnitId(SpaceModel space) async {
|
||||||
emitSafe(GetSpaceRoomsLoading());
|
emitSafe(GetSpaceRoomsLoading());
|
||||||
try {
|
try {
|
||||||
space.subspaces = await SpacesAPI.getSubSpaceBySpaceId(space.community.uuid, space.id);
|
space.subspaces =
|
||||||
|
await SpacesAPI.getSubSpaceBySpaceId(space.community.uuid, space.id);
|
||||||
} catch (failure) {
|
} catch (failure) {
|
||||||
emitSafe(GetSpaceRoomsError(failure.toString()));
|
emitSafe(GetSpaceRoomsError(failure.toString()));
|
||||||
return;
|
return;
|
||||||
@ -283,6 +291,28 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activationCode(activationCode) async {
|
||||||
|
try {
|
||||||
|
emitSafe(GetSpaceRoomsLoading());
|
||||||
|
var uuid =
|
||||||
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||||
|
var res = await SpacesAPI.activationCodeSpace(
|
||||||
|
activationCode: activationCode, userUuid: uuid);
|
||||||
|
if (res['success'] == true) {
|
||||||
|
fetchUserInfo();
|
||||||
|
fetchUnitsByUserId();
|
||||||
|
}
|
||||||
|
emitSafe(GetSpacesSuccess(spaces!));
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final errorMessage = e.response?.data['error']['message'];
|
||||||
|
emitSafe(ActivationError(errMessage: errorMessage));
|
||||||
|
return errorMessage;
|
||||||
|
} catch (e) {
|
||||||
|
emitSafe(ActivationError(errMessage: e.toString()));
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////// Nav ///////////////////////////////////////
|
/////////////////////////////////////// Nav ///////////////////////////////////////
|
||||||
|
|
||||||
static int pageIndex = 0;
|
static int pageIndex = 0;
|
||||||
@ -353,7 +383,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
size: 32,
|
size: 32,
|
||||||
),
|
),
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
foregroundColor:
|
||||||
|
WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pushNamed(
|
Navigator.pushNamed(
|
||||||
@ -374,7 +405,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
NavigationService.navigatorKey.currentContext!
|
NavigationService.navigatorKey.currentContext!
|
||||||
.read<SmartSceneSelectBloc>()
|
.read<SmartSceneSelectBloc>()
|
||||||
.add(const SmartSceneClearEvent());
|
.add(const SmartSceneClearEvent());
|
||||||
BlocProvider.of<EffectPeriodBloc>(NavigationService.navigatorKey.currentState!.context)
|
BlocProvider.of<EffectPeriodBloc>(
|
||||||
|
NavigationService.navigatorKey.currentState!.context)
|
||||||
.add(ResetEffectivePeriod());
|
.add(ResetEffectivePeriod());
|
||||||
NavigationService.navigatorKey.currentContext!
|
NavigationService.navigatorKey.currentContext!
|
||||||
.read<CreateSceneBloc>()
|
.read<CreateSceneBloc>()
|
||||||
@ -447,7 +479,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
void updateDevice(String deviceId) async {
|
void updateDevice(String deviceId) async {
|
||||||
try {
|
try {
|
||||||
final response = await DevicesAPI.firmwareDevice(deviceId: deviceId, firmwareVersion: '0');
|
final response = await DevicesAPI.firmwareDevice(
|
||||||
|
deviceId: deviceId, firmwareVersion: '0');
|
||||||
if (response['success'] ?? false) {
|
if (response['success'] ?? false) {
|
||||||
CustomSnackBar.displaySnackBar('No updates available');
|
CustomSnackBar.displaySnackBar('No updates available');
|
||||||
}
|
}
|
||||||
@ -455,7 +488,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BottomNavigationBarItem defaultBottomNavBarItem({required String icon, required String label}) {
|
BottomNavigationBarItem defaultBottomNavBarItem(
|
||||||
|
{required String icon, required String label}) {
|
||||||
return BottomNavigationBarItem(
|
return BottomNavigationBarItem(
|
||||||
icon: SvgPicture.asset(icon),
|
icon: SvgPicture.asset(icon),
|
||||||
activeIcon: SvgPicture.asset(
|
activeIcon: SvgPicture.asset(
|
||||||
|
@ -32,6 +32,12 @@ class GetSpacesError extends HomeError {
|
|||||||
//get rooms
|
//get rooms
|
||||||
class GetSpaceRoomsLoading extends HomeLoading {}
|
class GetSpaceRoomsLoading extends HomeLoading {}
|
||||||
|
|
||||||
|
class ActivationError extends HomeLoading {
|
||||||
|
final String errMessage;
|
||||||
|
|
||||||
|
ActivationError({this.errMessage = ''});
|
||||||
|
}
|
||||||
|
|
||||||
class GetSpaceRoomsSuccess extends HomeSuccess {
|
class GetSpaceRoomsSuccess extends HomeSuccess {
|
||||||
final List<SubSpaceModel> rooms;
|
final List<SubSpaceModel> rooms;
|
||||||
|
|
||||||
@ -58,6 +64,7 @@ class RoomSelected extends HomeState {
|
|||||||
class RoomUnSelected extends HomeState {}
|
class RoomUnSelected extends HomeState {}
|
||||||
|
|
||||||
class NavChangePage extends HomeState {}
|
class NavChangePage extends HomeState {}
|
||||||
|
|
||||||
// Define new state classes
|
// Define new state classes
|
||||||
class HomeUserInfoLoaded extends HomeState {
|
class HomeUserInfoLoaded extends HomeState {
|
||||||
final UserModel user;
|
final UserModel user;
|
||||||
|
@ -204,7 +204,7 @@ class AuthCubit extends Cubit<AuthState> {
|
|||||||
const FlutterSecureStorage().write(
|
const FlutterSecureStorage().write(
|
||||||
key: UserModel.userUuidKey,
|
key: UserModel.userUuidKey,
|
||||||
value: Token.decodeToken(token.accessToken)['uuid'].toString());
|
value: Token.decodeToken(token.accessToken)['uuid'].toString());
|
||||||
|
|
||||||
user = UserModel.fromToken(token);
|
user = UserModel.fromToken(token);
|
||||||
emailController.clear();
|
emailController.clear();
|
||||||
passwordController.clear();
|
passwordController.clear();
|
||||||
|
@ -1,8 +1,39 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:syncrow_app/features/auth/model/token.dart';
|
import 'package:syncrow_app/features/auth/model/token.dart';
|
||||||
|
|
||||||
|
class Role {
|
||||||
|
final String uuid;
|
||||||
|
final DateTime createdAt;
|
||||||
|
final DateTime updatedAt;
|
||||||
|
final String type;
|
||||||
|
|
||||||
|
Role({
|
||||||
|
required this.uuid,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
required this.type,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Role.fromJson(Map<String, dynamic> json) {
|
||||||
|
return Role(
|
||||||
|
uuid: json['uuid'],
|
||||||
|
createdAt: DateTime.parse(json['createdAt']),
|
||||||
|
updatedAt: DateTime.parse(json['updatedAt']),
|
||||||
|
type: json['type'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'uuid': uuid,
|
||||||
|
'createdAt': createdAt.toIso8601String(),
|
||||||
|
'updatedAt': updatedAt.toIso8601String(),
|
||||||
|
'type': type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class UserModel {
|
class UserModel {
|
||||||
static String userUuidKey = 'userUuid';
|
static String userUuidKey = 'userUuid';
|
||||||
final String? uuid;
|
final String? uuid;
|
||||||
@ -16,6 +47,7 @@ class UserModel {
|
|||||||
final String? timeZone;
|
final String? timeZone;
|
||||||
final String? regionUuid;
|
final String? regionUuid;
|
||||||
final bool? isAgreementAccepted;
|
final bool? isAgreementAccepted;
|
||||||
|
final Role? role;
|
||||||
|
|
||||||
UserModel({
|
UserModel({
|
||||||
required this.uuid,
|
required this.uuid,
|
||||||
@ -27,8 +59,9 @@ class UserModel {
|
|||||||
required this.isEmailVerified,
|
required this.isEmailVerified,
|
||||||
required this.regionUuid,
|
required this.regionUuid,
|
||||||
required this.isAgreementAccepted,
|
required this.isAgreementAccepted,
|
||||||
required this.regionName, // Add this line
|
required this.regionName,
|
||||||
required this.timeZone, // Add this line
|
required this.timeZone,
|
||||||
|
required this.role,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory UserModel.fromJson(Map<String, dynamic> json) {
|
factory UserModel.fromJson(Map<String, dynamic> json) {
|
||||||
@ -41,13 +74,13 @@ class UserModel {
|
|||||||
phoneNumber: json['phoneNumber'],
|
phoneNumber: json['phoneNumber'],
|
||||||
isEmailVerified: json['isEmailVerified'],
|
isEmailVerified: json['isEmailVerified'],
|
||||||
isAgreementAccepted: json['isAgreementAccepted'],
|
isAgreementAccepted: json['isAgreementAccepted'],
|
||||||
regionName: json['region']?['regionName'], // Extract regionName
|
regionName: json['region']?['regionName'],
|
||||||
timeZone: json['timeZone']?['timeZoneOffset'], // Extract regionName
|
timeZone: json['timeZone']?['timeZoneOffset'],
|
||||||
regionUuid: json['region']?['uuid'],
|
regionUuid: json['region']?['uuid'],
|
||||||
|
role: json['role'] != null ? Role.fromJson(json['role']) : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
//uuid to json
|
|
||||||
//from token
|
|
||||||
factory UserModel.fromToken(Token token) {
|
factory UserModel.fromToken(Token token) {
|
||||||
Map<String, dynamic> tempJson = Token.decodeToken(token.accessToken);
|
Map<String, dynamic> tempJson = Token.decodeToken(token.accessToken);
|
||||||
return UserModel(
|
return UserModel(
|
||||||
@ -62,6 +95,7 @@ class UserModel {
|
|||||||
regionUuid: null,
|
regionUuid: null,
|
||||||
regionName: tempJson['region']?['regionName'],
|
regionName: tempJson['region']?['regionName'],
|
||||||
timeZone: tempJson['timezone']?['timeZoneOffset'],
|
timeZone: tempJson['timezone']?['timeZoneOffset'],
|
||||||
|
role: tempJson['role'] != null ? Role.fromJson(tempJson['role']) : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,14 +108,18 @@ class UserModel {
|
|||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
return {
|
||||||
'id': uuid,
|
'uuid': uuid,
|
||||||
'email': email,
|
'email': email,
|
||||||
'lastName': lastName,
|
|
||||||
'firstName': firstName,
|
'firstName': firstName,
|
||||||
'photoUrl': profilePicture,
|
'lastName': lastName,
|
||||||
|
'profilePicture': profilePicture != null ? base64.encode(profilePicture!) : null,
|
||||||
'phoneNumber': phoneNumber,
|
'phoneNumber': phoneNumber,
|
||||||
'isEmailVerified': isEmailVerified,
|
'isEmailVerified': isEmailVerified,
|
||||||
|
'regionUuid': regionUuid,
|
||||||
'isAgreementAccepted': isAgreementAccepted,
|
'isAgreementAccepted': isAgreementAccepted,
|
||||||
|
'regionName': regionName,
|
||||||
|
'timeZone': timeZone,
|
||||||
|
'role': role?.toJson(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
|||||||
class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
||||||
final String acId;
|
final String acId;
|
||||||
AcStatusModel deviceStatus = AcStatusModel(
|
AcStatusModel deviceStatus = AcStatusModel(
|
||||||
|
countdown1: 0,
|
||||||
uuid: '',
|
uuid: '',
|
||||||
acSwitch: true,
|
acSwitch: true,
|
||||||
modeString: 'hot',
|
modeString: 'hot',
|
||||||
@ -41,6 +42,12 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
on<IncreaseAllTemp>(_increaseAllTemp);
|
on<IncreaseAllTemp>(_increaseAllTemp);
|
||||||
on<DecreaseAllTemp>(_decreaseAllTemp);
|
on<DecreaseAllTemp>(_decreaseAllTemp);
|
||||||
on<AcUpdated>(_onAcUpdated);
|
on<AcUpdated>(_onAcUpdated);
|
||||||
|
on<OnClose>(_onClose);
|
||||||
|
on<GetCounterEvent>(_getCounterValue);
|
||||||
|
on<SetCounterValue>(_setCounterValue);
|
||||||
|
on<TickTimer>(_onTickTimer);
|
||||||
|
|
||||||
|
// on<SetTimeOutValue>(_setTimeOutAlarm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchAcsStatus(AcsInitial event, Emitter<AcsState> emit) async {
|
void _fetchAcsStatus(AcsInitial event, Emitter<AcsState> emit) async {
|
||||||
@ -61,7 +68,8 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
}
|
}
|
||||||
deviceStatus = AcStatusModel.fromJson(response['productUuid'], statusModelList);
|
deviceStatus =
|
||||||
|
AcStatusModel.fromJson(response['productUuid'], statusModelList);
|
||||||
emit(GetAcStatusState(acStatusModel: deviceStatus));
|
emit(GetAcStatusState(acStatusModel: deviceStatus));
|
||||||
Future.delayed(const Duration(milliseconds: 500));
|
Future.delayed(const Duration(milliseconds: 500));
|
||||||
// _listenToChanges();
|
// _listenToChanges();
|
||||||
@ -74,18 +82,22 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
|
|
||||||
_listenToChanges() {
|
_listenToChanges() {
|
||||||
try {
|
try {
|
||||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$acId');
|
DatabaseReference ref =
|
||||||
|
FirebaseDatabase.instance.ref('device-status/$acId');
|
||||||
Stream<DatabaseEvent> stream = ref.onValue;
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) {
|
stream.listen((DatabaseEvent event) {
|
||||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
Map<dynamic, dynamic> usersMap =
|
||||||
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
List<StatusModel> statusList = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
usersMap['status'].forEach((element) {
|
||||||
statusList.add(StatusModel(code: element['code'], value: element['value']));
|
statusList
|
||||||
|
.add(StatusModel(code: element['code'], value: element['value']));
|
||||||
});
|
});
|
||||||
|
|
||||||
deviceStatus = AcStatusModel.fromJson(usersMap['productUuid'], statusList);
|
deviceStatus =
|
||||||
|
AcStatusModel.fromJson(usersMap['productUuid'], statusList);
|
||||||
add(AcUpdated());
|
add(AcUpdated());
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
@ -102,12 +114,14 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', 'AC');
|
HomeCubit.getInstance().selectedSpace?.id ?? '', 'AC');
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
for (int i = 0; i < devicesList.length; i++) {
|
||||||
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
var response =
|
||||||
|
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
||||||
List<StatusModel> statusModelList = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
}
|
}
|
||||||
deviceStatusList.add(AcStatusModel.fromJson(response['productUuid'], statusModelList));
|
deviceStatusList.add(
|
||||||
|
AcStatusModel.fromJson(response['productUuid'], statusModelList));
|
||||||
}
|
}
|
||||||
_setAllAcsTempsAndSwitches();
|
_setAllAcsTempsAndSwitches();
|
||||||
}
|
}
|
||||||
@ -129,7 +143,8 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
emit(AcModifyingState(acStatusModel: deviceStatus));
|
emit(AcModifyingState(acStatusModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'switch', value: acSwitchValue);
|
await _runDeBouncerForOneDevice(
|
||||||
|
deviceId: event.deviceId, code: 'switch', value: acSwitchValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeAllAcSwitch(ChangeAllSwitch event, Emitter<AcsState> emit) async {
|
void _changeAllAcSwitch(ChangeAllSwitch event, Emitter<AcsState> emit) async {
|
||||||
@ -190,7 +205,8 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
deviceStatus.childLock = lockValue;
|
deviceStatus.childLock = lockValue;
|
||||||
emit(AcModifyingState(acStatusModel: deviceStatus));
|
emit(AcModifyingState(acStatusModel: deviceStatus));
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(deviceId: acId, code: 'child_lock', value: lockValue);
|
await _runDeBouncerForOneDevice(
|
||||||
|
deviceId: acId, code: 'child_lock', value: lockValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _increaseCoolTo(IncreaseCoolToTemp event, Emitter<AcsState> emit) async {
|
void _increaseCoolTo(IncreaseCoolToTemp event, Emitter<AcsState> emit) async {
|
||||||
@ -218,7 +234,8 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
emit(AcModifyingState(acStatusModel: deviceStatus));
|
emit(AcModifyingState(acStatusModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'temp_set', value: value);
|
await _runDeBouncerForOneDevice(
|
||||||
|
deviceId: event.deviceId, code: 'temp_set', value: value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _decreaseCoolTo(DecreaseCoolToTemp event, Emitter<AcsState> emit) async {
|
void _decreaseCoolTo(DecreaseCoolToTemp event, Emitter<AcsState> emit) async {
|
||||||
@ -246,7 +263,8 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
emit(AcModifyingState(acStatusModel: deviceStatus));
|
emit(AcModifyingState(acStatusModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'temp_set', value: value);
|
await _runDeBouncerForOneDevice(
|
||||||
|
deviceId: event.deviceId, code: 'temp_set', value: value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeAcMode(ChangeAcMode event, Emitter<AcsState> emit) async {
|
void _changeAcMode(ChangeAcMode event, Emitter<AcsState> emit) async {
|
||||||
@ -268,7 +286,9 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(
|
await _runDeBouncerForOneDevice(
|
||||||
deviceId: event.deviceId, code: 'mode', value: getACModeString(tempMode));
|
deviceId: event.deviceId,
|
||||||
|
code: 'mode',
|
||||||
|
value: getACModeString(tempMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFanSpeed(ChangeFanSpeed event, Emitter<AcsState> emit) async {
|
void _changeFanSpeed(ChangeFanSpeed event, Emitter<AcsState> emit) async {
|
||||||
@ -281,19 +301,23 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
for (AcStatusModel ac in deviceStatusList) {
|
for (AcStatusModel ac in deviceStatusList) {
|
||||||
if (ac.uuid == event.productId) {
|
if (ac.uuid == event.productId) {
|
||||||
ac.fanSpeedsString = getNextFanSpeedKey(fanSpeed);
|
ac.fanSpeedsString = getNextFanSpeedKey(fanSpeed);
|
||||||
ac.acFanSpeed = AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
|
ac.acFanSpeed =
|
||||||
|
AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_emitAcsStatus(emit);
|
_emitAcsStatus(emit);
|
||||||
} else {
|
} else {
|
||||||
emit(AcChangeLoading(acStatusModel: deviceStatus));
|
emit(AcChangeLoading(acStatusModel: deviceStatus));
|
||||||
deviceStatus.fanSpeedsString = getNextFanSpeedKey(fanSpeed);
|
deviceStatus.fanSpeedsString = getNextFanSpeedKey(fanSpeed);
|
||||||
deviceStatus.acFanSpeed = AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
|
deviceStatus.acFanSpeed =
|
||||||
|
AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
|
||||||
emit(AcModifyingState(acStatusModel: deviceStatus));
|
emit(AcModifyingState(acStatusModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(
|
await _runDeBouncerForOneDevice(
|
||||||
deviceId: event.deviceId, code: 'level', value: getNextFanSpeedKey(fanSpeed));
|
deviceId: event.deviceId,
|
||||||
|
code: 'level',
|
||||||
|
value: getNextFanSpeedKey(fanSpeed));
|
||||||
}
|
}
|
||||||
|
|
||||||
String getACModeString(TempModes value) {
|
String getACModeString(TempModes value) {
|
||||||
@ -338,7 +362,8 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
for (int i = 0; i < deviceStatusList.length; i++) {
|
for (int i = 0; i < deviceStatusList.length; i++) {
|
||||||
try {
|
try {
|
||||||
await DevicesAPI.controlDevice(
|
await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: devicesList[i].uuid, code: code, value: value),
|
DeviceControlModel(
|
||||||
|
deviceId: devicesList[i].uuid, code: code, value: value),
|
||||||
devicesList[i].uuid ?? '');
|
devicesList[i].uuid ?? '');
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
@ -360,7 +385,10 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
_timer = Timer(const Duration(seconds: 1), () async {
|
_timer = Timer(const Duration(seconds: 1), () async {
|
||||||
try {
|
try {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: allAcsPage ? deviceId : acId, code: code, value: value),
|
DeviceControlModel(
|
||||||
|
deviceId: allAcsPage ? deviceId : acId,
|
||||||
|
code: code,
|
||||||
|
value: value),
|
||||||
allAcsPage ? deviceId : acId);
|
allAcsPage ? deviceId : acId);
|
||||||
|
|
||||||
if (!response['success']) {
|
if (!response['success']) {
|
||||||
@ -377,7 +405,8 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
if (value >= 20 && value <= 30) {
|
if (value >= 20 && value <= 30) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
emit(const AcsFailedState(errorMessage: 'The temperature must be between 20 and 30'));
|
emit(const AcsFailedState(
|
||||||
|
errorMessage: 'The temperature must be between 20 and 30'));
|
||||||
emit(GetAllAcsStatusState(
|
emit(GetAllAcsStatusState(
|
||||||
allAcsStatues: deviceStatusList,
|
allAcsStatues: deviceStatusList,
|
||||||
allAcs: devicesList,
|
allAcs: devicesList,
|
||||||
@ -396,4 +425,90 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
allTempSame: allTempSame,
|
allTempSame: allTempSame,
|
||||||
temp: globalTemp));
|
temp: globalTemp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _setCounterValue(SetCounterValue event, Emitter<AcsState> emit) async {
|
||||||
|
emit(AcsLoadingState());
|
||||||
|
int seconds = 0;
|
||||||
|
try {
|
||||||
|
seconds = event.seconds;
|
||||||
|
final response = await DevicesAPI.controlDevice(
|
||||||
|
DeviceControlModel(
|
||||||
|
deviceId: acId, code: 'countdown_time', value: event.duration),
|
||||||
|
acId);
|
||||||
|
|
||||||
|
if (response['success'] ?? false) {
|
||||||
|
deviceStatus.countdown1 = seconds;
|
||||||
|
|
||||||
|
emit(UpdateTimerState(seconds: deviceStatus.countdown1));
|
||||||
|
} else {
|
||||||
|
emit(const AcsFailedState(errorMessage: 'Something went wrong'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(AcsFailedState(errorMessage: e.toString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (seconds > 0) {
|
||||||
|
_onStartTimer(seconds);
|
||||||
|
} else {
|
||||||
|
_timer?.cancel();
|
||||||
|
emit(TimerRunComplete());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _getCounterValue(GetCounterEvent event, Emitter<AcsState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(AcsLoadingState());
|
||||||
|
var response = await DevicesAPI.getDeviceStatus(acId);
|
||||||
|
List<StatusModel> statusModelList = [];
|
||||||
|
for (var status in response['status']) {
|
||||||
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
|
}
|
||||||
|
deviceStatus =
|
||||||
|
AcStatusModel.fromJson(response['productUuid'], statusModelList);
|
||||||
|
|
||||||
|
if (event.deviceCode == 'countdown_time') {
|
||||||
|
deviceStatus.countdown1 > 0
|
||||||
|
? _onStartTimer(deviceStatus.countdown1)
|
||||||
|
: emit(UpdateTimerState(seconds: deviceStatus.countdown1));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(AcsFailedState(errorMessage: e.toString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onStartTimer(int seconds) {
|
||||||
|
_timer?.cancel(); // Cancel any existing timer
|
||||||
|
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||||
|
final remainingTime = seconds - timer.tick;
|
||||||
|
if (remainingTime > 0) {
|
||||||
|
if (!isClosed) {
|
||||||
|
// Check if the Bloc is still active
|
||||||
|
add(TickTimer(remainingTime: remainingTime));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_timer?.cancel();
|
||||||
|
if (!isClosed) {
|
||||||
|
emit(TimerRunComplete());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onTickTimer(TickTimer event, Emitter<AcsState> emit) {
|
||||||
|
if (!isClosed) {
|
||||||
|
// Check if the Bloc is still active
|
||||||
|
if (event.remainingTime > 0) {
|
||||||
|
emit(TimerRunInProgress(event.remainingTime));
|
||||||
|
} else {
|
||||||
|
_timer?.cancel();
|
||||||
|
emit(TimerRunComplete());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onClose(OnClose event, Emitter<AcsState> emit) {
|
||||||
|
_timer?.cancel(); // Cancel the timer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,8 @@ class AcSwitch extends AcsEvent {
|
|||||||
final bool acSwitch;
|
final bool acSwitch;
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
final String productId;
|
final String productId;
|
||||||
const AcSwitch({required this.acSwitch, this.deviceId = '', this.productId = ''});
|
const AcSwitch(
|
||||||
|
{required this.acSwitch, this.deviceId = '', this.productId = ''});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [acSwitch, deviceId, productId];
|
List<Object> get props => [acSwitch, deviceId, productId];
|
||||||
@ -35,7 +36,8 @@ class IncreaseCoolToTemp extends AcsEvent {
|
|||||||
final double value;
|
final double value;
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
final String productId;
|
final String productId;
|
||||||
const IncreaseCoolToTemp({required this.value, this.deviceId = '', this.productId = ''});
|
const IncreaseCoolToTemp(
|
||||||
|
{required this.value, this.deviceId = '', this.productId = ''});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [value, deviceId];
|
List<Object> get props => [value, deviceId];
|
||||||
@ -46,7 +48,8 @@ class DecreaseCoolToTemp extends AcsEvent {
|
|||||||
final String deviceId;
|
final String deviceId;
|
||||||
final String productId;
|
final String productId;
|
||||||
|
|
||||||
const DecreaseCoolToTemp({required this.value, this.deviceId = '', this.productId = ''});
|
const DecreaseCoolToTemp(
|
||||||
|
{required this.value, this.deviceId = '', this.productId = ''});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [value, deviceId];
|
List<Object> get props => [value, deviceId];
|
||||||
@ -56,7 +59,8 @@ class ChangeAcMode extends AcsEvent {
|
|||||||
final TempModes tempModes;
|
final TempModes tempModes;
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
final String productId;
|
final String productId;
|
||||||
const ChangeAcMode({required this.tempModes, this.deviceId = '', this.productId = ''});
|
const ChangeAcMode(
|
||||||
|
{required this.tempModes, this.deviceId = '', this.productId = ''});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [tempModes, deviceId, productId];
|
List<Object> get props => [tempModes, deviceId, productId];
|
||||||
@ -67,7 +71,8 @@ class ChangeFanSpeed extends AcsEvent {
|
|||||||
final String deviceId;
|
final String deviceId;
|
||||||
final String productId;
|
final String productId;
|
||||||
|
|
||||||
const ChangeFanSpeed({required this.fanSpeeds, this.deviceId = '', this.productId = ''});
|
const ChangeFanSpeed(
|
||||||
|
{required this.fanSpeeds, this.deviceId = '', this.productId = ''});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [fanSpeeds, deviceId, productId];
|
List<Object> get props => [fanSpeeds, deviceId, productId];
|
||||||
@ -104,3 +109,52 @@ class DecreaseAllTemp extends AcsEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [value];
|
List<Object> get props => [value];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SetCounterValue extends AcsEvent {
|
||||||
|
final int duration;
|
||||||
|
final String deviceCode;
|
||||||
|
final int seconds;
|
||||||
|
const SetCounterValue(
|
||||||
|
{required this.duration,
|
||||||
|
required this.deviceCode,
|
||||||
|
required this.seconds});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [duration, deviceCode, seconds];
|
||||||
|
}
|
||||||
|
|
||||||
|
class SetTimeOutValue extends AcsEvent {
|
||||||
|
final Duration duration;
|
||||||
|
final String deviceCode;
|
||||||
|
const SetTimeOutValue({required this.duration, required this.deviceCode});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [duration, deviceCode];
|
||||||
|
}
|
||||||
|
|
||||||
|
class StartTimer extends AcsEvent {
|
||||||
|
final int duration;
|
||||||
|
|
||||||
|
const StartTimer(this.duration);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [duration];
|
||||||
|
}
|
||||||
|
|
||||||
|
class TickTimer extends AcsEvent {
|
||||||
|
final int remainingTime;
|
||||||
|
|
||||||
|
const TickTimer({required this.remainingTime});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [remainingTime];
|
||||||
|
}
|
||||||
|
|
||||||
|
class StopTimer extends AcsEvent {}
|
||||||
|
|
||||||
|
class GetCounterEvent extends AcsEvent {
|
||||||
|
final String deviceCode;
|
||||||
|
const GetCounterEvent({required this.deviceCode});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceCode];
|
||||||
|
}
|
||||||
|
|
||||||
|
class OnClose extends AcsEvent {}
|
||||||
|
@ -63,3 +63,22 @@ class AcsFailedState extends AcsState {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [errorMessage];
|
List<Object> get props => [errorMessage];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class UpdateTimerState extends AcsState {
|
||||||
|
final int seconds;
|
||||||
|
const UpdateTimerState({required this.seconds});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [seconds];
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimerRunInProgress extends AcsState {
|
||||||
|
final int remainingTime;
|
||||||
|
|
||||||
|
const TimerRunInProgress(this.remainingTime);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [remainingTime];
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimerRunComplete extends AcsState {}
|
||||||
|
@ -65,7 +65,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
batteryPercentage: 0,
|
batteryPercentage: 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
void _fetchStatus(GarageDoorInitial event, Emitter<GarageDoorSensorState> emit) async {
|
void _fetchStatus(
|
||||||
|
GarageDoorInitial event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
emit(GarageDoorLoadingState());
|
emit(GarageDoorLoadingState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(GDId);
|
var response = await DevicesAPI.getDeviceStatus(GDId);
|
||||||
@ -113,8 +114,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _toggleClosingReminder(
|
void _toggleClosingReminder(ToggleClosingReminderEvent event,
|
||||||
ToggleClosingReminderEvent event, Emitter<GarageDoorSensorState> emit) async {
|
Emitter<GarageDoorSensorState> emit) async {
|
||||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||||
try {
|
try {
|
||||||
closingReminder = event.isClosingReminderEnabled;
|
closingReminder = event.isClosingReminderEnabled;
|
||||||
@ -132,7 +133,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _toggleDoorAlarm(ToggleDoorAlarmEvent event, Emitter<GarageDoorSensorState> emit) async {
|
void _toggleDoorAlarm(
|
||||||
|
ToggleDoorAlarmEvent event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||||
try {
|
try {
|
||||||
doorAlarm = event.isDoorAlarmEnabled;
|
doorAlarm = event.isDoorAlarmEnabled;
|
||||||
@ -150,7 +152,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []);
|
DeviceReport recordGroups =
|
||||||
|
DeviceReport(startTime: '0', endTime: '0', data: []);
|
||||||
|
|
||||||
Future<void> fetchLogsForLastMonth(
|
Future<void> fetchLogsForLastMonth(
|
||||||
ReportLogsInitial event, Emitter<GarageDoorSensorState> emit) async {
|
ReportLogsInitial event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
@ -179,14 +182,16 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
|
|
||||||
_listenToChanges() {
|
_listenToChanges() {
|
||||||
try {
|
try {
|
||||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$GDId');
|
DatabaseReference ref =
|
||||||
|
FirebaseDatabase.instance.ref('device-status/$GDId');
|
||||||
Stream<DatabaseEvent> stream = ref.onValue;
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
stream.listen((DatabaseEvent event) async {
|
||||||
if (_timer != null) {
|
if (_timer != null) {
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
}
|
}
|
||||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
Map<dynamic, dynamic> usersMap =
|
||||||
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
List<StatusModel> statusList = [];
|
List<StatusModel> statusList = [];
|
||||||
usersMap['status'].forEach((element) {
|
usersMap['status'].forEach((element) {
|
||||||
statusList.add(StatusModel(code: element['code'], value: true));
|
statusList.add(StatusModel(code: element['code'], value: true));
|
||||||
@ -261,7 +266,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
deviceId: GDId,
|
deviceId: GDId,
|
||||||
);
|
);
|
||||||
List<dynamic> jsonData = response;
|
List<dynamic> jsonData = response;
|
||||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
listSchedule =
|
||||||
|
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
emit(UpdateState(garageSensor: deviceStatus));
|
emit(UpdateState(garageSensor: deviceStatus));
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
@ -272,12 +278,13 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
|
|
||||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
if (dateTime == null) return null;
|
if (dateTime == null) return null;
|
||||||
DateTime dateTimeWithoutSeconds =
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future toggleChange(ToggleScheduleEvent event, Emitter<GarageDoorSensorState> emit) async {
|
Future toggleChange(
|
||||||
|
ToggleScheduleEvent event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(GarageDoorLoadingState());
|
emit(GarageDoorLoadingState());
|
||||||
final response = await DevicesAPI.changeSchedule(
|
final response = await DevicesAPI.changeSchedule(
|
||||||
@ -295,7 +302,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future deleteSchedule(DeleteScheduleEvent event, Emitter<GarageDoorSensorState> emit) async {
|
Future deleteSchedule(
|
||||||
|
DeleteScheduleEvent event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(GarageDoorLoadingState());
|
emit(GarageDoorLoadingState());
|
||||||
final response = await DevicesAPI.deleteSchedule(
|
final response = await DevicesAPI.deleteSchedule(
|
||||||
@ -314,13 +322,15 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<GarageDoorSensorState> emit) {
|
void toggleSelectedIndex(
|
||||||
|
ToggleSelectedEvent event, Emitter<GarageDoorSensorState> emit) {
|
||||||
emit(GarageDoorLoadingState());
|
emit(GarageDoorLoadingState());
|
||||||
selectedTabIndex = event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<GarageDoorSensorState> emit) {
|
void toggleCreateSchedule(
|
||||||
|
ToggleCreateScheduleEvent event, Emitter<GarageDoorSensorState> emit) {
|
||||||
emit(GarageDoorLoadingState());
|
emit(GarageDoorLoadingState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
@ -337,13 +347,16 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
|
|
||||||
int secondSelected = 0;
|
int secondSelected = 0;
|
||||||
bool toggleDoor = false;
|
bool toggleDoor = false;
|
||||||
Future<void> selectSeconds(SelectSecondsEvent event, Emitter<GarageDoorSensorState> emit) async {
|
Future<void> selectSeconds(
|
||||||
|
SelectSecondsEvent event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(GarageDoorLoadingState());
|
emit(GarageDoorLoadingState());
|
||||||
secondSelected = event.seconds;
|
secondSelected = event.seconds;
|
||||||
|
|
||||||
await DevicesAPI.controlDevice(
|
await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: GDId, code: 'tr_timecon', value: secondSelected), GDId);
|
DeviceControlModel(
|
||||||
|
deviceId: GDId, code: 'tr_timecon', value: secondSelected),
|
||||||
|
GDId);
|
||||||
emit(UpdateState(garageSensor: deviceStatus));
|
emit(UpdateState(garageSensor: deviceStatus));
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
@ -352,12 +365,15 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
openCloseGarageDoor(ToggleDoorEvent event, Emitter<GarageDoorSensorState> emit) async {
|
openCloseGarageDoor(
|
||||||
|
ToggleDoorEvent event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
emit(GarageDoorLoadingState());
|
emit(GarageDoorLoadingState());
|
||||||
try {
|
try {
|
||||||
toggleDoor = !event.toggle;
|
toggleDoor = !event.toggle;
|
||||||
await DevicesAPI.controlDevice(
|
await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: GDId, code: 'switch_1', value: toggleDoor), GDId);
|
DeviceControlModel(
|
||||||
|
deviceId: GDId, code: 'switch_1', value: toggleDoor),
|
||||||
|
GDId);
|
||||||
add(const GarageDoorInitial());
|
add(const GarageDoorInitial());
|
||||||
emit(UpdateState(garageSensor: deviceStatus));
|
emit(UpdateState(garageSensor: deviceStatus));
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
@ -367,13 +383,16 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setCounterValue(SetCounterValue event, Emitter<GarageDoorSensorState> emit) async {
|
void _setCounterValue(
|
||||||
|
SetCounterValue event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try {
|
try {
|
||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: GDId, code: 'countdown_1', value: seconds), GDId);
|
DeviceControlModel(
|
||||||
|
deviceId: GDId, code: 'countdown_1', value: seconds),
|
||||||
|
GDId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
if (response['success'] ?? false) {
|
||||||
deviceStatus.countdown1 = seconds;
|
deviceStatus.countdown1 = seconds;
|
||||||
@ -393,7 +412,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getCounterValue(GetCounterEvent event, Emitter<GarageDoorSensorState> emit) async {
|
void _getCounterValue(
|
||||||
|
GetCounterEvent event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(GDId);
|
var response = await DevicesAPI.getDeviceStatus(GDId);
|
||||||
@ -434,7 +454,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
List<GroupGarageModel> groupList = [];
|
List<GroupGarageModel> groupList = [];
|
||||||
bool allSwitchesOn = true;
|
bool allSwitchesOn = true;
|
||||||
|
|
||||||
void _fetchWizardStatus(InitialWizardEvent event, Emitter<GarageDoorSensorState> emit) async {
|
void _fetchWizardStatus(
|
||||||
|
InitialWizardEvent event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
devicesList = [];
|
devicesList = [];
|
||||||
@ -444,7 +465,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', 'GD');
|
HomeCubit.getInstance().selectedSpace?.id ?? '', 'GD');
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
for (int i = 0; i < devicesList.length; i++) {
|
||||||
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
var response =
|
||||||
|
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
||||||
List<StatusModel> statusModelList = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
@ -473,7 +495,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _groupAllOn(GroupAllOnEvent event, Emitter<GarageDoorSensorState> emit) async {
|
void _groupAllOn(
|
||||||
|
GroupAllOnEvent event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||||
try {
|
try {
|
||||||
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
|
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
|
||||||
@ -485,7 +508,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
emit(UpdateGroupState(garageList: groupList, allSwitches: true));
|
emit(UpdateGroupState(garageList: groupList, allSwitches: true));
|
||||||
|
|
||||||
// Get a list of all device IDs
|
// Get a list of all device IDs
|
||||||
List<String> allDeviceIds = groupList.map((device) => device.deviceId).toList();
|
List<String> allDeviceIds =
|
||||||
|
groupList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
// First call for switch_1
|
// First call for switch_1
|
||||||
final response = await DevicesAPI.deviceBatchController(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
@ -505,7 +529,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _groupAllOff(GroupAllOffEvent event, Emitter<GarageDoorSensorState> emit) async {
|
void _groupAllOff(
|
||||||
|
GroupAllOffEvent event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||||
try {
|
try {
|
||||||
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
|
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
|
||||||
@ -517,7 +542,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
emit(UpdateGroupState(garageList: groupList, allSwitches: false));
|
emit(UpdateGroupState(garageList: groupList, allSwitches: false));
|
||||||
|
|
||||||
// Get a list of all device IDs
|
// Get a list of all device IDs
|
||||||
List<String> allDeviceIds = groupList.map((device) => device.deviceId).toList();
|
List<String> allDeviceIds =
|
||||||
|
groupList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
// First call for switch_1
|
// First call for switch_1
|
||||||
final response = await DevicesAPI.deviceBatchController(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
@ -538,8 +564,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstWizardSwitch(
|
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
|
||||||
ChangeFirstWizardSwitchStatusEvent event, Emitter<GarageDoorSensorState> emit) async {
|
Emitter<GarageDoorSensorState> emit) async {
|
||||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||||
try {
|
try {
|
||||||
bool allSwitchesValue = true;
|
bool allSwitchesValue = true;
|
||||||
@ -552,7 +578,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
emit(UpdateGroupState(garageList: groupList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
garageList: groupList, allSwitches: allSwitchesValue));
|
||||||
|
|
||||||
final response = await DevicesAPI.deviceBatchController(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
@ -568,13 +595,16 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setTimeOutAlarm(SetTimeOutValue event, Emitter<GarageDoorSensorState> emit) async {
|
void _setTimeOutAlarm(
|
||||||
|
SetTimeOutValue event, Emitter<GarageDoorSensorState> emit) async {
|
||||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try {
|
try {
|
||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: GDId, code: 'countdown_alarm', value: seconds), GDId);
|
DeviceControlModel(
|
||||||
|
deviceId: GDId, code: 'countdown_alarm', value: seconds),
|
||||||
|
GDId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
if (response['success'] ?? false) {
|
||||||
deviceStatus.countdownAlarm = seconds;
|
deviceStatus.countdownAlarm = seconds;
|
||||||
|
@ -11,12 +11,14 @@ class AcStatusModel {
|
|||||||
bool childLock;
|
bool childLock;
|
||||||
late TempModes acMode;
|
late TempModes acMode;
|
||||||
late FanSpeeds acFanSpeed;
|
late FanSpeeds acFanSpeed;
|
||||||
|
int countdown1;
|
||||||
|
|
||||||
AcStatusModel(
|
AcStatusModel(
|
||||||
{required this.uuid,
|
{required this.uuid,
|
||||||
required this.acSwitch,
|
required this.acSwitch,
|
||||||
required this.modeString,
|
required this.modeString,
|
||||||
required this.tempSet,
|
required this.tempSet,
|
||||||
|
required this.countdown1,
|
||||||
required this.currentTemp,
|
required this.currentTemp,
|
||||||
required this.fanSpeedsString,
|
required this.fanSpeedsString,
|
||||||
required this.childLock}) {
|
required this.childLock}) {
|
||||||
@ -30,6 +32,7 @@ class AcStatusModel {
|
|||||||
late int _tempSet;
|
late int _tempSet;
|
||||||
late int _currentTemp;
|
late int _currentTemp;
|
||||||
late String _fanSpeeds;
|
late String _fanSpeeds;
|
||||||
|
late int _countdown1;
|
||||||
late bool _childLock;
|
late bool _childLock;
|
||||||
for (int i = 0; i < jsonList.length; i++) {
|
for (int i = 0; i < jsonList.length; i++) {
|
||||||
if (jsonList[i].code == 'switch') {
|
if (jsonList[i].code == 'switch') {
|
||||||
@ -44,6 +47,8 @@ class AcStatusModel {
|
|||||||
_fanSpeeds = jsonList[i].value ?? 210;
|
_fanSpeeds = jsonList[i].value ?? 210;
|
||||||
} else if (jsonList[i].code == 'child_lock') {
|
} else if (jsonList[i].code == 'child_lock') {
|
||||||
_childLock = jsonList[i].value ?? false;
|
_childLock = jsonList[i].value ?? false;
|
||||||
|
} else if (jsonList[i].code == 'countdown_time') {
|
||||||
|
_countdown1 = jsonList[i].value ?? 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return AcStatusModel(
|
return AcStatusModel(
|
||||||
@ -53,6 +58,7 @@ class AcStatusModel {
|
|||||||
tempSet: _tempSet,
|
tempSet: _tempSet,
|
||||||
currentTemp: _currentTemp,
|
currentTemp: _currentTemp,
|
||||||
fanSpeedsString: _fanSpeeds,
|
fanSpeedsString: _fanSpeeds,
|
||||||
|
countdown1: _countdown1,
|
||||||
childLock: _childLock);
|
childLock: _childLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CustomHalfHourPicker extends StatefulWidget {
|
||||||
|
final Function(double) onValueChanged;
|
||||||
|
|
||||||
|
const CustomHalfHourPicker({Key? key, required this.onValueChanged})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_CustomHalfHourPickerState createState() => _CustomHalfHourPickerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomHalfHourPickerState extends State<CustomHalfHourPicker> {
|
||||||
|
double selectedValue = 0.0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 200,
|
||||||
|
child: ListWheelScrollView.useDelegate(
|
||||||
|
itemExtent: 50,
|
||||||
|
perspective: 0.005,
|
||||||
|
physics: const FixedExtentScrollPhysics(),
|
||||||
|
overAndUnderCenterOpacity: 0.3,
|
||||||
|
onSelectedItemChanged: (index) {
|
||||||
|
setState(() {
|
||||||
|
selectedValue =
|
||||||
|
index * 0.5; // Convert index to half-hour increments
|
||||||
|
widget.onValueChanged(selectedValue);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
childDelegate: ListWheelChildBuilderDelegate(
|
||||||
|
builder: (context, index) {
|
||||||
|
if (index < 0 || index > 48)
|
||||||
|
return null; // Limit to 24.0 (48 * 0.5)
|
||||||
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
(index * 0.5)
|
||||||
|
.toStringAsFixed(1), // Display value as 0.0, 0.5, etc.
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 25,
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.w800),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
childCount: 49, // 0.0 to 24.0 (inclusive)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -28,6 +28,7 @@ class AcInterface extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
AcStatusModel statusModel = AcStatusModel(
|
AcStatusModel statusModel = AcStatusModel(
|
||||||
|
countdown1: 0,
|
||||||
uuid: ac.uuid ?? '',
|
uuid: ac.uuid ?? '',
|
||||||
acSwitch: true,
|
acSwitch: true,
|
||||||
modeString: 'hot',
|
modeString: 'hot',
|
||||||
|
@ -7,11 +7,13 @@ import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.dart';
|
|||||||
import 'package:syncrow_app/features/devices/model/ac_model.dart';
|
import 'package:syncrow_app/features/devices/model/ac_model.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/ac_mode_control_unit.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_mode_control_unit.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_timer_page.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
|
||||||
class AcInterfaceControls extends StatelessWidget {
|
class AcInterfaceControls extends StatelessWidget {
|
||||||
const AcInterfaceControls({super.key, required this.deviceModel, required this.deviceStatus});
|
const AcInterfaceControls(
|
||||||
|
{super.key, required this.deviceModel, required this.deviceStatus});
|
||||||
|
|
||||||
final DeviceModel deviceModel;
|
final DeviceModel deviceModel;
|
||||||
final AcStatusModel deviceStatus;
|
final AcStatusModel deviceStatus;
|
||||||
@ -20,8 +22,9 @@ class AcInterfaceControls extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<ACsBloc, AcsState>(
|
return BlocBuilder<ACsBloc, AcsState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
String lockIconName =
|
String lockIconName = deviceStatus.childLock
|
||||||
deviceStatus.childLock ? Assets.assetsIconsLock : Assets.assetsIconsUnLock;
|
? Assets.assetsIconsLock
|
||||||
|
: Assets.assetsIconsUnLock;
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
@ -34,11 +37,22 @@ class AcInterfaceControls extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {},
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
PageRouteBuilder(
|
||||||
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
|
AcTimerPage(
|
||||||
|
device: deviceModel,
|
||||||
|
deviceCode: deviceModel.type!,
|
||||||
|
switchCode: '',
|
||||||
|
)));
|
||||||
|
},
|
||||||
child: DefaultContainer(
|
child: DefaultContainer(
|
||||||
height: 55,
|
height: 55,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: SvgPicture.asset(Assets.assetsIconsAutomatedClock),
|
child:
|
||||||
|
SvgPicture.asset(Assets.assetsIconsAutomatedClock),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
170
lib/features/devices/view/widgets/ACs/ac_timer_page.dart
Normal file
170
lib/features/devices/view/widgets/ACs/ac_timer_page.dart
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.dart';
|
||||||
|
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/ACs/CustomHalfHourTimerPicker.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.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 AcTimerPage extends StatelessWidget {
|
||||||
|
final DeviceModel device;
|
||||||
|
final String deviceCode;
|
||||||
|
final String switchCode;
|
||||||
|
const AcTimerPage(
|
||||||
|
{required this.device,
|
||||||
|
required this.deviceCode,
|
||||||
|
required this.switchCode,
|
||||||
|
super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AnnotatedRegion(
|
||||||
|
value: SystemUiOverlayStyle(
|
||||||
|
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||||
|
statusBarIconBrightness: Brightness.light,
|
||||||
|
),
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (context) => ACsBloc(acId: device.uuid ?? ''),
|
||||||
|
child: BlocBuilder<ACsBloc, AcsState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
final oneGangBloc = BlocProvider.of<ACsBloc>(context);
|
||||||
|
Duration duration = Duration.zero;
|
||||||
|
int selectedValue = 0;
|
||||||
|
|
||||||
|
int countNum = 0;
|
||||||
|
if (state is UpdateTimerState) {
|
||||||
|
countNum = state.seconds;
|
||||||
|
} else if (state is TimerRunInProgress) {
|
||||||
|
countNum = state.remainingTime;
|
||||||
|
} else if (state is TimerRunComplete) {
|
||||||
|
countNum = 0;
|
||||||
|
}
|
||||||
|
// else if (state is LoadingNewSate) {
|
||||||
|
// countNum = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return PopScope(
|
||||||
|
canPop: false,
|
||||||
|
onPopInvoked: (didPop) {
|
||||||
|
if (!didPop) {
|
||||||
|
oneGangBloc.add(OnClose());
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: DefaultTabController(
|
||||||
|
length: 2,
|
||||||
|
child: DefaultScaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
centerTitle: true,
|
||||||
|
title: const BodyLarge(
|
||||||
|
text: 'Countdown',
|
||||||
|
fontColor: ColorsManager.primaryColor,
|
||||||
|
fontWeight: FontsManager.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: state is AcsLoadingState
|
||||||
|
? const Center(child: CircularProgressIndicator())
|
||||||
|
: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
decoration: const ShapeDecoration(
|
||||||
|
color: ColorsManager.onPrimaryColor,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.all(Radius.circular(30)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: Container(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
countNum > 0
|
||||||
|
? BodyLarge(
|
||||||
|
text: formatDuration(countNum),
|
||||||
|
fontColor: ColorsManager
|
||||||
|
.slidingBlueColor,
|
||||||
|
fontSize: 40,
|
||||||
|
)
|
||||||
|
: Container(
|
||||||
|
child: CustomHalfHourPicker(
|
||||||
|
onValueChanged: (value) {
|
||||||
|
selectedValue =
|
||||||
|
(value * 10).toInt();
|
||||||
|
if (selectedValue == 5) {
|
||||||
|
duration = const Duration(
|
||||||
|
minutes:
|
||||||
|
30); // 0.5 translates to 30 minutes
|
||||||
|
countNum =
|
||||||
|
duration.inSeconds;
|
||||||
|
} else {
|
||||||
|
duration = Duration(
|
||||||
|
minutes: selectedValue *
|
||||||
|
6); // Each step represents 6 minutes
|
||||||
|
countNum =
|
||||||
|
duration.inSeconds;
|
||||||
|
}
|
||||||
|
print(
|
||||||
|
"Selected Value: $selectedValue, Duration: $duration");
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if (state is LoadingNewSate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (countNum > 0) {
|
||||||
|
oneGangBloc.add(SetCounterValue(
|
||||||
|
seconds: countNum,
|
||||||
|
deviceCode:
|
||||||
|
'countdown_time',
|
||||||
|
duration: selectedValue));
|
||||||
|
} else if (duration !=
|
||||||
|
Duration.zero) {
|
||||||
|
oneGangBloc.add(SetCounterValue(
|
||||||
|
seconds: 0,
|
||||||
|
deviceCode:
|
||||||
|
'countdown_time',
|
||||||
|
duration: selectedValue));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: SvgPicture.asset(countNum > 0
|
||||||
|
? Assets.pauseIcon
|
||||||
|
: Assets.playIcon)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String formatDuration(int seconds) {
|
||||||
|
final hours = (seconds ~/ 3600).toString().padLeft(2, '0');
|
||||||
|
final minutes = ((seconds % 3600) ~/ 60).toString().padLeft(2, '0');
|
||||||
|
final secs = (seconds % 60).toString().padLeft(2, '0');
|
||||||
|
return '$hours:$minutes:$secs';
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,142 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
// import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
// import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
// import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
// import 'package:syncrow_app/navigation/routing_constants.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
class CreateUnitWidget extends StatelessWidget {
|
class CreateUnitWidget extends StatelessWidget {
|
||||||
const CreateUnitWidget({super.key});
|
const CreateUnitWidget({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container();
|
TextEditingController textEditingController = TextEditingController();
|
||||||
|
return BlocConsumer<HomeCubit, HomeState>(
|
||||||
|
listener: (context, state) {
|
||||||
|
if (state is ActivationError) {}
|
||||||
|
},
|
||||||
|
builder: (context, state) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'Join a Space',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: ColorsManager.secondaryColor),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height * 0.6,
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.assetsIconsMenuIconsHomeManagementIconsJoinAHome,
|
||||||
|
width: 70,
|
||||||
|
height: 70,
|
||||||
|
color: ColorsManager.grayButtonColors,
|
||||||
|
),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 30,
|
||||||
|
),
|
||||||
|
child: BodyMedium(
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
text: 'Please enter your invitation code'),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
border: Border.all(
|
||||||
|
color: state is ActivationError
|
||||||
|
? ColorsManager.red // Red border for error
|
||||||
|
: ColorsManager
|
||||||
|
.grayBox, // Default border color
|
||||||
|
width: 1.5, // Border width
|
||||||
|
),
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(20.0), // Border radius
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 5,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: TextFormField(
|
||||||
|
validator: (value) {},
|
||||||
|
controller: textEditingController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Invitation code',
|
||||||
|
hintStyle: context.bodyMedium.copyWith(
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
border: InputBorder.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () async {
|
||||||
|
if (textEditingController.text.isEmpty) {
|
||||||
|
CustomSnackBar.displaySnackBar(
|
||||||
|
'Please enter the invitation code');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//3Hsn4X
|
||||||
|
if (await HomeCubit.getInstance()
|
||||||
|
.activationCode(
|
||||||
|
textEditingController.text)) {
|
||||||
|
CustomSnackBar.displaySnackBar(
|
||||||
|
'Done successfully');
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
} else {
|
||||||
|
CustomSnackBar.displaySnackBar(
|
||||||
|
'Wrong code!');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.arrow_right_alt,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
state is ActivationError
|
||||||
|
? Text(
|
||||||
|
state.errMessage,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: ColorsManager.red,
|
||||||
|
fontWeight: FontWeight.w400),
|
||||||
|
)
|
||||||
|
: const SizedBox()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
// return state is! GetSpacesLoading
|
||||||
|
// ? state is! GetSpaceRoomsLoading
|
||||||
|
// ? HomeCubit.getInstance().pages[HomeCubit.pageIndex]
|
||||||
|
// : const Center(child: CircularProgressIndicator())
|
||||||
|
// : const Center(child: CircularProgressIndicator());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// return SizedBox(
|
// return SizedBox(
|
||||||
// width: MediaQuery.sizeOf(context).width,
|
// width: MediaQuery.sizeOf(context).width,
|
||||||
// height: MediaQuery.sizeOf(context).height,
|
// height: MediaQuery.sizeOf(context).height,
|
||||||
@ -47,5 +174,5 @@ class CreateUnitWidget extends StatelessWidget {
|
|||||||
// ],
|
// ],
|
||||||
// ),
|
// ),
|
||||||
// );
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
@ -63,6 +63,8 @@ abstract class ApiEndpoints {
|
|||||||
static const String unitUser = '/unit/user/';
|
static const String unitUser = '/unit/user/';
|
||||||
static const String invitationCode =
|
static const String invitationCode =
|
||||||
'/projects/{projectUuid}/communities/{communityUuid}/spaces/{unitUuid}/invitation-code';
|
'/projects/{projectUuid}/communities/{communityUuid}/spaces/{unitUuid}/invitation-code';
|
||||||
|
static const String activationCode =
|
||||||
|
'/invite-user/activation';
|
||||||
|
|
||||||
//PUT
|
//PUT
|
||||||
static const String renameUnit = '/unit/{unitUuid}';
|
static const String renameUnit = '/unit/{unitUuid}';
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||||
|
@ -31,8 +31,10 @@ class ServerFailure extends Failure {
|
|||||||
{
|
{
|
||||||
// var document = parser.parse(dioError.response!.data.toString());
|
// var document = parser.parse(dioError.response!.data.toString());
|
||||||
// var message = document.body!.text;
|
// var message = document.body!.text;
|
||||||
return ServerFailure.fromResponse(dioError.response!.statusCode!,
|
return ServerFailure.fromResponse(
|
||||||
dioError.response?.data['error']['message'] ?? "Something went wrong");
|
dioError.response!.statusCode!,
|
||||||
|
dioError.response?.data['error']['message'] ??
|
||||||
|
"Something went wrong");
|
||||||
}
|
}
|
||||||
case DioExceptionType.cancel:
|
case DioExceptionType.cancel:
|
||||||
return ServerFailure("The request to ApiServer was canceled");
|
return ServerFailure("The request to ApiServer was canceled");
|
||||||
@ -54,15 +56,7 @@ class ServerFailure extends Failure {
|
|||||||
case 403:
|
case 403:
|
||||||
return ServerFailure(responseMessage);
|
return ServerFailure(responseMessage);
|
||||||
case 400:
|
case 400:
|
||||||
List<String> errors = [];
|
return ServerFailure(responseMessage);
|
||||||
if (responseMessage is List) {
|
|
||||||
for (var error in responseMessage) {
|
|
||||||
errors.add(error);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ServerFailure(responseMessage);
|
|
||||||
}
|
|
||||||
return ServerFailure(errors.join('\n'));
|
|
||||||
case 404:
|
case 404:
|
||||||
return ServerFailure("");
|
return ServerFailure("");
|
||||||
case 500:
|
case 500:
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||||
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
||||||
@ -95,4 +96,21 @@ class SpacesAPI {
|
|||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future activationCodeSpace({
|
||||||
|
String? activationCode,
|
||||||
|
String? userUuid,
|
||||||
|
}) async {
|
||||||
|
Map body = {"activationCode": activationCode, "userUuid": userUuid};
|
||||||
|
final response = await _httpService.post(
|
||||||
|
path: ApiEndpoints.activationCode,
|
||||||
|
showServerMessage: true,
|
||||||
|
body: body,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
|
||||||
|
return json;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user