fix oct/8 issues

This commit is contained in:
ashrafzarkanisala
2024-10-08 20:15:52 +03:00
parent 66f6b1cba9
commit 79ec890244
19 changed files with 406 additions and 335 deletions

View File

@ -15,6 +15,9 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
List<AllDevicesModel> _selectedDevices = [];
List<AllDevicesModel> _filteredDevices = [];
String productName = '';
String? currentCommunity;
String? currentUnitName;
String? currentProductName;
DeviceManagementBloc() : super(DeviceManagementInitial()) {
on<FetchDevices>(_onFetchDevices);
@ -234,6 +237,16 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
}
void _onSearchDevices(SearchDevices event, Emitter<DeviceManagementState> emit) {
if (event.productName == currentProductName &&
event.community == currentCommunity &&
event.unitName == currentUnitName) {
return;
}
currentProductName = event.productName;
currentCommunity = event.community;
currentUnitName = event.unitName;
if ((event.community == null || event.community!.isEmpty) &&
(event.unitName == null || event.unitName!.isEmpty) &&
(event.productName == null || event.productName!.isEmpty)) {

View File

@ -38,14 +38,13 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
on<GarageDoorBatchControlEvent>(_onBatchControl);
on<GarageDoorFetchBatchStatusEvent>(_onFetchBatchStatus);
on<GarageDoorFactoryResetEvent>(_onFactoryReset);
on<EditGarageDoorScheduleEvent>(_onEditSchedule);
}
void _fetchGarageDoorStatus(
GarageDoorInitialEvent event, Emitter<GarageDoorState> emit) async {
void _fetchGarageDoorStatus(GarageDoorInitialEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState());
try {
var response =
await DevicesManagementApi().getDeviceStatus(event.deviceId);
var response = await DevicesManagementApi().getDeviceStatus(event.deviceId);
deviceStatus = GarageDoorStatusModel.fromJson(deviceId, response.status);
emit(GarageDoorLoadedState(status: deviceStatus));
} catch (e) {
@ -53,22 +52,18 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
Future<void> _onFetchBatchStatus(GarageDoorFetchBatchStatusEvent event,
Emitter<GarageDoorState> emit) async {
Future<void> _onFetchBatchStatus(GarageDoorFetchBatchStatusEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState());
try {
final status =
await DevicesManagementApi().getBatchStatus(event.deviceIds);
deviceStatus =
GarageDoorStatusModel.fromJson(event.deviceIds.first, status.status);
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
deviceStatus = GarageDoorStatusModel.fromJson(event.deviceIds.first, status.status);
emit(GarageDoorBatchStatusLoaded(deviceStatus));
} catch (e) {
emit(GarageDoorBatchControlError(e.toString()));
}
}
Future<void> _addSchedule(
AddGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
Future<void> _addSchedule(AddGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
try {
ScheduleEntry newSchedule = ScheduleEntry(
category: event.category,
@ -76,11 +71,9 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
function: Status(code: 'switch_1', value: event.functionOn),
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
);
bool success =
await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId);
bool success = await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId);
if (success) {
add(FetchGarageDoorSchedulesEvent(
deviceId: deviceId, category: 'switch_1'));
add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'));
} else {
emit(GarageDoorLoadedState(status: deviceStatus));
}
@ -89,19 +82,16 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
void _onUpdateCountdownAlarm(
UpdateCountdownAlarmEvent event, Emitter<GarageDoorState> emit) {
void _onUpdateCountdownAlarm(UpdateCountdownAlarmEvent event, Emitter<GarageDoorState> emit) {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(
status:
currentState.status.copyWith(countdownAlarm: event.countdownAlarm),
status: currentState.status.copyWith(countdownAlarm: event.countdownAlarm),
));
}
}
void _onUpdateTrTimeCon(
UpdateTrTimeConEvent event, Emitter<GarageDoorState> emit) {
void _onUpdateTrTimeCon(UpdateTrTimeConEvent event, Emitter<GarageDoorState> emit) {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(
@ -110,8 +100,7 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
Future<void> _updateSchedule(UpdateGarageDoorScheduleEvent event,
Emitter<GarageDoorState> emit) async {
Future<void> _updateSchedule(UpdateGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
try {
final updatedSchedules = deviceStatus.schedules?.map((schedule) {
if (schedule.scheduleId == event.scheduleId) {
@ -138,15 +127,12 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
Future<void> _deleteSchedule(DeleteGarageDoorScheduleEvent event,
Emitter<GarageDoorState> emit) async {
Future<void> _deleteSchedule(DeleteGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
try {
bool success = await DevicesManagementApi()
.deleteScheduleRecord(deviceStatus.uuid, event.scheduleId);
bool success = await DevicesManagementApi().deleteScheduleRecord(deviceStatus.uuid, event.scheduleId);
if (success) {
final updatedSchedules = deviceStatus.schedules
?.where((schedule) => schedule.scheduleId != event.scheduleId)
.toList();
final updatedSchedules =
deviceStatus.schedules?.where((schedule) => schedule.scheduleId != event.scheduleId).toList();
deviceStatus = deviceStatus.copyWith(schedules: updatedSchedules);
emit(GarageDoorLoadedState(status: deviceStatus));
} else {
@ -157,12 +143,11 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
Future<void> _fetchSchedules(FetchGarageDoorSchedulesEvent event,
Emitter<GarageDoorState> emit) async {
Future<void> _fetchSchedules(FetchGarageDoorSchedulesEvent event, Emitter<GarageDoorState> emit) async {
emit(ScheduleGarageLoadingState());
try {
List<ScheduleModel> schedules = await DevicesManagementApi()
.getDeviceSchedules(deviceStatus.uuid, event.category);
List<ScheduleModel> schedules =
await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category);
deviceStatus = deviceStatus.copyWith(schedules: schedules);
emit(
GarageDoorLoadedState(
@ -180,37 +165,30 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
Future<void> _updateSelectedTime(
UpdateSelectedTimeEvent event, Emitter<GarageDoorState> emit) async {
Future<void> _updateSelectedTime(UpdateSelectedTimeEvent event, Emitter<GarageDoorState> emit) async {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(selectedTime: event.selectedTime));
}
}
Future<void> _updateSelectedDay(
UpdateSelectedDayEvent event, Emitter<GarageDoorState> emit) async {
Future<void> _updateSelectedDay(UpdateSelectedDayEvent event, Emitter<GarageDoorState> emit) async {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
List<bool> updatedDays = List.from(currentState.selectedDays);
updatedDays[event.dayIndex] = event.isSelected;
emit(currentState.copyWith(
selectedDays: updatedDays, selectedTime: currentState.selectedTime));
emit(currentState.copyWith(selectedDays: updatedDays, selectedTime: currentState.selectedTime));
}
}
Future<void> _updateFunctionOn(
UpdateFunctionOnEvent event, Emitter<GarageDoorState> emit) async {
Future<void> _updateFunctionOn(UpdateFunctionOnEvent event, Emitter<GarageDoorState> emit) async {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(
functionOn: event.functionOn,
selectedTime: currentState.selectedTime));
emit(currentState.copyWith(functionOn: event.functionOn, selectedTime: currentState.selectedTime));
}
}
Future<void> _initializeAddSchedule(
InitializeAddScheduleEvent event, Emitter<GarageDoorState> emit) async {
Future<void> _initializeAddSchedule(InitializeAddScheduleEvent event, Emitter<GarageDoorState> emit) async {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(
@ -222,25 +200,20 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
Future<void> _fetchRecords(
FetchGarageDoorRecordsEvent event, Emitter<GarageDoorState> emit) async {
Future<void> _fetchRecords(FetchGarageDoorRecordsEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorReportsLoadingState());
try {
final from = DateTime.now()
.subtract(const Duration(days: 30))
.millisecondsSinceEpoch;
final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch;
final to = DateTime.now().millisecondsSinceEpoch;
final DeviceReport records =
await DevicesManagementApi.getDeviceReportsByDate(
event.deviceId, 'switch_1', from.toString(), to.toString());
await DevicesManagementApi.getDeviceReportsByDate(event.deviceId, 'switch_1', from.toString(), to.toString());
emit(GarageDoorReportsState(deviceReport: records));
} catch (e) {
emit(GarageDoorReportsFailedState(error: e.toString()));
}
}
Future<void> _onBatchControl(
GarageDoorBatchControlEvent event, Emitter<GarageDoorState> emit) async {
Future<void> _onBatchControl(GarageDoorBatchControlEvent event, Emitter<GarageDoorState> emit) async {
final oldValue = event.code == 'switch_1' ? deviceStatus.switch1 : false;
_updateLocalValue(event.code, event.value);
@ -260,13 +233,11 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
void _backToGridView(
BackToGarageDoorGridViewEvent event, Emitter<GarageDoorState> emit) {
void _backToGridView(BackToGarageDoorGridViewEvent event, Emitter<GarageDoorState> emit) {
emit(GarageDoorLoadedState(status: deviceStatus));
}
void _handleUpdate(
GarageDoorUpdatedEvent event, Emitter<GarageDoorState> emit) {
void _handleUpdate(GarageDoorUpdatedEvent event, Emitter<GarageDoorState> emit) {
emit(GarageDoorLoadedState(status: deviceStatus));
}
@ -282,11 +253,9 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
late bool status;
await Future.delayed(const Duration(milliseconds: 500));
if (isBatch) {
status = await DevicesManagementApi()
.deviceBatchControl(deviceId, code, value);
status = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
} else {
status = await DevicesManagementApi()
.deviceControl(deviceId, Status(code: code, value: value));
status = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
}
if (!status) {
@ -301,12 +270,10 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
Future<void> _onFactoryReset(
GarageDoorFactoryResetEvent event, Emitter<GarageDoorState> emit) async {
Future<void> _onFactoryReset(GarageDoorFactoryResetEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState());
try {
final response = await DevicesManagementApi()
.factoryReset(event.factoryReset, event.deviceId);
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
if (!response) {
emit(const GarageDoorErrorState(message: 'Failed to reset device'));
} else {
@ -317,47 +284,34 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
void _increaseDelay(
IncreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
void _increaseDelay(IncreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
// if (deviceStatus.countdown1 != 0) {
try {
deviceStatus = deviceStatus.copyWith(
delay: deviceStatus.delay + Duration(minutes: 10));
deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay + Duration(minutes: 10));
emit(GarageDoorLoadedState(status: deviceStatus));
add(GarageDoorControlEvent(
deviceId: event.deviceId,
value: deviceStatus.delay.inSeconds,
code: 'countdown_1'));
add(GarageDoorControlEvent(deviceId: event.deviceId, value: deviceStatus.delay.inSeconds, code: 'countdown_1'));
} catch (e) {
emit(GarageDoorErrorState(message: e.toString()));
}
// }
}
void _decreaseDelay(
DecreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
void _decreaseDelay(DecreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
// if (deviceStatus.countdown1 != 0) {
try {
if (deviceStatus.delay.inMinutes > 10) {
deviceStatus = deviceStatus.copyWith(
delay: deviceStatus.delay - Duration(minutes: 10));
deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay - Duration(minutes: 10));
}
emit(GarageDoorLoadedState(status: deviceStatus));
add(GarageDoorControlEvent(
deviceId: event.deviceId,
value: deviceStatus.delay.inSeconds,
code: 'countdown_1'));
add(GarageDoorControlEvent(deviceId: event.deviceId, value: deviceStatus.delay.inSeconds, code: 'countdown_1'));
} catch (e) {
emit(GarageDoorErrorState(message: e.toString()));
}
//}
}
void _garageDoorControlEvent(
GarageDoorControlEvent event, Emitter<GarageDoorState> emit) async {
final oldValue = event.code == 'countdown_1'
? deviceStatus.countdown1
: deviceStatus.switch1;
void _garageDoorControlEvent(GarageDoorControlEvent event, Emitter<GarageDoorState> emit) async {
final oldValue = event.code == 'countdown_1' ? deviceStatus.countdown1 : deviceStatus.switch1;
_updateLocalValue(event.code, event.value);
emit(GarageDoorLoadedState(status: deviceStatus));
final success = await _runDeBouncer(
@ -373,8 +327,7 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
void _revertValue(
String code, dynamic oldValue, Emitter<GarageDoorState> emit) {
void _revertValue(String code, dynamic oldValue, Emitter<GarageDoorState> emit) {
switch (code) {
case 'switch_1':
if (oldValue is bool) {
@ -383,8 +336,7 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
break;
case 'countdown_1':
if (oldValue is int) {
deviceStatus = deviceStatus.copyWith(
countdown1: oldValue, delay: Duration(seconds: oldValue));
deviceStatus = deviceStatus.copyWith(countdown1: oldValue, delay: Duration(seconds: oldValue));
}
break;
// Add other cases if needed
@ -406,8 +358,7 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
break;
case 'countdown_1':
if (value is int) {
deviceStatus = deviceStatus.copyWith(
countdown1: value, delay: Duration(seconds: value));
deviceStatus = deviceStatus.copyWith(countdown1: value, delay: Duration(seconds: value));
}
break;
case 'countdown_alarm':
@ -420,6 +371,25 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
deviceStatus = deviceStatus.copyWith(trTimeCon: value);
}
break;
case 'door_state_1':
if (value is String) {
deviceStatus = deviceStatus.copyWith(doorState1: value);
}
break;
case 'door_control_1':
if (value is String) {
deviceStatus = deviceStatus.copyWith(doorControl1: value);
}
break;
case 'voice_control_1':
if (value is bool) {
deviceStatus = deviceStatus.copyWith(voiceControl1: value);
}
break;
case 'door_contact_state':
if (value is bool) {
deviceStatus = deviceStatus.copyWith(doorContactState: value);
}
default:
break;
}
@ -430,4 +400,24 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
_timer?.cancel();
return super.close();
}
FutureOr<void> _onEditSchedule(EditGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
try {
ScheduleEntry newSchedule = ScheduleEntry(
scheduleId: event.scheduleId,
category: event.category,
time: formatTimeOfDayToISO(event.time),
function: Status(code: 'switch_1', value: event.functionOn),
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
);
bool success = await DevicesManagementApi().editScheduleRecord(deviceId, newSchedule);
if (success) {
add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'));
} else {
emit(GarageDoorLoadedState(status: deviceStatus));
}
} catch (e) {
emit(GarageDoorLoadedState(status: deviceStatus));
}
}
}

View File

@ -25,8 +25,7 @@ class GarageDoorControlEvent extends GarageDoorEvent {
final dynamic value;
final String code;
const GarageDoorControlEvent(
{required this.deviceId, required this.value, required this.code});
const GarageDoorControlEvent({required this.deviceId, required this.value, required this.code});
@override
List<Object?> get props => [deviceId, value];
@ -46,6 +45,22 @@ class AddGarageDoorScheduleEvent extends GarageDoorEvent {
});
}
class EditGarageDoorScheduleEvent extends GarageDoorEvent {
final String scheduleId;
final String category;
final TimeOfDay time;
final bool functionOn;
final List<bool> selectedDays;
const EditGarageDoorScheduleEvent({
required this.scheduleId,
required this.category,
required this.time,
required this.functionOn,
required this.selectedDays,
});
}
class UpdateGarageDoorScheduleEvent extends GarageDoorEvent {
final String deviceId;
final String scheduleId;
@ -106,8 +121,7 @@ class FetchGarageDoorRecordsEvent extends GarageDoorEvent {
final String deviceId;
final String code;
const FetchGarageDoorRecordsEvent(
{required this.deviceId, required this.code});
const FetchGarageDoorRecordsEvent({required this.deviceId, required this.code});
@override
List<Object?> get props => [deviceId, code];

View File

@ -76,35 +76,30 @@ class GarageDoorDialogHelper {
padding: 8,
backgroundColor: ColorsManager.boxColor,
borderRadius: 15,
onPressed: isEdit == true
? null
: () async {
TimeOfDay? time = await showTimePicker(
context: context,
initialTime:
state.selectedTime ?? TimeOfDay.now(),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: const ColorScheme.light(
primary: ColorsManager.primaryColor,
),
),
child: child!,
);
},
);
if (time != null) {
bloc.add(UpdateSelectedTimeEvent(time));
}
},
onPressed: () async {
TimeOfDay? time = await showTimePicker(
context: context,
initialTime: state.selectedTime ?? TimeOfDay.now(),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: const ColorScheme.light(
primary: ColorsManager.primaryColor,
),
),
child: child!,
);
},
);
if (time != null) {
bloc.add(UpdateSelectedTimeEvent(time));
}
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
state.selectedTime == null
? 'Time'
: state.selectedTime!.format(context),
state.selectedTime == null ? 'Time' : state.selectedTime!.format(context),
style: context.textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor,
),
@ -119,8 +114,7 @@ class GarageDoorDialogHelper {
),
),
const SizedBox(height: 16),
_buildDayCheckboxes(context, state.selectedDays,
isEdit: isEdit),
_buildDayCheckboxes(context, state.selectedDays, isEdit: isEdit),
const SizedBox(height: 16),
_buildFunctionSwitch(context, state.functionOn, isEdit),
],
@ -147,7 +141,13 @@ class GarageDoorDialogHelper {
onPressed: () {
if (state.selectedTime != null) {
if (state.isEditing && index != null) {
return;
bloc.add(EditGarageDoorScheduleEvent(
scheduleId: schedule?.scheduleId ?? '',
category: 'switch_1',
time: state.selectedTime!,
selectedDays: state.selectedDays,
functionOn: state.functionOn,
));
} else {
bloc.add(AddGarageDoorScheduleEvent(
category: 'switch_1',
@ -199,9 +199,7 @@ class GarageDoorDialogHelper {
return daysBoolean;
}
static Widget _buildDayCheckboxes(
BuildContext context, List<bool> selectedDays,
{bool? isEdit}) {
static Widget _buildDayCheckboxes(BuildContext context, List<bool> selectedDays, {bool? isEdit}) {
final dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
return Row(
@ -210,13 +208,9 @@ class GarageDoorDialogHelper {
children: [
Checkbox(
value: selectedDays[index],
onChanged: isEdit == true
? null
: (bool? value) {
context
.read<GarageDoorBloc>()
.add(UpdateSelectedDayEvent(index, value!));
},
onChanged: (bool? value) {
context.read<GarageDoorBloc>().add(UpdateSelectedDayEvent(index, value!));
},
),
Text(dayLabels[index]),
],
@ -225,27 +219,19 @@ class GarageDoorDialogHelper {
);
}
static Widget _buildFunctionSwitch(
BuildContext context, bool isOn, bool? isEdit) {
static Widget _buildFunctionSwitch(BuildContext context, bool isOn, bool? isEdit) {
return Row(
children: [
Text(
'Function:',
style: context.textTheme.bodySmall!
.copyWith(color: ColorsManager.grayColor),
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.grayColor),
),
const SizedBox(width: 10),
Radio<bool>(
value: true,
groupValue: isOn,
onChanged: (bool? value) {
if (isEdit == true) {
return;
} else {
context
.read<GarageDoorBloc>()
.add(const UpdateFunctionOnEvent(functionOn: true));
}
context.read<GarageDoorBloc>().add(const UpdateFunctionOnEvent(functionOn: true));
},
),
const Text('On'),
@ -254,13 +240,7 @@ class GarageDoorDialogHelper {
value: false,
groupValue: isOn,
onChanged: (bool? value) {
if (isEdit == true) {
return;
} else {
context
.read<GarageDoorBloc>()
.add(const UpdateFunctionOnEvent(functionOn: false));
}
context.read<GarageDoorBloc>().add(const UpdateFunctionOnEvent(functionOn: false));
},
),
const Text('Off'),
@ -317,33 +297,36 @@ class GarageDoorDialogHelper {
alertBody: TimeOutAlarmDialogBody(bloc),
title: 'Time Out Alarm',
onConfirm: () {
final updatedState =
context.read<GarageDoorBloc>().state;
if (updatedState
is GarageDoorLoadedState) {
final updatedState = context.read<GarageDoorBloc>().state;
if (updatedState is GarageDoorLoadedState) {
context.read<GarageDoorBloc>().add(
GarageDoorControlEvent(
deviceId:
updatedState.status.uuid,
deviceId: updatedState.status.uuid,
code: 'countdown_alarm',
value: updatedState
.status.countdownAlarm,
value: updatedState.status.countdownAlarm,
),
);
Navigator.pop(context);
// context.read<GarageDoorBloc>().add(
// GarageDoorInitialEvent(
// bloc.deviceId));
}
});
},
child: ToggleWidget(
icon: "-1",
value: state.status.countdownAlarm > 0,
code: 'countdown_alarm',
value: state.status.doorState1 == "close_time_alarm" ? false : true,
code: 'door_state_1',
deviceId: bloc.deviceId,
label: 'Alarm when door is open',
onChange: (value) {}),
onChange: (value) {
context.read<GarageDoorBloc>().add(
GarageDoorControlEvent(
deviceId: bloc.deviceId,
code: 'door_state_1',
value: state.status.doorState1 == "close_time_alarm"
? "unclosed_time"
: "close_time_alarm",
),
);
}),
),
),
const SizedBox(
@ -365,23 +348,16 @@ class GarageDoorDialogHelper {
),
title: 'Opening and Closing Time',
onConfirm: () {
final updatedState =
context.read<GarageDoorBloc>().state;
if (updatedState
is GarageDoorLoadedState) {
final updatedState = context.read<GarageDoorBloc>().state;
if (updatedState is GarageDoorLoadedState) {
context.read<GarageDoorBloc>().add(
GarageDoorControlEvent(
deviceId:
updatedState.status.uuid,
deviceId: updatedState.status.uuid,
code: 'tr_timecon',
value: updatedState
.status.trTimeCon,
value: updatedState.status.trTimeCon,
),
);
Navigator.pop(context);
// context.read<GarageDoorBloc>().add(
// GarageDoorInitialEvent(
// bloc.deviceId));
}
});
},

View File

@ -65,7 +65,7 @@ class GarageDoorStatusModel {
voiceControl1 = status.value ?? false;
break;
case 'door_state_1':
doorState1 = status.value ?? 'closed';
doorState1 = status.value ?? 'close_time_alarm';
break;
}
}

View File

@ -2,9 +2,18 @@ import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class NotificationDialog extends StatelessWidget {
class NotificationDialog extends StatefulWidget {
const NotificationDialog({super.key});
@override
State<NotificationDialog> createState() => _NotificationDialogState();
}
class _NotificationDialogState extends State<NotificationDialog> {
bool isLowBatteryNotificationEnabled = true;
bool isClosingRemindersEnabled = true;
bool isDoorAlarmEnabled = true;
@override
Widget build(BuildContext context) {
return Dialog(
@ -66,7 +75,11 @@ class NotificationDialog extends StatelessWidget {
code: 'notification',
deviceId: '',
label: 'Low Battery',
onChange: (v) {},
onChange: (v) {
setState(() {
isLowBatteryNotificationEnabled = v;
});
},
icon: '-1',
),
ToggleWidget(
@ -74,7 +87,11 @@ class NotificationDialog extends StatelessWidget {
code: 'notification',
deviceId: '',
label: 'Closing\nReminders',
onChange: (v) {},
onChange: (v) {
setState(() {
isClosingRemindersEnabled = v;
});
},
icon: '-1',
),
ToggleWidget(
@ -82,7 +99,11 @@ class NotificationDialog extends StatelessWidget {
code: 'notification',
deviceId: '',
label: 'Door Alarm',
onChange: (v) {},
onChange: (v) {
setState(() {
isDoorAlarmEnabled = v;
});
},
icon: '-1',
),
],

View File

@ -10,14 +10,12 @@ import 'package:syncrow_web/services/devices_mang_api.dart';
part 'one_gang_glass_switch_event.dart';
part 'one_gang_glass_switch_state.dart';
class OneGangGlassSwitchBloc
extends Bloc<OneGangGlassSwitchEvent, OneGangGlassSwitchState> {
class OneGangGlassSwitchBloc extends Bloc<OneGangGlassSwitchEvent, OneGangGlassSwitchState> {
OneGangGlassStatusModel deviceStatus;
Timer? _timer;
OneGangGlassSwitchBloc({required String deviceId})
: deviceStatus = OneGangGlassStatusModel(
uuid: deviceId, switch1: false, countDown: 0),
: deviceStatus = OneGangGlassStatusModel(uuid: deviceId, switch1: false, countDown: 0),
super(OneGangGlassSwitchInitial()) {
on<OneGangGlassSwitchFetchDeviceEvent>(_onFetchDeviceStatus);
on<OneGangGlassSwitchControl>(_onControl);
@ -26,22 +24,19 @@ class OneGangGlassSwitchBloc
on<OneGangGlassFactoryResetEvent>(_onFactoryReset);
}
Future<void> _onFetchDeviceStatus(OneGangGlassSwitchFetchDeviceEvent event,
Emitter<OneGangGlassSwitchState> emit) async {
Future<void> _onFetchDeviceStatus(
OneGangGlassSwitchFetchDeviceEvent event, Emitter<OneGangGlassSwitchState> emit) async {
emit(OneGangGlassSwitchLoading());
try {
final status =
await DevicesManagementApi().getDeviceStatus(event.deviceId);
deviceStatus =
OneGangGlassStatusModel.fromJson(event.deviceId, status.status);
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status);
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
} catch (e) {
emit(OneGangGlassSwitchError(e.toString()));
}
}
Future<void> _onControl(OneGangGlassSwitchControl event,
Emitter<OneGangGlassSwitchState> emit) async {
Future<void> _onControl(OneGangGlassSwitchControl event, Emitter<OneGangGlassSwitchState> emit) async {
final oldValue = _getValueByCode(event.code);
_updateLocalValue(event.code, event.value);
@ -57,12 +52,10 @@ class OneGangGlassSwitchBloc
);
}
Future<void> _onFactoryReset(OneGangGlassFactoryResetEvent event,
Emitter<OneGangGlassSwitchState> emit) async {
Future<void> _onFactoryReset(OneGangGlassFactoryResetEvent event, Emitter<OneGangGlassSwitchState> emit) async {
emit(OneGangGlassSwitchLoading());
try {
final response = await DevicesManagementApi()
.factoryReset(event.factoryReset, event.deviceId);
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
if (!response) {
emit(OneGangGlassSwitchError('Failed to reset device'));
} else {
@ -73,12 +66,11 @@ class OneGangGlassSwitchBloc
}
}
Future<void> _onBatchControl(OneGangGlassSwitchBatchControl event,
Emitter<OneGangGlassSwitchState> emit) async {
Future<void> _onBatchControl(OneGangGlassSwitchBatchControl event, Emitter<OneGangGlassSwitchState> emit) async {
final oldValue = _getValueByCode(event.code);
_updateLocalValue(event.code, event.value);
emit(OneGangGlassSwitchBatchStatusLoaded(deviceStatus));
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
await _runDebounce(
deviceId: event.deviceIds,
@ -91,15 +83,12 @@ class OneGangGlassSwitchBloc
}
Future<void> _onFetchBatchStatus(
OneGangGlassSwitchFetchBatchStatusEvent event,
Emitter<OneGangGlassSwitchState> emit) async {
OneGangGlassSwitchFetchBatchStatusEvent event, Emitter<OneGangGlassSwitchState> emit) async {
emit(OneGangGlassSwitchLoading());
try {
final status =
await DevicesManagementApi().getBatchStatus(event.deviceIds);
deviceStatus = OneGangGlassStatusModel.fromJson(
event.deviceIds.first, status.status);
emit(OneGangGlassSwitchBatchStatusLoaded(deviceStatus));
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
} catch (e) {
emit(OneGangGlassSwitchError(e.toString()));
}
@ -128,11 +117,9 @@ class OneGangGlassSwitchBloc
try {
late bool response;
if (isBatch) {
response = await DevicesManagementApi()
.deviceBatchControl(deviceId, code, value);
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
} else {
response = await DevicesManagementApi()
.deviceControl(deviceId, Status(code: code, value: value));
response = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
}
if (!response) {
@ -144,8 +131,7 @@ class OneGangGlassSwitchBloc
});
}
void _revertValueAndEmit(String deviceId, String code, bool oldValue,
Emitter<OneGangGlassSwitchState> emit) {
void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter<OneGangGlassSwitchState> emit) {
_updateLocalValue(code, oldValue);
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
}

View File

@ -55,7 +55,7 @@ class OneGangGlassSwitchControlView extends StatelessWidget with HelperResponsiv
value: status.switch1,
code: 'switch_1',
deviceId: deviceId,
label: 'Wall Lightً',
label: "Wall Light",
onChange: (value) {
context.read<OneGangGlassSwitchBloc>().add(
OneGangGlassSwitchControl(

View File

@ -31,6 +31,7 @@ class ToggleWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
debugPrint(label.toString());
return DeviceControlsContainer(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,

View File

@ -57,7 +57,7 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperRe
value: status.switch1,
code: 'switch_1',
deviceId: deviceIds.first,
label: 'Glass Switch 1',
label: "Wall Light",
onChange: (value) {
context.read<ThreeGangGlassSwitchBloc>().add(
ThreeGangGlassSwitchBatchControl(
@ -72,7 +72,7 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperRe
value: status.switch2,
code: 'switch_2',
deviceId: deviceIds.first,
label: 'Glass Switch 2',
label: "Ceiling Light",
onChange: (value) {
context.read<ThreeGangGlassSwitchBloc>().add(
ThreeGangGlassSwitchBatchControl(
@ -87,7 +87,7 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperRe
value: status.switch3,
code: 'switch_3',
deviceId: deviceIds.first,
label: 'Glass Switch 3',
label: "SpotLight",
onChange: (value) {
context.read<ThreeGangGlassSwitchBloc>().add(
ThreeGangGlassSwitchBatchControl(

View File

@ -56,7 +56,7 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperRespons
value: status.switch1,
code: 'switch_1',
deviceId: deviceId,
label: 'Wall Light',
label: "Wall Light",
onChange: (value) {
context.read<ThreeGangGlassSwitchBloc>().add(
ThreeGangGlassSwitchControl(
@ -71,7 +71,7 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperRespons
value: status.switch2,
code: 'switch_2',
deviceId: deviceId,
label: 'Ceiling Light',
label: "Ceiling Light",
onChange: (value) {
context.read<ThreeGangGlassSwitchBloc>().add(
ThreeGangGlassSwitchControl(
@ -86,7 +86,7 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperRespons
value: status.switch3,
code: 'switch_3',
deviceId: deviceId,
label: 'SpotLight',
label: "SpotLight",
onChange: (value) {
context.read<ThreeGangGlassSwitchBloc>().add(
ThreeGangGlassSwitchControl(

View File

@ -1,6 +1,7 @@
// water_heater_bloc.dart
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
@ -30,6 +31,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
on<GetSchedulesEvent>(_getSchedule);
on<AddScheduleEvent>(_onAddSchedule);
on<EditWaterHeaterScheduleEvent>(_onEditSchedule);
on<DeleteScheduleEvent>(_onDeleteSchedule);
on<UpdateScheduleEntryEvent>(_onUpdateSchedule);
}
@ -76,8 +78,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
final currentState = state as WaterHeaterDeviceStatusLoaded;
final updatedDays = List<bool>.from(currentState.selectedDays);
updatedDays[event.index] = event.value;
emit(currentState.copyWith(
selectedDays: updatedDays, selectedTime: currentState.selectedTime));
emit(currentState.copyWith(selectedDays: updatedDays, selectedTime: currentState.selectedTime));
}
FutureOr<void> _updateFunctionOn(
@ -85,8 +86,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
Emitter<WaterHeaterState> emit,
) {
final currentState = state as WaterHeaterDeviceStatusLoaded;
emit(currentState.copyWith(
functionOn: event.isOn, selectedTime: currentState.selectedTime));
emit(currentState.copyWith(functionOn: event.isOn, selectedTime: currentState.selectedTime));
}
FutureOr<void> _updateScheduleEvent(
@ -101,8 +101,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
));
}
if (event.scheduleMode == ScheduleModes.countdown) {
final countdownRemaining =
Duration(hours: event.hours, minutes: event.minutes);
final countdownRemaining = Duration(hours: event.hours, minutes: event.minutes);
emit(currentState.copyWith(
scheduleMode: ScheduleModes.countdown,
@ -112,13 +111,11 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
countdownRemaining: countdownRemaining,
));
if (!currentState.isCountdownActive! &&
countdownRemaining > Duration.zero) {
if (!currentState.isCountdownActive! && countdownRemaining > Duration.zero) {
_startCountdownTimer(emit, countdownRemaining);
}
} else if (event.scheduleMode == ScheduleModes.inching) {
final inchingDuration =
Duration(hours: event.hours, minutes: event.minutes);
final inchingDuration = Duration(hours: event.hours, minutes: event.minutes);
emit(currentState.copyWith(
scheduleMode: ScheduleModes.inching,
@ -220,8 +217,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
try {
final status = await DevicesManagementApi().deviceControl(
event.deviceId,
Status(
code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0),
Status(code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0),
);
if (!status) {
emit(const WaterHeaterFailedState(error: 'Failed to stop schedule.'));
@ -239,10 +235,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
emit(WaterHeaterLoadingState());
try {
final status =
await DevicesManagementApi().getDeviceStatus(event.deviceId);
deviceStatus =
WaterHeaterStatusModel.fromJson(event.deviceId, status.status);
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
deviceStatus = WaterHeaterStatusModel.fromJson(event.deviceId, status.status);
if (deviceStatus.scheduleMode == ScheduleModes.countdown) {
final countdownRemaining = Duration(
@ -340,10 +334,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
if (state is WaterHeaterDeviceStatusLoaded) {
final currentState = state as WaterHeaterDeviceStatusLoaded;
if (currentState.countdownRemaining != null &&
currentState.countdownRemaining! > Duration.zero) {
final newRemaining =
currentState.countdownRemaining! - const Duration(minutes: 1);
if (currentState.countdownRemaining != null && currentState.countdownRemaining! > Duration.zero) {
final newRemaining = currentState.countdownRemaining! - const Duration(minutes: 1);
if (newRemaining <= Duration.zero) {
_countdownTimer?.cancel();
@ -438,8 +430,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
void _revertValue(String code, dynamic oldValue,
void Function(WaterHeaterState state) emit) {
void _revertValue(String code, dynamic oldValue, void Function(WaterHeaterState state) emit) {
_updateLocalValue(code, oldValue);
if (state is WaterHeaterDeviceStatusLoaded) {
final currentState = state as WaterHeaterDeviceStatusLoaded;
@ -486,13 +477,12 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
return super.close();
}
FutureOr<void> _getSchedule(
GetSchedulesEvent event, Emitter<WaterHeaterState> emit) async {
FutureOr<void> _getSchedule(GetSchedulesEvent event, Emitter<WaterHeaterState> emit) async {
emit(ScheduleLoadingState());
try {
List<ScheduleModel> schedules = await DevicesManagementApi()
.getDeviceSchedules(deviceStatus.uuid, event.category);
List<ScheduleModel> schedules =
await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category);
emit(WaterHeaterDeviceStatusLoaded(
deviceStatus,
@ -524,8 +514,35 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
// emit(ScheduleLoadingState());
bool success = await DevicesManagementApi()
.addScheduleRecord(newSchedule, currentState.status.uuid);
bool success = await DevicesManagementApi().addScheduleRecord(newSchedule, currentState.status.uuid);
if (success) {
add(GetSchedulesEvent(category: 'switch_1', uuid: deviceStatus.uuid));
} else {
emit(currentState);
//emit(const WaterHeaterFailedState(error: 'Failed to add schedule.'));
}
}
}
FutureOr<void> _onEditSchedule(EditWaterHeaterScheduleEvent event, Emitter<WaterHeaterState> emit) async {
if (state is WaterHeaterDeviceStatusLoaded) {
final currentState = state as WaterHeaterDeviceStatusLoaded;
ScheduleEntry newSchedule = ScheduleEntry(
scheduleId: event.scheduleId,
category: event.category,
time: formatTimeOfDayToISO(event.time),
function: Status(code: 'switch_1', value: event.functionOn),
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
);
// emit(ScheduleLoadingState());
bool success = await DevicesManagementApi().editScheduleRecord(
currentState.status.uuid,
newSchedule,
);
if (success) {
add(GetSchedulesEvent(category: 'switch_1', uuid: deviceStatus.uuid));
@ -577,13 +594,11 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
// emit(ScheduleLoadingState());
bool success = await DevicesManagementApi()
.deleteScheduleRecord(currentState.status.uuid, event.scheduleId);
bool success = await DevicesManagementApi().deleteScheduleRecord(currentState.status.uuid, event.scheduleId);
if (success) {
final updatedSchedules = currentState.schedules
.where((schedule) => schedule.scheduleId != event.scheduleId)
.toList();
final updatedSchedules =
currentState.schedules.where((schedule) => schedule.scheduleId != event.scheduleId).toList();
emit(currentState.copyWith(schedules: updatedSchedules));
} else {
@ -593,15 +608,12 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
FutureOr<void> _batchFetchWaterHeater(FetchWaterHeaterBatchStatusEvent event,
Emitter<WaterHeaterState> emit) async {
FutureOr<void> _batchFetchWaterHeater(FetchWaterHeaterBatchStatusEvent event, Emitter<WaterHeaterState> emit) async {
emit(WaterHeaterLoadingState());
try {
final status =
await DevicesManagementApi().getBatchStatus(event.devicesUuid);
deviceStatus = WaterHeaterStatusModel.fromJson(
event.devicesUuid.first, status.status);
final status = await DevicesManagementApi().getBatchStatus(event.devicesUuid);
deviceStatus = WaterHeaterStatusModel.fromJson(event.devicesUuid.first, status.status);
emit(WaterHeaterDeviceStatusLoaded(deviceStatus));
} catch (e) {
@ -609,8 +621,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
FutureOr<void> _batchControlWaterHeater(ControlWaterHeaterBatchEvent event,
Emitter<WaterHeaterState> emit) async {
FutureOr<void> _batchControlWaterHeater(ControlWaterHeaterBatchEvent event, Emitter<WaterHeaterState> emit) async {
if (state is WaterHeaterDeviceStatusLoaded) {
final currentState = state as WaterHeaterDeviceStatusLoaded;

View File

@ -71,6 +71,22 @@ final class AddScheduleEvent extends WaterHeaterEvent {
List<Object?> get props => [selectedDays, time, functionOn, category];
}
class EditWaterHeaterScheduleEvent extends WaterHeaterEvent {
final String scheduleId;
final String category;
final TimeOfDay time;
final bool functionOn;
final List<bool> selectedDays;
const EditWaterHeaterScheduleEvent({
required this.scheduleId,
required this.category,
required this.time,
required this.functionOn,
required this.selectedDays,
});
}
final class DeleteScheduleEvent extends WaterHeaterEvent {
final int index;
final String scheduleId;

View File

@ -1,14 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
class ScheduleDialogHelper {
static void showAddScheduleDialog(BuildContext context,
{ScheduleModel? schedule, int? index, bool? isEdit}) {
static void showAddScheduleDialog(BuildContext context, {ScheduleModel? schedule, int? index, bool? isEdit}) {
final bloc = context.read<WaterHeaterBloc>();
if (schedule == null) {
@ -70,35 +69,30 @@ class ScheduleDialogHelper {
padding: 8,
backgroundColor: ColorsManager.boxColor,
borderRadius: 15,
onPressed: isEdit == true
? null
: () async {
TimeOfDay? time = await showTimePicker(
context: context,
initialTime:
state.selectedTime ?? TimeOfDay.now(),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: const ColorScheme.light(
primary: ColorsManager.primaryColor,
),
),
child: child!,
);
},
);
if (time != null) {
bloc.add(UpdateSelectedTimeEvent(time));
}
},
onPressed: () async {
TimeOfDay? time = await showTimePicker(
context: context,
initialTime: state.selectedTime ?? TimeOfDay.now(),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: const ColorScheme.light(
primary: ColorsManager.primaryColor,
),
),
child: child!,
);
},
);
if (time != null) {
bloc.add(UpdateSelectedTimeEvent(time));
}
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
state.selectedTime == null
? 'Time'
: state.selectedTime!.format(context),
state.selectedTime == null ? 'Time' : state.selectedTime!.format(context),
style: context.textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor,
),
@ -113,8 +107,7 @@ class ScheduleDialogHelper {
),
),
const SizedBox(height: 16),
_buildDayCheckboxes(context, state.selectedDays,
isEdit: isEdit),
_buildDayCheckboxes(context, state.selectedDays, isEdit: isEdit),
const SizedBox(height: 16),
_buildFunctionSwitch(context, state.functionOn, isEdit),
],
@ -141,7 +134,13 @@ class ScheduleDialogHelper {
onPressed: () {
if (state.selectedTime != null) {
if (state.isEditing && index != null) {
return;
bloc.add(EditWaterHeaterScheduleEvent(
scheduleId: schedule?.scheduleId ?? '',
category: 'switch_1',
time: state.selectedTime!,
selectedDays: state.selectedDays,
functionOn: state.functionOn,
));
} else {
bloc.add(AddScheduleEvent(
category: 'switch_1',
@ -193,9 +192,7 @@ class ScheduleDialogHelper {
return daysBoolean;
}
static Widget _buildDayCheckboxes(
BuildContext context, List<bool> selectedDays,
{bool? isEdit}) {
static Widget _buildDayCheckboxes(BuildContext context, List<bool> selectedDays, {bool? isEdit}) {
final dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
return Row(
@ -204,13 +201,9 @@ class ScheduleDialogHelper {
children: [
Checkbox(
value: selectedDays[index],
onChanged: isEdit == true
? null
: (bool? value) {
context
.read<WaterHeaterBloc>()
.add(UpdateSelectedDayEvent(index, value!));
},
onChanged: (bool? value) {
context.read<WaterHeaterBloc>().add(UpdateSelectedDayEvent(index, value!));
},
),
Text(dayLabels[index]),
],
@ -219,27 +212,19 @@ class ScheduleDialogHelper {
);
}
static Widget _buildFunctionSwitch(
BuildContext context, bool isOn, bool? isEdit) {
static Widget _buildFunctionSwitch(BuildContext context, bool isOn, bool? isEdit) {
return Row(
children: [
Text(
'Function:',
style: context.textTheme.bodySmall!
.copyWith(color: ColorsManager.grayColor),
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.grayColor),
),
const SizedBox(width: 10),
Radio<bool>(
value: true,
groupValue: isOn,
onChanged: (bool? value) {
if (isEdit == true) {
return;
} else {
context
.read<WaterHeaterBloc>()
.add(const UpdateFunctionOnEvent(true));
}
context.read<WaterHeaterBloc>().add(const UpdateFunctionOnEvent(true));
},
),
const Text('On'),
@ -248,13 +233,7 @@ class ScheduleDialogHelper {
value: false,
groupValue: isOn,
onChanged: (bool? value) {
if (isEdit == true) {
return;
} else {
context
.read<WaterHeaterBloc>()
.add(const UpdateFunctionOnEvent(false));
}
context.read<WaterHeaterBloc>().add(const UpdateFunctionOnEvent(false));
},
),
const Text('Off'),

View File

@ -1,7 +1,6 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
class ScheduleEntry {
@ -9,12 +8,14 @@ class ScheduleEntry {
final String time;
final Status function;
final List<String> days;
final String? scheduleId;
ScheduleEntry({
required this.category,
required this.time,
required this.function,
required this.days,
this.scheduleId,
});
@override
@ -38,6 +39,7 @@ class ScheduleEntry {
Map<String, dynamic> toMap() {
return {
'scheduleId': scheduleId,
'category': category,
'time': time,
'function': function.toMap(),
@ -56,8 +58,7 @@ class ScheduleEntry {
String toJson() => json.encode(toMap());
factory ScheduleEntry.fromJson(String source) =>
ScheduleEntry.fromMap(json.decode(source));
factory ScheduleEntry.fromJson(String source) => ScheduleEntry.fromMap(json.decode(source));
@override
bool operator ==(Object other) {
@ -72,9 +73,6 @@ class ScheduleEntry {
@override
int get hashCode {
return category.hashCode ^
time.hashCode ^
function.hashCode ^
days.hashCode;
return category.hashCode ^ time.hashCode ^ function.hashCode ^ days.hashCode;
}
}

View File

@ -2,9 +2,17 @@ import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class WaterLeakNotificationDialog extends StatelessWidget {
class WaterLeakNotificationDialog extends StatefulWidget {
const WaterLeakNotificationDialog({super.key});
@override
State<WaterLeakNotificationDialog> createState() => _WaterLeakNotificationDialogState();
}
class _WaterLeakNotificationDialogState extends State<WaterLeakNotificationDialog> {
bool isLowBatteryNotificationEnabled = true;
bool isWaterLeakageNotificationEnabled = true;
@override
Widget build(BuildContext context) {
return Dialog(
@ -66,7 +74,11 @@ class WaterLeakNotificationDialog extends StatelessWidget {
code: 'notification',
deviceId: '',
label: 'Low Battery',
onChange: (v) {},
onChange: (v) {
setState(() {
isLowBatteryNotificationEnabled = v;
});
},
icon: '-1',
),
ToggleWidget(
@ -74,7 +86,11 @@ class WaterLeakNotificationDialog extends StatelessWidget {
code: 'notification',
deviceId: '',
label: 'Water Leakage',
onChange: (v) {},
onChange: (v) {
setState(() {
isWaterLeakageNotificationEnabled = v;
});
},
icon: '-1',
),
],

View File

@ -71,6 +71,12 @@ class DeviceModel {
tempIcon = Assets.twoGang;
} else if (type == DeviceType.WH) {
tempIcon = Assets.waterHeater;
} else if (type == DeviceType.DoorSensor) {
tempIcon = Assets.sensors;
} else if (type == DeviceType.GarageDoor) {
tempIcon = Assets.openedDoor;
} else if (type == DeviceType.WaterLeak) {
tempIcon = Assets.waterLeakNormal;
} else {
tempIcon = Assets.blackLogo;
}

View File

@ -232,6 +232,22 @@ class DevicesManagementApi {
}
}
Future<bool> editScheduleRecord(String uuid, ScheduleEntry newSchedule) async {
try {
final response = await HTTPService().put(
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
body: newSchedule.toMap(),
expectedResponseModel: (json) {
return json['success'] ?? false;
},
);
return response;
} catch (e) {
debugPrint('Error fetching $e');
return false;
}
}
Future<bool> deleteScheduleRecord(String uuid, String scheduleId) async {
try {
final response = await HTTPService().delete(

View File

@ -11,8 +11,30 @@ enum DeviceType {
CeilingSensor,
WallSensor,
WH,
DoorSensor,
GarageDoor,
WaterLeak,
Other,
}
/*
3G:
1G:
2G:
GW:
DL:
WPS:
CPS:
AC:
CUR:
WH:
DS:
1GT:
2GT:
3GT:
GD:
WL:
*/
Map<String, DeviceType> devicesTypesMap = {
"AC": DeviceType.AC,
@ -25,4 +47,10 @@ Map<String, DeviceType> devicesTypesMap = {
"1G": DeviceType.OneGang,
"CUR": DeviceType.Curtain,
"WH": DeviceType.WH,
'DS': DeviceType.DoorSensor,
"1GT": DeviceType.OneGang,
"2GT": DeviceType.TwoGang,
"3GT": DeviceType.ThreeGang,
'GD': DeviceType.GarageDoor,
'WL': DeviceType.WaterLeak
};