diff --git a/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart b/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart index 5c35f9e9..46eedaaf 100644 --- a/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart +++ b/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart @@ -15,6 +15,9 @@ class DeviceManagementBloc extends Bloc _selectedDevices = []; List _filteredDevices = []; String productName = ''; + String? currentCommunity; + String? currentUnitName; + String? currentProductName; DeviceManagementBloc() : super(DeviceManagementInitial()) { on(_onFetchDevices); @@ -234,6 +237,16 @@ class DeviceManagementBloc extends Bloc 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)) { diff --git a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart index 69e58c65..7060c668 100644 --- a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart +++ b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart @@ -38,14 +38,13 @@ class GarageDoorBloc extends Bloc { on(_onBatchControl); on(_onFetchBatchStatus); on(_onFactoryReset); + on(_onEditSchedule); } - void _fetchGarageDoorStatus( - GarageDoorInitialEvent event, Emitter emit) async { + void _fetchGarageDoorStatus(GarageDoorInitialEvent event, Emitter 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 { } } - Future _onFetchBatchStatus(GarageDoorFetchBatchStatusEvent event, - Emitter emit) async { + Future _onFetchBatchStatus(GarageDoorFetchBatchStatusEvent event, Emitter 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 _addSchedule( - AddGarageDoorScheduleEvent event, Emitter emit) async { + Future _addSchedule(AddGarageDoorScheduleEvent event, Emitter emit) async { try { ScheduleEntry newSchedule = ScheduleEntry( category: event.category, @@ -76,11 +71,9 @@ class GarageDoorBloc extends Bloc { 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 { } } - void _onUpdateCountdownAlarm( - UpdateCountdownAlarmEvent event, Emitter emit) { + void _onUpdateCountdownAlarm(UpdateCountdownAlarmEvent event, Emitter 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 emit) { + void _onUpdateTrTimeCon(UpdateTrTimeConEvent event, Emitter emit) { final currentState = state; if (currentState is GarageDoorLoadedState) { emit(currentState.copyWith( @@ -110,8 +100,7 @@ class GarageDoorBloc extends Bloc { } } - Future _updateSchedule(UpdateGarageDoorScheduleEvent event, - Emitter emit) async { + Future _updateSchedule(UpdateGarageDoorScheduleEvent event, Emitter emit) async { try { final updatedSchedules = deviceStatus.schedules?.map((schedule) { if (schedule.scheduleId == event.scheduleId) { @@ -138,15 +127,12 @@ class GarageDoorBloc extends Bloc { } } - Future _deleteSchedule(DeleteGarageDoorScheduleEvent event, - Emitter emit) async { + Future _deleteSchedule(DeleteGarageDoorScheduleEvent event, Emitter 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 { } } - Future _fetchSchedules(FetchGarageDoorSchedulesEvent event, - Emitter emit) async { + Future _fetchSchedules(FetchGarageDoorSchedulesEvent event, Emitter emit) async { emit(ScheduleGarageLoadingState()); try { - List schedules = await DevicesManagementApi() - .getDeviceSchedules(deviceStatus.uuid, event.category); + List schedules = + await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category); deviceStatus = deviceStatus.copyWith(schedules: schedules); emit( GarageDoorLoadedState( @@ -180,37 +165,30 @@ class GarageDoorBloc extends Bloc { } } - Future _updateSelectedTime( - UpdateSelectedTimeEvent event, Emitter emit) async { + Future _updateSelectedTime(UpdateSelectedTimeEvent event, Emitter emit) async { final currentState = state; if (currentState is GarageDoorLoadedState) { emit(currentState.copyWith(selectedTime: event.selectedTime)); } } - Future _updateSelectedDay( - UpdateSelectedDayEvent event, Emitter emit) async { + Future _updateSelectedDay(UpdateSelectedDayEvent event, Emitter emit) async { final currentState = state; if (currentState is GarageDoorLoadedState) { List 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 _updateFunctionOn( - UpdateFunctionOnEvent event, Emitter emit) async { + Future _updateFunctionOn(UpdateFunctionOnEvent event, Emitter 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 _initializeAddSchedule( - InitializeAddScheduleEvent event, Emitter emit) async { + Future _initializeAddSchedule(InitializeAddScheduleEvent event, Emitter emit) async { final currentState = state; if (currentState is GarageDoorLoadedState) { emit(currentState.copyWith( @@ -222,25 +200,20 @@ class GarageDoorBloc extends Bloc { } } - Future _fetchRecords( - FetchGarageDoorRecordsEvent event, Emitter emit) async { + Future _fetchRecords(FetchGarageDoorRecordsEvent event, Emitter 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 _onBatchControl( - GarageDoorBatchControlEvent event, Emitter emit) async { + Future _onBatchControl(GarageDoorBatchControlEvent event, Emitter emit) async { final oldValue = event.code == 'switch_1' ? deviceStatus.switch1 : false; _updateLocalValue(event.code, event.value); @@ -260,13 +233,11 @@ class GarageDoorBloc extends Bloc { } } - void _backToGridView( - BackToGarageDoorGridViewEvent event, Emitter emit) { + void _backToGridView(BackToGarageDoorGridViewEvent event, Emitter emit) { emit(GarageDoorLoadedState(status: deviceStatus)); } - void _handleUpdate( - GarageDoorUpdatedEvent event, Emitter emit) { + void _handleUpdate(GarageDoorUpdatedEvent event, Emitter emit) { emit(GarageDoorLoadedState(status: deviceStatus)); } @@ -282,11 +253,9 @@ class GarageDoorBloc extends Bloc { 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 { } } - Future _onFactoryReset( - GarageDoorFactoryResetEvent event, Emitter emit) async { + Future _onFactoryReset(GarageDoorFactoryResetEvent event, Emitter 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 { } } - void _increaseDelay( - IncreaseGarageDoorDelayEvent event, Emitter emit) async { + void _increaseDelay(IncreaseGarageDoorDelayEvent event, Emitter 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 emit) async { + void _decreaseDelay(DecreaseGarageDoorDelayEvent event, Emitter 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 emit) async { - final oldValue = event.code == 'countdown_1' - ? deviceStatus.countdown1 - : deviceStatus.switch1; + void _garageDoorControlEvent(GarageDoorControlEvent event, Emitter 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 { } } - void _revertValue( - String code, dynamic oldValue, Emitter emit) { + void _revertValue(String code, dynamic oldValue, Emitter emit) { switch (code) { case 'switch_1': if (oldValue is bool) { @@ -383,8 +336,7 @@ class GarageDoorBloc extends Bloc { 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 { 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 { 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 { _timer?.cancel(); return super.close(); } + + FutureOr _onEditSchedule(EditGarageDoorScheduleEvent event, Emitter 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)); + } + } } diff --git a/lib/pages/device_managment/garage_door/bloc/garage_door_event.dart b/lib/pages/device_managment/garage_door/bloc/garage_door_event.dart index 24eb921e..d1fb15bb 100644 --- a/lib/pages/device_managment/garage_door/bloc/garage_door_event.dart +++ b/lib/pages/device_managment/garage_door/bloc/garage_door_event.dart @@ -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 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 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 get props => [deviceId, code]; diff --git a/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart b/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart index c30f391d..7b133d45 100644 --- a/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart +++ b/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart @@ -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 selectedDays, - {bool? isEdit}) { + static Widget _buildDayCheckboxes(BuildContext context, List 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() - .add(UpdateSelectedDayEvent(index, value!)); - }, + onChanged: (bool? value) { + context.read().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( value: true, groupValue: isOn, onChanged: (bool? value) { - if (isEdit == true) { - return; - } else { - context - .read() - .add(const UpdateFunctionOnEvent(functionOn: true)); - } + context.read().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() - .add(const UpdateFunctionOnEvent(functionOn: false)); - } + context.read().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().state; - if (updatedState - is GarageDoorLoadedState) { + final updatedState = context.read().state; + if (updatedState is GarageDoorLoadedState) { context.read().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().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().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().state; - if (updatedState - is GarageDoorLoadedState) { + final updatedState = context.read().state; + if (updatedState is GarageDoorLoadedState) { context.read().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().add( - // GarageDoorInitialEvent( - // bloc.deviceId)); } }); }, diff --git a/lib/pages/device_managment/garage_door/models/garage_door_model.dart b/lib/pages/device_managment/garage_door/models/garage_door_model.dart index dcb4718c..60d37d9f 100644 --- a/lib/pages/device_managment/garage_door/models/garage_door_model.dart +++ b/lib/pages/device_managment/garage_door/models/garage_door_model.dart @@ -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; } } diff --git a/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart b/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart index d452026d..83ba41bc 100644 --- a/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart +++ b/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart @@ -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 createState() => _NotificationDialogState(); +} + +class _NotificationDialogState extends State { + 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', ), ], diff --git a/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart b/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart index b7760333..eb72eecd 100644 --- a/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart @@ -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 { +class OneGangGlassSwitchBloc extends Bloc { 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(_onFetchDeviceStatus); on(_onControl); @@ -26,22 +24,19 @@ class OneGangGlassSwitchBloc on(_onFactoryReset); } - Future _onFetchDeviceStatus(OneGangGlassSwitchFetchDeviceEvent event, - Emitter emit) async { + Future _onFetchDeviceStatus( + OneGangGlassSwitchFetchDeviceEvent event, Emitter 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 _onControl(OneGangGlassSwitchControl event, - Emitter emit) async { + Future _onControl(OneGangGlassSwitchControl event, Emitter emit) async { final oldValue = _getValueByCode(event.code); _updateLocalValue(event.code, event.value); @@ -57,12 +52,10 @@ class OneGangGlassSwitchBloc ); } - Future _onFactoryReset(OneGangGlassFactoryResetEvent event, - Emitter emit) async { + Future _onFactoryReset(OneGangGlassFactoryResetEvent event, Emitter 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 _onBatchControl(OneGangGlassSwitchBatchControl event, - Emitter emit) async { + Future _onBatchControl(OneGangGlassSwitchBatchControl event, Emitter 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 _onFetchBatchStatus( - OneGangGlassSwitchFetchBatchStatusEvent event, - Emitter emit) async { + OneGangGlassSwitchFetchBatchStatusEvent event, Emitter 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 emit) { + void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter emit) { _updateLocalValue(code, oldValue); emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); } diff --git a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart index 77b3dc9e..8914b786 100644 --- a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart +++ b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart @@ -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().add( OneGangGlassSwitchControl( diff --git a/lib/pages/device_managment/shared/toggle_widget.dart b/lib/pages/device_managment/shared/toggle_widget.dart index ad0ba8ad..61c16e4b 100644 --- a/lib/pages/device_managment/shared/toggle_widget.dart +++ b/lib/pages/device_managment/shared/toggle_widget.dart @@ -31,6 +31,7 @@ class ToggleWidget extends StatelessWidget { @override Widget build(BuildContext context) { + debugPrint(label.toString()); return DeviceControlsContainer( child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, diff --git a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart index f7118ae6..4d1bb91c 100644 --- a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart +++ b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart @@ -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().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().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().add( ThreeGangGlassSwitchBatchControl( diff --git a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart index 2f14eaac..433e5408 100644 --- a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart +++ b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart @@ -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().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().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().add( ThreeGangGlassSwitchControl( diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart index 0a5b2895..498c55fb 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart @@ -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 { on(_getSchedule); on(_onAddSchedule); + on(_onEditSchedule); on(_onDeleteSchedule); on(_onUpdateSchedule); } @@ -76,8 +78,7 @@ class WaterHeaterBloc extends Bloc { final currentState = state as WaterHeaterDeviceStatusLoaded; final updatedDays = List.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 _updateFunctionOn( @@ -85,8 +86,7 @@ class WaterHeaterBloc extends Bloc { Emitter 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 _updateScheduleEvent( @@ -101,8 +101,7 @@ class WaterHeaterBloc extends Bloc { )); } 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 { 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 { 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 { 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 { 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 { } } - 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 { return super.close(); } - FutureOr _getSchedule( - GetSchedulesEvent event, Emitter emit) async { + FutureOr _getSchedule(GetSchedulesEvent event, Emitter emit) async { emit(ScheduleLoadingState()); try { - List schedules = await DevicesManagementApi() - .getDeviceSchedules(deviceStatus.uuid, event.category); + List schedules = + await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category); emit(WaterHeaterDeviceStatusLoaded( deviceStatus, @@ -524,8 +514,35 @@ class WaterHeaterBloc extends Bloc { // 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 _onEditSchedule(EditWaterHeaterScheduleEvent event, Emitter 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 { // 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 { } } - FutureOr _batchFetchWaterHeater(FetchWaterHeaterBatchStatusEvent event, - Emitter emit) async { + FutureOr _batchFetchWaterHeater(FetchWaterHeaterBatchStatusEvent event, Emitter 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 { } } - FutureOr _batchControlWaterHeater(ControlWaterHeaterBatchEvent event, - Emitter emit) async { + FutureOr _batchControlWaterHeater(ControlWaterHeaterBatchEvent event, Emitter emit) async { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart index 4b9ec7a1..ff5de32c 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart @@ -71,6 +71,22 @@ final class AddScheduleEvent extends WaterHeaterEvent { List get props => [selectedDays, time, functionOn, category]; } +class EditWaterHeaterScheduleEvent extends WaterHeaterEvent { + final String scheduleId; + final String category; + final TimeOfDay time; + final bool functionOn; + final List 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; diff --git a/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart b/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart index 4ccec509..9278e396 100644 --- a/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart +++ b/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart @@ -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(); 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 selectedDays, - {bool? isEdit}) { + static Widget _buildDayCheckboxes(BuildContext context, List 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() - .add(UpdateSelectedDayEvent(index, value!)); - }, + onChanged: (bool? value) { + context.read().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( value: true, groupValue: isOn, onChanged: (bool? value) { - if (isEdit == true) { - return; - } else { - context - .read() - .add(const UpdateFunctionOnEvent(true)); - } + context.read().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() - .add(const UpdateFunctionOnEvent(false)); - } + context.read().add(const UpdateFunctionOnEvent(false)); }, ), const Text('Off'), diff --git a/lib/pages/device_managment/water_heater/models/schedule_entry.dart b/lib/pages/device_managment/water_heater/models/schedule_entry.dart index ca14bf51..a2a109af 100644 --- a/lib/pages/device_managment/water_heater/models/schedule_entry.dart +++ b/lib/pages/device_managment/water_heater/models/schedule_entry.dart @@ -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 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 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; } } diff --git a/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart b/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart index 0c2ae6ab..c8aca44e 100644 --- a/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart +++ b/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart @@ -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 createState() => _WaterLeakNotificationDialogState(); +} + +class _WaterLeakNotificationDialogState extends State { + 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', ), ], diff --git a/lib/pages/visitor_password/model/device_model.dart b/lib/pages/visitor_password/model/device_model.dart index c357da52..c2f6f6f2 100644 --- a/lib/pages/visitor_password/model/device_model.dart +++ b/lib/pages/visitor_password/model/device_model.dart @@ -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; } diff --git a/lib/services/devices_mang_api.dart b/lib/services/devices_mang_api.dart index dc0af9a8..bb591b0d 100644 --- a/lib/services/devices_mang_api.dart +++ b/lib/services/devices_mang_api.dart @@ -232,6 +232,22 @@ class DevicesManagementApi { } } + Future 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 deleteScheduleRecord(String uuid, String scheduleId) async { try { final response = await HTTPService().delete( diff --git a/lib/utils/enum/device_types.dart b/lib/utils/enum/device_types.dart index 9ddead07..2b1ce8a5 100644 --- a/lib/utils/enum/device_types.dart +++ b/lib/utils/enum/device_types.dart @@ -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 devicesTypesMap = { "AC": DeviceType.AC, @@ -25,4 +47,10 @@ Map 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 };