push garage door preferences

This commit is contained in:
ashrafzarkanisala
2024-10-07 09:31:33 +03:00
parent ebde81b64d
commit 3748fc1419
6 changed files with 317 additions and 54 deletions

View File

@ -33,12 +33,16 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
on<UpdateFunctionOnEvent>(_updateFunctionOn);
on<InitializeAddScheduleEvent>(_initializeAddSchedule);
on<BackToGarageDoorGridViewEvent>(_backToGridView);
on<UpdateCountdownAlarmEvent>(_onUpdateCountdownAlarm);
on<UpdateTrTimeConEvent>(_onUpdateTrTimeCon);
}
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) {
@ -46,7 +50,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
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,
@ -54,9 +59,11 @@ 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));
}
@ -65,7 +72,29 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
}
}
Future<void> _updateSchedule(UpdateGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
void _onUpdateCountdownAlarm(
UpdateCountdownAlarmEvent event, Emitter<GarageDoorState> emit) {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(
status:
currentState.status.copyWith(countdownAlarm: event.countdownAlarm),
));
}
}
void _onUpdateTrTimeCon(
UpdateTrTimeConEvent event, Emitter<GarageDoorState> emit) {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(
status: currentState.status.copyWith(trTimeCon: event.trTimeCon),
));
}
}
Future<void> _updateSchedule(UpdateGarageDoorScheduleEvent event,
Emitter<GarageDoorState> emit) async {
try {
final updatedSchedules = deviceStatus.schedules?.map((schedule) {
if (schedule.scheduleId == event.scheduleId) {
@ -92,12 +121,15 @@ 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 {
@ -108,11 +140,12 @@ 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(
@ -130,30 +163,37 @@ 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(
@ -165,24 +205,30 @@ 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()));
}
}
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));
}
@ -198,9 +244,11 @@ 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) {
@ -215,34 +263,47 @@ 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(
@ -258,7 +319,8 @@ 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) {
@ -267,7 +329,8 @@ 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
@ -289,10 +352,20 @@ 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':
if (value is int) {
deviceStatus = deviceStatus.copyWith(countdownAlarm: value);
}
break;
case 'tr_timecon':
if (value is int) {
deviceStatus = deviceStatus.copyWith(trTimeCon: value);
}
break;
// Add other cases if needed
default:
break;
}

View File

@ -24,7 +24,8 @@ 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];
@ -104,7 +105,8 @@ 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];
@ -166,3 +168,15 @@ class InitializeAddScheduleEvent extends GarageDoorEvent {
index,
];
}
class UpdateCountdownAlarmEvent extends GarageDoorEvent {
final int countdownAlarm;
const UpdateCountdownAlarmEvent(this.countdownAlarm);
}
class UpdateTrTimeConEvent extends GarageDoorEvent {
final int trTimeCon;
const UpdateTrTimeConEvent(this.trTimeCon);
}

View File

