Added latest changes from dev and solved conflicts

This commit is contained in:
Abdullah Alassaf
2024-06-30 16:27:42 +03:00
94 changed files with 4674 additions and 1442 deletions
+180 -17
View File
@@ -1,4 +1,5 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.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/ac_model.dart';
@@ -10,34 +11,165 @@ import 'package:syncrow_app/utils/resource_manager/constants.dart';
class ACsBloc extends Bloc<AcsEvent, AcsState> {
final String acId;
late DeviceModel deviceModel;
late AcStatusModel deviceStatus;
AcStatusModel deviceStatus = AcStatusModel(
acSwitch: true,
modeString: 'hot',
tempSet: 300,
currentTemp: 315,
fanSpeedsString: 'low',
childLock: false);
List<AcStatusModel> deviceStatusList = [];
List<DeviceModel> devicesList = [];
bool allAcsPage = false;
bool allAcsOn = true;
bool allTempSame = true;
int globalTemp = 25;
ACsBloc({required this.acId}) : super(AcsInitialState()) {
on<AcsInitial>(_fetchAcsStatus);
on<AcSwitch>(_changeAcSwitch);
on<IncreaseCoolToTemp>(_increaseCoolTo);
on<DecreaseCoolToTemp>(_decreaseCoolTo);
on<ChangeLock>(_changeLockValue);
on<ChangeAcMode>(_changeAcMode);
on<ChangeFanSpeed>(_changeFanSpeed);
on<ChangeAllSwitch>(_changeAllAcSwitch);
on<IncreaseAllTemp>(_increaseAllTemp);
on<DecreaseAllTemp>(_decreaseAllTemp);
}
void _fetchAcsStatus(AcsInitial event, Emitter<AcsState> emit) async {
emit(AcsLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(acId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
allAcsPage = event.allAcs;
if (event.allAcs) {
await _getAllAcs();
emit(GetAllAcsStatusState(
allAcsStatues: deviceStatusList,
allAcs: devicesList,
allOn: allAcsOn,
allTempSame: allTempSame,
temp: globalTemp));
} else {
var response = await DevicesAPI.getDeviceStatus(acId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = AcStatusModel.fromJson(statusModelList);
emit(GetAcStatusState(acStatusModel: deviceStatus));
}
deviceStatus = AcStatusModel.fromJson(statusModelList);
emit(GetAcStatusState(acStatusModel: deviceStatus));
} catch (e) {
emit(AcsFailedState(error: e.toString()));
return;
}
}
_getAllAcs() async {
deviceStatusList = [];
devicesList = [];
allAcsOn = true;
allTempSame = true;
devicesList = await DevicesAPI.getDeviceByGroupName(
HomeCubit.getInstance().selectedSpace?.id ?? '', 'AC');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatusList.add(AcStatusModel.fromJson(statusModelList));
}
if (deviceStatusList.isNotEmpty) {
int temp = deviceStatusList[0].tempSet;
deviceStatusList.firstWhere((element) {
if (!element.acSwitch) {
allAcsOn = false;
}
if (element.tempSet != temp) {
allTempSame = false;
}
return true;
});
if (allTempSame) {
globalTemp = temp;
}
}
}
void _changeAcSwitch(AcSwitch event, Emitter<AcsState> emit) async {
emit(AcChangeLoading(acStatusModel: deviceStatus));
final acSwitchValue = !event.acSwitch;
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: allAcsPage ? event.deviceId : acId, code: 'switch', value: acSwitchValue),
allAcsPage ? event.deviceId : acId);
if (response['success'] ?? false) {
deviceStatus.acSwitch = acSwitchValue;
}
} catch (_) {}
if (allAcsPage) {
await Future.delayed(const Duration(seconds: 1));
add(const AcsInitial(allAcs: true));
} else {
emit(AcModifyingState(acStatusModel: deviceStatus));
}
}
void _changeAllAcSwitch(ChangeAllSwitch event, Emitter<AcsState> emit) async {
emit(AcsLoadingState());
try {
if (deviceStatusList.length == devicesList.length) {
for (int i = 0; i < deviceStatusList.length; i++) {
await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: devicesList[i].uuid, code: 'switch', value: event.value),
devicesList[i].uuid ?? '');
}
}
} catch (_) {}
await Future.delayed(const Duration(seconds: 1));
add(const AcsInitial(allAcs: true));
}
void _increaseAllTemp(IncreaseAllTemp event, Emitter<AcsState> emit) async {
emit(AcsLoadingState());
try {
double tempValue = event.value + 0.5;
int value = (tempValue * 10).toInt();
if (deviceStatusList.length == devicesList.length) {
for (int i = 0; i < deviceStatusList.length; i++) {
await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: devicesList[i].uuid, code: 'temp_set', value: value),
devicesList[i].uuid ?? '');
}
}
} catch (_) {}
await Future.delayed(const Duration(seconds: 1));
add(const AcsInitial(allAcs: true));
}
void _decreaseAllTemp(DecreaseAllTemp event, Emitter<AcsState> emit) async {
emit(AcsLoadingState());
try {
double tempValue = event.value - 0.5;
int value = (tempValue * 10).toInt();
if (deviceStatusList.length == devicesList.length) {
for (int i = 0; i < deviceStatusList.length; i++) {
await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: devicesList[i].uuid, code: 'temp_set', value: value),
devicesList[i].uuid ?? '');
}
}
} catch (_) {}
await Future.delayed(const Duration(seconds: 1));
add(const AcsInitial(allAcs: true));
}
void _changeLockValue(ChangeLock event, Emitter<AcsState> emit) async {
emit(AcChangeLoading(acStatusModel: deviceStatus));
@@ -59,13 +191,20 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
int value = (tempValue * 10).toInt();
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: acId, code: 'temp_set', value: value), acId);
DeviceControlModel(
deviceId: allAcsPage ? event.deviceId : acId, code: 'temp_set', value: value),
allAcsPage ? event.deviceId : acId);
if (response['success'] ?? false) {
deviceStatus.tempSet = value;
}
} catch (_) {}
emit(AcModifyingState(acStatusModel: deviceStatus));
if (allAcsPage) {
await Future.delayed(const Duration(seconds: 1));
add(const AcsInitial(allAcs: true));
} else {
emit(AcModifyingState(acStatusModel: deviceStatus));
}
}
void _decreaseCoolTo(DecreaseCoolToTemp event, Emitter<AcsState> emit) async {
@@ -75,13 +214,20 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
int value = (tempValue * 10).toInt();
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: acId, code: 'temp_set', value: value), acId);
DeviceControlModel(
deviceId: allAcsPage ? event.deviceId : acId, code: 'temp_set', value: value),
allAcsPage ? event.deviceId : acId);
if (response['success'] ?? false) {
deviceStatus.tempSet = value;
}
} catch (_) {}
emit(AcModifyingState(acStatusModel: deviceStatus));
if (allAcsPage) {
await Future.delayed(const Duration(seconds: 1));
add(const AcsInitial(allAcs: true));
} else {
emit(AcModifyingState(acStatusModel: deviceStatus));
}
}
void _changeAcMode(ChangeAcMode event, Emitter<AcsState> emit) async {
@@ -89,14 +235,23 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
final tempMode = tempModesMap[getNextItem(tempModesMap, event.tempModes)]!;
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: acId, code: 'mode', value: getACModeString(tempMode)), acId);
DeviceControlModel(
deviceId: allAcsPage ? event.deviceId : acId,
code: 'mode',
value: getACModeString(tempMode)),
allAcsPage ? event.deviceId : acId);
if (response['success'] ?? false) {
deviceStatus.modeString = getACModeString(tempMode);
deviceStatus.acMode = AcStatusModel.getACMode(getACModeString(tempMode));
}
} catch (_) {}
emit(AcModifyingState(acStatusModel: deviceStatus));
if (allAcsPage) {
await Future.delayed(const Duration(seconds: 1));
add(const AcsInitial(allAcs: true));
} else {
emit(AcModifyingState(acStatusModel: deviceStatus));
}
}
void _changeFanSpeed(ChangeFanSpeed event, Emitter<AcsState> emit) async {
@@ -104,8 +259,11 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
final fanSpeed = event.fanSpeeds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: acId, code: 'level', value: getNextFanSpeedKey(fanSpeed)),
acId);
DeviceControlModel(
deviceId: allAcsPage ? event.deviceId : acId,
code: 'level',
value: getNextFanSpeedKey(fanSpeed)),
allAcsPage ? event.deviceId : acId);
try {
if (response['success'] ?? false) {
@@ -113,7 +271,12 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
deviceStatus.acFanSpeed = AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
}
} catch (_) {}
emit(AcModifyingState(acStatusModel: deviceStatus));
if (allAcsPage) {
await Future.delayed(const Duration(seconds: 1));
add(const AcsInitial(allAcs: true));
} else {
emit(AcModifyingState(acStatusModel: deviceStatus));
}
}
String getACModeString(TempModes value) {
@@ -10,40 +10,58 @@ abstract class AcsEvent extends Equatable {
class AcsLoading extends AcsEvent {}
class AcsInitial extends AcsEvent {}
class AcSwitch extends AcsEvent {
final bool acSwitch;
final String deviceId;
const AcSwitch({required this.acSwitch, this.deviceId = ''});
@override
List<Object> get props => [acSwitch, deviceId];
}
class AcsInitial extends AcsEvent {
final bool allAcs;
const AcsInitial({required this.allAcs});
@override
List<Object> get props => [allAcs];
}
class ACsChangeStatus extends AcsEvent {}
class IncreaseCoolToTemp extends AcsEvent {
final double value;
const IncreaseCoolToTemp({required this.value});
final String deviceId;
const IncreaseCoolToTemp({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value];
List<Object> get props => [value, deviceId];
}
class DecreaseCoolToTemp extends AcsEvent {
final double value;
const DecreaseCoolToTemp({required this.value});
final String deviceId;
const DecreaseCoolToTemp({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value];
List<Object> get props => [value, deviceId];
}
class ChangeAcMode extends AcsEvent {
final TempModes tempModes;
const ChangeAcMode({required this.tempModes});
final String deviceId;
const ChangeAcMode({required this.tempModes, this.deviceId = ''});
@override
List<Object> get props => [tempModes];
List<Object> get props => [tempModes, deviceId];
}
class ChangeFanSpeed extends AcsEvent {
final FanSpeeds fanSpeeds;
const ChangeFanSpeed({required this.fanSpeeds});
final String deviceId;
const ChangeFanSpeed({required this.fanSpeeds, this.deviceId = ''});
@override
List<Object> get props => [fanSpeeds];
List<Object> get props => [fanSpeeds, deviceId];
}
class ChangeLock extends AcsEvent {
@@ -53,3 +71,27 @@ class ChangeLock extends AcsEvent {
@override
List<Object> get props => [lockBool];
}
class ChangeAllSwitch extends AcsEvent {
final bool value;
const ChangeAllSwitch({required this.value});
@override
List<Object> get props => [value];
}
class IncreaseAllTemp extends AcsEvent {
final double value;
const IncreaseAllTemp({required this.value});
@override
List<Object> get props => [value];
}
class DecreaseAllTemp extends AcsEvent {
final double value;
const DecreaseAllTemp({required this.value});
@override
List<Object> get props => [value];
}
@@ -1,5 +1,6 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
abstract class AcsState extends Equatable {
const AcsState();
@@ -36,6 +37,24 @@ class GetAcStatusState extends AcsState {
List<Object> get props => [acStatusModel];
}
class GetAllAcsStatusState extends AcsState {
final List<AcStatusModel> allAcsStatues;
final List<DeviceModel> allAcs;
final bool allOn;
final bool allTempSame;
final int temp;
const GetAllAcsStatusState(
{required this.allAcsStatues,
required this.allAcs,
required this.allOn,
required this.allTempSame,
required this.temp});
@override
List<Object> get props => [allAcsStatues, allAcs, allAcs, allTempSame, temp];
}
class AcsFailedState extends AcsState {
final String error;
+9 -14
View File
@@ -30,6 +30,7 @@ class DevicesCubit extends Cubit<DevicesState> {
for (var room in HomeCubit.getInstance().selectedSpace!.rooms!) {
fetchDevicesByRoomId(room.id!);
}
fetchGroups(HomeCubit.getInstance().selectedSpace?.id ?? '');
}
}
@@ -53,7 +54,7 @@ class DevicesCubit extends Cubit<DevicesState> {
static DevicesCubit get(context) => BlocProvider.of(context);
static List<DevicesCategoryModel>? allCategories;
List<DevicesCategoryModel>? allCategories;
selectCategory(int index) {
for (var i = 0; i < allCategories!.length; i++) {
@@ -88,8 +89,8 @@ class DevicesCubit extends Cubit<DevicesState> {
return const CurtainListView();
// case DeviceType.ThreeGang:
// return const ThreeGangSwitchesView();
case DeviceType.Gateway:
return const GateWayView();
// case DeviceType.Gateway:
// return const GateWayView();
default:
return null;
}
@@ -306,10 +307,8 @@ class DevicesCubit extends Cubit<DevicesState> {
if (roomId == null) return;
emitSafe(GetDevicesLoading());
int roomIndex = HomeCubit.getInstance()
.selectedSpace!
.rooms!
.indexWhere((element) => element.id == roomId);
int roomIndex =
HomeCubit.getInstance().selectedSpace!.rooms!.indexWhere((element) => element.id == roomId);
try {
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices =
await DevicesAPI.getDevicesByRoomId(roomId);
@@ -317,8 +316,7 @@ class DevicesCubit extends Cubit<DevicesState> {
emitSafe(GetDevicesError(e.toString()));
return;
}
final devices =
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices;
final devices = HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices;
emitSafe(GetDevicesSuccess(devices));
//get status for each device
@@ -348,11 +346,8 @@ class DevicesCubit extends Cubit<DevicesState> {
emitSafe(GetDeviceStatusError(e.toString()));
return;
}
HomeCubit.getInstance()
.selectedSpace!
.rooms![roomIndex]
.devices![deviceIndex]
.status = statuses;
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices![deviceIndex].status =
statuses;
emitSafe(GetDeviceStatusSuccess(code: code));
}
@@ -0,0 +1,23 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/gateway_bloc/gateway_event.dart';
import 'package:syncrow_app/features/devices/bloc/gateway_bloc/gateway_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
class GatewayBloc extends Bloc<GatewayEvent, GatewayState> {
GatewayBloc() : super(GatewayInitialState()) {
on<GatewayInitial>(_fetchDevices);
}
void _fetchDevices(GatewayInitial event, Emitter<GatewayState> emit) async {
emit(GatewayLoadingState());
try {
List<DeviceModel> devicesList = await DevicesAPI.getDevicesByGatewayId(event.gatewayId);
emit(UpdateGatewayState(list: devicesList));
} catch (e) {
emit(ErrorState(message: e.toString()));
return;
}
}
}
@@ -0,0 +1,20 @@
import 'package:equatable/equatable.dart';
abstract class GatewayEvent extends Equatable {
const GatewayEvent();
@override
List<Object> get props => [];
}
class GatewayInitial extends GatewayEvent {
final String gatewayId;
const GatewayInitial({required this.gatewayId});
@override
List<Object> get props => [gatewayId];
}
class GatewayLoading extends GatewayEvent {}
class GatewayUpdateState extends GatewayEvent {}
@@ -0,0 +1,29 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
abstract class GatewayState extends Equatable {
const GatewayState();
@override
List<Object> get props => [];
}
class GatewayInitialState extends GatewayState {}
class GatewayLoadingState extends GatewayState {}
class UpdateGatewayState extends GatewayState {
final List<DeviceModel> list;
const UpdateGatewayState({required this.list});
@override
List<Object> get props => [list];
}
class ErrorState extends GatewayState {
final String message;
const ErrorState({required this.message});
@override
List<Object> get props => [message];
}
@@ -1,23 +1,39 @@
import 'dart:math';
import 'package:day_picker/model/day_in_week.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/smart_door_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/create_temporary_password_model.dart';
import 'package:syncrow_app/features/devices/model/temporary_password_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
final String deviceId;
late SmartDoorModel deviceStatus;
static String pageType = '';
SmartDoorBloc({required this.deviceId}) : super(InitialState()) {
on<InitialEvent>(_fetchSmartDoorStatus);
on<InitialPasswordsPage>(getTemporaryPasswords);
on<UpdateLockEvent>(_updateLock);
on<SavePasswordEvent>(savePassword);
on<ToggleRepeatEvent>(toggleRepeat);
on<SetStartEndTimeEvent>(setStartEndTime);
on<ChangeTimeEvent>(changeTime);
on<GeneratePasswordEvent>(generate7DigitNumber);
on<SelectTimeEvent>(selectTime);
on<DeletePasswordEvent>(deletePassword);
}
void _fetchSmartDoorStatus(InitialEvent event, Emitter<SmartDoorState> emit) async {
emit(LoadingInitialState());
void _fetchSmartDoorStatus(
InitialEvent event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
var response = await DevicesAPI.getDeviceStatus(deviceId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
@@ -31,11 +47,76 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
}
void getTemporaryPasswords(
InitialPasswordsPage event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
pageType = event.type!;
var response = await DevicesAPI.getTemporaryPasswords(deviceId, pageType);
if (response is List) {
temporaryPasswords =
response.map((item) => TemporaryPassword.fromJson(item)).toList();
} else if (response is Map && response.containsKey('data')) {
temporaryPasswords = (response['data'] as List)
.map((item) => TemporaryPassword.fromJson(item))
.toList();
} else {
throw Exception("Unexpected response format");
}
emit(TemporaryPasswordsLoadedState(
temporaryPassword: temporaryPasswords!));
} catch (e) {
emit(FailedState(errorMessage: e.toString()));
}
}
TextEditingController passwordController = TextEditingController();
TextEditingController passwordNameController = TextEditingController();
String effectiveTime = 'Select Time';
int? effectiveTimeTimeStamp;
String expirationTime = 'Select Time';
int? expirationTimeTimeStamp;
bool repeat = false;
bool isStartEndTime = true;
List<String>? selectedDay;
DateTime? startTime;
DateTime? endTime;
List<TemporaryPassword>? temporaryPasswords = [];
List<TemporaryPassword>? oneTimePasswords = [];
changeTime(ChangeTimeEvent event, Emitter<SmartDoorState> emit) {
emit(LoadingInitialState());
if (event.isStartEndTime == true) {
startTime = event.val;
} else {
endTime = event.val;
}
emit(changeTimeState());
}
bool toggleRepeat(ToggleRepeatEvent event, Emitter<SmartDoorState> emit) {
emit(LoadingInitialState());
repeat = !repeat;
emit(IsRepeatState());
return repeat;
}
bool setStartEndTime(SetStartEndTimeEvent event, Emitter<SmartDoorState> emit) {
emit(LoadingInitialState());
isStartEndTime = event.val;
emit(IsStartEndState());
return isStartEndTime;
}
void _updateLock(UpdateLockEvent event, Emitter<SmartDoorState> emit) async {
emit(LoadingNewSate(smartDoorModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'normal_open_switch', value: !event.value),
DeviceControlModel(
deviceId: deviceId,
code: 'normal_open_switch',
value: !event.value),
deviceId);
if (response['success'] ?? false) {
@@ -44,4 +125,146 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
} catch (_) {}
emit(UpdateState(smartDoorModel: deviceStatus));
}
void generate7DigitNumber(GeneratePasswordEvent event, Emitter<SmartDoorState> emit) async {
emit(LoadingInitialState());
passwordController.clear();
Random random = Random();
int min = 1000000;
int max = 9999999;
passwordController.text = (min + random.nextInt(max - min + 1)).toString();
emit(GeneratePasswordState());
}
Future<void> selectTime(SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
final DateTime? picked = await showDatePicker(
context: event.context,
initialDate: DateTime.now(),
firstDate: DateTime(2015, 8),
lastDate: DateTime(2101),
);
if (picked != null) {
final TimeOfDay? timePicked = await showTimePicker(
context: event.context,
initialTime: TimeOfDay.now(),
);
if (timePicked != null) {
final selectedDateTime = DateTime(
picked.year,
picked.month,
picked.day,
timePicked.hour,
timePicked.minute,
);
if (event.isEffective) {
if (expirationTimeTimeStamp != null &&
selectedDateTime.millisecondsSinceEpoch >
expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
} else {
effectiveTime = selectedDateTime.toString();
effectiveTimeTimeStamp = selectedDateTime.millisecondsSinceEpoch;
}
} else {
if (effectiveTimeTimeStamp != null &&
selectedDateTime.millisecondsSinceEpoch <
effectiveTimeTimeStamp!) {
CustomSnackBar.displaySnackBar('Expiration Time cannot be earlier than Effective Time.');
} else {
expirationTime = selectedDateTime.toString();
expirationTimeTimeStamp = selectedDateTime.millisecondsSinceEpoch;
}
}
emit(TimeSelectedState());
}
}
}
Future<void> savePassword(SavePasswordEvent event, Emitter<SmartDoorState> emit) async {
if (_validateInputs()) return;
try {
emit(LoadingSaveState());
var res = await DevicesAPI.createPassword(
pageType: pageType,
deviceId: deviceId,
effectiveTime: effectiveTimeTimeStamp.toString(),
invalidTime: expirationTimeTimeStamp.toString(),
name: passwordNameController.text,
password: passwordController.text,
scheduleList: [
if (repeat)
Schedule(
effectiveTime: getTimeOnly(startTime),
invalidTime: getTimeOnly(endTime).toString(),
workingDay: selectedDay!,
),
],
);
Navigator.of(event.context).pop(true);
CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveState());
} catch (_) {
}
}
Future<void> deletePassword(DeletePasswordEvent event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
var response = await DevicesAPI.deletePassword(
deviceId: deviceId, passwordId: event.passwordId)
.then((value) async {
add(InitialPasswordsPage(type: pageType));
});
} catch (e) {
emit(FailedState(errorMessage: e.toString()));
}
}
bool _validateInputs() {
if (passwordController.text.length<7) {
CustomSnackBar.displaySnackBar('Password less than 7');
return true;
}
if (passwordController.text.isEmpty) {
CustomSnackBar.displaySnackBar('Password required');
return true;
}
if (passwordNameController.text.isEmpty) {
CustomSnackBar.displaySnackBar('Password name required');
return true;
}
if (effectiveTime == 'Select Time' || effectiveTimeTimeStamp == null) {
CustomSnackBar.displaySnackBar('Select effective time');
return true;
}
if (expirationTime == 'Select Time' || expirationTimeTimeStamp == null) {
CustomSnackBar.displaySnackBar('Select expiration time');
return true;
}
if (repeat == true &&
(endTime == null || startTime == null || selectedDay == null)) {
CustomSnackBar.displaySnackBar('Start Time and End time and the days required ');
return true;
}
return false;
}
List<DayInWeek> days = [
DayInWeek("S", dayKey: 'Sun'),
DayInWeek("M", dayKey: 'Mon'),
DayInWeek("T", dayKey: 'Tue'),
DayInWeek("W", dayKey: 'Wed'),
DayInWeek("T", dayKey: 'Thu'),
DayInWeek("F", dayKey: 'Fri'),
DayInWeek("S", dayKey: 'Sat'),
];
String getTimeOnly(DateTime? dateTime) {
if (dateTime == null) return '';
return DateFormat('HH:mm').format(dateTime);
}
}
@@ -1,4 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
abstract class SmartDoorEvent extends Equatable {
const SmartDoorEvent();
@@ -8,6 +9,11 @@ abstract class SmartDoorEvent extends Equatable {
}
class InitialEvent extends SmartDoorEvent {}
class InitialPasswordsPage extends SmartDoorEvent {
final String? type;
const InitialPasswordsPage({ this.type});
}
class InitialOneTimePassword extends SmartDoorEvent {}
class UpdateLockEvent extends SmartDoorEvent {
final bool value;
@@ -15,3 +21,47 @@ class UpdateLockEvent extends SmartDoorEvent {
@override
List<Object> get props => [value];
}
class SavePasswordEvent extends SmartDoorEvent {
final BuildContext context;
const SavePasswordEvent({required this.context});
@override
List<Object> get props => [context];
}
class GeneratePasswordEvent extends SmartDoorEvent {}
class SelectTimeEvent extends SmartDoorEvent {
final BuildContext context;
final bool isEffective;
const SelectTimeEvent({required this.context,required this.isEffective});
@override
List<Object> get props => [context,isEffective];
}
class ToggleRepeatEvent extends SmartDoorEvent {}
class SetStartEndTimeEvent extends SmartDoorEvent {
final bool val;
const SetStartEndTimeEvent({required this.val});
@override
List<Object> get props => [val];
}
class DeletePasswordEvent extends SmartDoorEvent {
final String passwordId;
const DeletePasswordEvent({required this.passwordId});
@override
List<Object> get props => [passwordId];
}
class ChangeTimeEvent extends SmartDoorEvent {
final dynamic val;
final bool isStartEndTime;
const ChangeTimeEvent({required this.val,required this.isStartEndTime});
@override
List<Object> get props => [val,isStartEndTime];
}
@@ -1,5 +1,6 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/smart_door_model.dart';
import 'package:syncrow_app/features/devices/model/temporary_password_model.dart';
class SmartDoorState extends Equatable {
const SmartDoorState();
@@ -36,3 +37,17 @@ class FailedState extends SmartDoorState {
@override
List<Object> get props => [errorMessage];
}
class GeneratePasswordState extends SmartDoorState{}
class TimeSelectedState extends SmartDoorState{}
class IsRepeatState extends SmartDoorState{}
class IsStartEndState extends SmartDoorState{}
class changeStartTimeState extends SmartDoorState{}
class changeEndTimeState extends SmartDoorState{}
class changeTimeState extends SmartDoorState{}
class SaveState extends SmartDoorState{}
class LoadingSaveState extends SmartDoorState{}
class TemporaryPasswordsLoadedState extends SmartDoorState{
final List<TemporaryPassword> temporaryPassword;
const TemporaryPasswordsLoadedState({required this.temporaryPassword});
}
@@ -1,14 +1,29 @@
import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_event.dart';
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/group_three_gang_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/three_gang_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
final String threeGangId;
late ThreeGangModel deviceStatus;
ThreeGangModel deviceStatus = ThreeGangModel(
firstSwitch: false,
secondSwitch: false,
thirdSwitch: false,
firstCountDown: 0,
secondCountDown: 0,
thirdCountDown: 0);
Timer? _timer;
bool threeGangGroup = false;
List<DeviceModel> devicesList = [];
List<GroupThreeGangModel> groupThreeGangList = [];
bool allSwitchesOn = true;
ThreeGangBloc({required this.threeGangId}) : super(InitialState()) {
on<InitialEvent>(_fetchThreeGangStatus);
@@ -17,18 +32,60 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
on<ChangeThirdSwitchStatusEvent>(_changeThirdSwitch);
on<AllOffEvent>(_allOff);
on<AllOnEvent>(_allOn);
on<ChangeSlidingSegment>(_changeSliding);
on<SetCounterValue>(_setCounterValue);
on<GetCounterEvent>(_getCounterValue);
on<TickTimer>(_onTickTimer);
on<OnClose>(_onClose);
on<GroupAllOnEvent>(_groupAllOn);
on<GroupAllOffEvent>(_groupAllOff);
}
void _fetchThreeGangStatus(InitialEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(threeGangId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
threeGangGroup = event.groupScreen;
if (threeGangGroup) {
devicesList = [];
groupThreeGangList = [];
allSwitchesOn = true;
devicesList = await DevicesAPI.getDeviceByGroupName(
HomeCubit.getInstance().selectedSpace?.id ?? '', '3G');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = ThreeGangModel.fromJson(statusModelList);
groupThreeGangList.add(GroupThreeGangModel(
deviceId: devicesList[i].uuid ?? '',
deviceName: devicesList[i].name ?? '',
firstSwitch: deviceStatus.firstSwitch,
secondSwitch: deviceStatus.secondSwitch,
thirdSwitch: deviceStatus.thirdSwitch));
}
if (groupThreeGangList.isNotEmpty) {
groupThreeGangList.firstWhere((element) {
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
allSwitchesOn = false;
}
return true;
});
}
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesOn));
} else {
var response = await DevicesAPI.getDeviceStatus(threeGangId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = ThreeGangModel.fromJson(statusModelList);
emit(UpdateState(threeGangModel: deviceStatus));
}
deviceStatus = ThreeGangModel.fromJson(statusModelList);
emit(UpdateState(threeGangModel: deviceStatus));
} catch (e) {
emit(FailedState(error: e.toString()));
return;
@@ -39,14 +96,22 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_1', value: !event.value),
threeGangId);
DeviceControlModel(
deviceId: threeGangGroup ? event.deviceId : threeGangId,
code: 'switch_1',
value: !event.value),
threeGangGroup ? event.deviceId : threeGangId);
if (response['success'] ?? false) {
deviceStatus.firstSwitch = !event.value;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
if (threeGangGroup) {
await Future.delayed(const Duration(seconds: 1));
add(const InitialEvent(groupScreen: true));
} else {
emit(UpdateState(threeGangModel: deviceStatus));
}
}
void _changeSecondSwitch(
@@ -54,28 +119,44 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_2', value: !event.value),
threeGangId);
DeviceControlModel(
deviceId: threeGangGroup ? event.deviceId : threeGangId,
code: 'switch_2',
value: !event.value),
threeGangGroup ? event.deviceId : threeGangId);
if (response['success'] ?? false) {
deviceStatus.secondSwitch = !event.value;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
if (threeGangGroup) {
await Future.delayed(const Duration(seconds: 1));
add(const InitialEvent(groupScreen: true));
} else {
emit(UpdateState(threeGangModel: deviceStatus));
}
}
void _changeThirdSwitch(ChangeThirdSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_3', value: !event.value),
threeGangId);
DeviceControlModel(
deviceId: threeGangGroup ? event.deviceId : threeGangId,
code: 'switch_3',
value: !event.value),
threeGangGroup ? event.deviceId : threeGangId);
if (response['success'] ?? false) {
deviceStatus.thirdSwitch = !event.value;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
if (threeGangGroup) {
await Future.delayed(const Duration(seconds: 1));
add(const InitialEvent(groupScreen: true));
} else {
emit(UpdateState(threeGangModel: deviceStatus));
}
}
void _allOff(AllOffEvent event, Emitter<ThreeGangState> emit) async {
@@ -121,4 +202,140 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
}
void _groupAllOn(GroupAllOnEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
for (int i = 0; i < groupThreeGangList.length; i++) {
await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_1', value: true),
groupThreeGangList[i].deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_2', value: true),
groupThreeGangList[i].deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_3', value: true),
groupThreeGangList[i].deviceId),
]);
}
} catch (_) {}
await Future.delayed(const Duration(seconds: 1));
add(const InitialEvent(groupScreen: true));
}
void _groupAllOff(GroupAllOffEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
for (int i = 0; i < groupThreeGangList.length; i++) {
await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_1', value: false),
groupThreeGangList[i].deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_2', value: false),
groupThreeGangList[i].deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_3', value: false),
groupThreeGangList[i].deviceId),
]);
}
} catch (_) {}
await Future.delayed(const Duration(seconds: 1));
add(const InitialEvent(groupScreen: true));
}
void _changeSliding(ChangeSlidingSegment event, Emitter<ThreeGangState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value));
}
void _setCounterValue(SetCounterValue event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: event.deviceCode, value: seconds),
threeGangId);
if (response['success'] ?? false) {
if (event.deviceCode == 'countdown_1') {
deviceStatus.firstCountDown = seconds;
} else if (event.deviceCode == 'countdown_2') {
deviceStatus.secondCountDown = seconds;
} else if (event.deviceCode == 'countdown_3') {
deviceStatus.thirdCountDown = seconds;
}
} else {
emit(const FailedState(error: 'Something went wrong'));
return;
}
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
if (seconds > 0) {
_onStartTimer(seconds);
} else {
_timer?.cancel();
emit(TimerRunComplete());
}
}
void _getCounterValue(GetCounterEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(threeGangId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = ThreeGangModel.fromJson(statusModelList);
if (event.deviceCode == 'countdown_1') {
deviceStatus.firstCountDown > 0
? _onStartTimer(deviceStatus.firstCountDown)
: emit(UpdateTimerState(seconds: deviceStatus.firstCountDown));
} else if (event.deviceCode == 'countdown_2') {
deviceStatus.secondCountDown > 0
? _onStartTimer(deviceStatus.secondCountDown)
: emit(UpdateTimerState(seconds: deviceStatus.secondCountDown));
} else if (event.deviceCode == 'countdown_3') {
deviceStatus.thirdCountDown > 0
? _onStartTimer(deviceStatus.thirdCountDown)
: emit(UpdateTimerState(seconds: deviceStatus.thirdCountDown));
}
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _onClose(OnClose event, Emitter<ThreeGangState> emit) {
_timer?.cancel();
}
void _onStartTimer(int seconds) {
_timer?.cancel();
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
add(TickTimer(seconds - timer.tick));
});
}
void _onTickTimer(TickTimer event, Emitter<ThreeGangState> emit) {
if (event.remainingTime > 0) {
emit(TimerRunInProgress(event.remainingTime));
} else {
_timer?.cancel();
emit(TimerRunComplete());
}
}
}
@@ -9,29 +9,85 @@ abstract class ThreeGangEvent extends Equatable {
class LoadingEvent extends ThreeGangEvent {}
class InitialEvent extends ThreeGangEvent {}
class InitialEvent extends ThreeGangEvent {
final bool groupScreen;
const InitialEvent({required this.groupScreen});
@override
List<Object> get props => [groupScreen];
}
class ChangeFirstSwitchStatusEvent extends ThreeGangEvent {
final bool value;
const ChangeFirstSwitchStatusEvent({required this.value});
final String deviceId;
const ChangeFirstSwitchStatusEvent({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value];
List<Object> get props => [value, deviceId];
}
class ChangeSecondSwitchStatusEvent extends ThreeGangEvent {
final bool value;
const ChangeSecondSwitchStatusEvent({required this.value});
final String deviceId;
const ChangeSecondSwitchStatusEvent({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value];
List<Object> get props => [value, deviceId];
}
class ChangeThirdSwitchStatusEvent extends ThreeGangEvent {
final bool value;
const ChangeThirdSwitchStatusEvent({required this.value});
final String deviceId;
const ChangeThirdSwitchStatusEvent({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value];
List<Object> get props => [value, deviceId];
}
class AllOffEvent extends ThreeGangEvent {}
class AllOnEvent extends ThreeGangEvent {}
class GroupAllOnEvent extends ThreeGangEvent {}
class GroupAllOffEvent extends ThreeGangEvent {}
class ChangeSlidingSegment extends ThreeGangEvent {
final int value;
const ChangeSlidingSegment({required this.value});
@override
List<Object> get props => [value];
}
class GetCounterEvent extends ThreeGangEvent {
final String deviceCode;
const GetCounterEvent({required this.deviceCode});
@override
List<Object> get props => [deviceCode];
}
class SetCounterValue extends ThreeGangEvent {
final Duration duration;
final String deviceCode;
const SetCounterValue({required this.duration, required this.deviceCode});
@override
List<Object> get props => [duration, deviceCode];
}
class StartTimer extends ThreeGangEvent {
final int duration;
const StartTimer(this.duration);
@override
List<Object> get props => [duration];
}
class TickTimer extends ThreeGangEvent {
final int remainingTime;
const TickTimer(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class StopTimer extends ThreeGangEvent {}
class OnClose extends ThreeGangEvent {}
@@ -1,4 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/group_three_gang_model.dart';
import 'package:syncrow_app/features/devices/model/three_gang_model.dart';
class ThreeGangState extends Equatable {
@@ -28,6 +29,16 @@ class LoadingNewSate extends ThreeGangState {
List<Object> get props => [threeGangModel];
}
class UpdateGroupState extends ThreeGangState {
final List<GroupThreeGangModel> threeGangList;
final bool allSwitches;
const UpdateGroupState({required this.threeGangList, required this.allSwitches});
@override
List<Object> get props => [threeGangList, allSwitches];
}
class FailedState extends ThreeGangState {
final String error;
@@ -36,3 +47,31 @@ class FailedState extends ThreeGangState {
@override
List<Object> get props => [error];
}
class ChangeSlidingSegmentState extends ThreeGangState {
final int value;
const ChangeSlidingSegmentState({required this.value});
@override
List<Object> get props => [value];
}
class UpdateTimerState extends ThreeGangState {
final int seconds;
const UpdateTimerState({required this.seconds});
@override
List<Object> get props => [seconds];
}
class TimerRunInProgress extends ThreeGangState {
final int remainingTime;
const TimerRunInProgress(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class TimerRunComplete extends ThreeGangState {}