@ -291,6 +291,9 @@ class GarageDoorDialogHelper {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(),
/// The dialog is closed when the user taps on the close button or when the
/// [GarageDoorBloc] state changes.
Text(
'Preferences',
style: context.textTheme.titleLarge!.copyWith(
@ -311,13 +314,32 @@ class GarageDoorDialogHelper {
child: GestureDetector(
onTap: () {
context.customAlertDialog(
alertBody: TimeOutAlarmDialogBody(),
alertBody: TimeOutAlarmDialogBody(bloc),
title: 'Time Out Alarm',
onConfirm: () {});
onConfirm: () {
final updatedState =
context.read<GarageDoorBloc>().state;
if (updatedState
is GarageDoorLoadedState) {
context.read<GarageDoorBloc>().add(
GarageDoorControlEvent(
deviceId:
updatedState.status.uuid,
code: 'countdown_alarm',
value: updatedState
.status.countdownAlarm,
),
);
Navigator.pop(context);
// context.read<GarageDoorBloc>().add(
// GarageDoorInitialEvent(
// bloc.deviceId));
}
});
},
child: ToggleWidget(
icon: "-1",
value: bloc.deviceStatus.countdownAlarm > 0,
value: state.status.countdownAlarm > 0,
code: 'countdown_alarm',
deviceId: bloc.deviceId,
label: 'Alarm when door is open',
@ -333,12 +355,38 @@ class GarageDoorDialogHelper {
child: GestureDetector(
onTap: () {
context.customAlertDialog(
alertBody: OpeningClosingTimeDialogBody(),
alertBody: OpeningAndClosingTimeDialogBody(
bloc: bloc,
onDurationChanged: (newDuration) {
context.read<GarageDoorBloc>().add(
UpdateTrTimeConEvent(newDuration),
);
},
),
title: 'Opening and Closing Time',
onConfirm: () {});
onConfirm: () {
final updatedState =
context.read<GarageDoorBloc>().state;
if (updatedState
is GarageDoorLoadedState) {
context.read<GarageDoorBloc>().add(
GarageDoorControlEvent(
deviceId:
updatedState.status.uuid,
code: 'tr_timecon',
value: updatedState
.status.trTimeCon,
),
);
Navigator.pop(context);
// context.read<GarageDoorBloc>().add(
// GarageDoorInitialEvent(
// bloc.deviceId));
}
});
},
child: PresenceDisplayValue(
value: bloc.deviceStatus.trTimeCon.toString(),
value: state.status.trTimeCon.toString(),
postfix: 'sec',
description: 'Opening & Closing Time',
),

View File

@ -1,13 +1,53 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/seconds_picker.dart';
class OpeningClosingTimeDialogBody extends StatelessWidget {
const OpeningClosingTimeDialogBody({super.key});
class OpeningAndClosingTimeDialogBody extends StatefulWidget {
final ValueChanged<int> onDurationChanged;
final GarageDoorBloc bloc;
OpeningAndClosingTimeDialogBody({
required this.onDurationChanged,
required this.bloc,
});
@override
_OpeningAndClosingTimeDialogBodyState createState() =>
_OpeningAndClosingTimeDialogBodyState();
}
class _OpeningAndClosingTimeDialogBodyState
extends State<OpeningAndClosingTimeDialogBody> {
late int durationInSeconds;
@override
void didChangeDependencies() {
super.didChangeDependencies();
final currentState = widget.bloc.state;
if (currentState is GarageDoorLoadedState) {
setState(() {
durationInSeconds = currentState.status.trTimeCon;
});
}
}
@override
Widget build(BuildContext context) {
return Container(
width: 350,
child: Text('asdasd'),
height: 120,
color: Colors.white,
child: SecondsPicker(
initialSeconds: durationInSeconds,
onSecondsChanged: (newSeconds) {
setState(() {
durationInSeconds = newSeconds;
});
widget.onDurationChanged(newSeconds);
},
),
);
}
}

View File

@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
class SecondsPicker extends StatefulWidget {
final int initialSeconds;
final ValueChanged<int> onSecondsChanged;
SecondsPicker({
required this.initialSeconds,
required this.onSecondsChanged,
});
@override
_SecondsPickerState createState() => _SecondsPickerState();
}
class _SecondsPickerState extends State<SecondsPicker> {
late FixedExtentScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = FixedExtentScrollController(
initialItem: widget.initialSeconds,
);
}
@override
Widget build(BuildContext context) {
return Container(
height: 120,
color: Colors.white,
child: ListWheelScrollView.useDelegate(
controller: _scrollController,
itemExtent: 48,
onSelectedItemChanged: (index) {
widget.onSecondsChanged(index);
},
physics: const FixedExtentScrollPhysics(),
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) {
return Center(
child: Text(
'$index sec',
style: const TextStyle(fontSize: 24),
),
);
},
),
),
);
}
}

View File

@ -1,13 +1,49 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
class TimeOutAlarmDialogBody extends StatelessWidget {
const TimeOutAlarmDialogBody({super.key});
class TimeOutAlarmDialogBody extends StatefulWidget {
TimeOutAlarmDialogBody(this.bloc);
final GarageDoorBloc bloc;
@override
_TimeOutAlarmDialogBodyState createState() => _TimeOutAlarmDialogBodyState();
}
class _TimeOutAlarmDialogBodyState extends State<TimeOutAlarmDialogBody> {
int durationInSeconds = 0;
@override
void didChangeDependencies() {
super.didChangeDependencies();
final currentState = widget.bloc.state;
if (currentState is GarageDoorLoadedState) {
if (currentState.status.countdownAlarm != 0) {
setState(() {
durationInSeconds = currentState.status.countdownAlarm;
});
}
}
}
@override
Widget build(BuildContext context) {
return Container(
width: 350,
child: Text('asdasd'),
height: 120,
color: Colors.white,
child: CupertinoTimerPicker(
itemExtent: 120,
mode: CupertinoTimerPickerMode.hm,
initialTimerDuration: Duration(seconds: durationInSeconds),
onTimerDurationChanged: (newDuration) {
widget.bloc.add(
UpdateCountdownAlarmEvent(newDuration.inSeconds),
);
},
),
);
}
}