start working on scheduling

This commit is contained in:
ashrafzarkanisala
2024-09-17 01:28:35 +03:00
parent e577cd3279
commit 3c8d3feba3
4 changed files with 252 additions and 33 deletions

View File

@ -12,6 +12,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
WaterHeaterBloc() : super(WaterHeaterInitial()) {
on<WaterHeaterFetchStatusEvent>(_fetchWaterHeaterStatus);
on<ToggleWaterHeaterEvent>(_controlWaterHeater);
on<ShowScheduleViewEvent>(_showScheduleView);
on<UpdateScheduleEvent>(_updateScheduleEvent);
on<StopScheduleEvent>(_stopScheduleEvent);
}
@ -23,14 +24,24 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
UpdateScheduleEvent event,
Emitter<WaterHeaterState> emit,
) {
emit(WaterHeaterScheduleState(
scheduleType: event.scheduleType,
emit(WaterHeaterScheduleViewState(
scheduleMode: event.scheduleMode,
hours: event.hours,
minutes: event.minutes,
isActive: true,
));
}
FutureOr<void> _showScheduleView(
ShowScheduleViewEvent event, Emitter<WaterHeaterState> emit) {
emit(const WaterHeaterScheduleViewState(
scheduleMode: ScheduleModes.countdown,
hours: 6,
minutes: 23,
isActive: false,
));
}
FutureOr<void> _stopScheduleEvent(
StopScheduleEvent event,
Emitter<WaterHeaterState> emit,

View File

@ -18,14 +18,15 @@ final class ToggleWaterHeaterEvent extends WaterHeaterEvent {
}
final class UpdateScheduleEvent extends WaterHeaterEvent {
final ScheduleType scheduleType;
final ScheduleModes scheduleMode;
final int hours;
final int minutes;
const UpdateScheduleEvent(this.scheduleType, this.hours, this.minutes);
const UpdateScheduleEvent(
{required this.scheduleMode, required this.hours, required this.minutes});
@override
List<Object?> get props => [scheduleType, hours, minutes];
List<Object?> get props => [scheduleMode, hours, minutes];
}
final class StopScheduleEvent extends WaterHeaterEvent {}
@ -47,3 +48,7 @@ class WaterHeaterFetchBatchStatusEvent extends WaterHeaterEvent {
@override
List<Object?> get props => [deviceId];
}
class ShowScheduleViewEvent extends WaterHeaterEvent {
const ShowScheduleViewEvent();
}

View File

@ -21,7 +21,7 @@ final class WaterHeaterToggleState extends WaterHeaterState {
}
final class WaterHeaterScheduleState extends WaterHeaterState {
final ScheduleType scheduleType;
final ScheduleModes scheduleType;
final int hours;
final int minutes;
final bool isActive;
@ -74,3 +74,20 @@ final class WaterHeaterBatchFailedState extends WaterHeaterState {
}
final class WaterHeaterLoadingState extends WaterHeaterState {}
class WaterHeaterScheduleViewState extends WaterHeaterState {
final ScheduleModes scheduleMode;
final int hours;
final int minutes;
final bool isActive;
const WaterHeaterScheduleViewState({
required this.scheduleMode,
required this.hours,
required this.minutes,
required this.isActive,
});
@override
List<Object> get props => [scheduleMode, hours, minutes];
}

View File

@ -28,6 +28,8 @@ class WaterHeaterDeviceControl extends StatelessWidget
return const Center(child: CircularProgressIndicator());
} else if (state is WaterHeaterDeviceStatusLoaded) {
return _buildStatusControls(context, state.status);
} else if (state is WaterHeaterScheduleViewState) {
return _buildScheduleView(context, state);
} else if (state is WaterHeaterFailedState ||
state is WaterHeaterBatchFailedState) {
return const Center(child: Text('Error fetching status'));
@ -66,7 +68,11 @@ class WaterHeaterDeviceControl extends StatelessWidget
));
},
),
DeviceControlsContainer(
GestureDetector(
onTap: () {
context.read<WaterHeaterBloc>().add(const ShowScheduleViewEvent());
},
child: DeviceControlsContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -97,8 +103,188 @@ class WaterHeaterDeviceControl extends StatelessWidget
),
],
),
),
)
],
);
}
Widget _buildScheduleView(
BuildContext context, WaterHeaterScheduleViewState state) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Scheduling',
style: context.textTheme.titleLarge!.copyWith(
fontWeight: FontWeight.bold,
color: ColorsManager.dialogBlueTitle,
),
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: ListTile(
title: const Text('Countdown'),
leading: Radio<ScheduleModes>(
value: ScheduleModes.countdown,
groupValue: state.scheduleMode,
onChanged: (ScheduleModes? value) {
if (value != null) {
context.read<WaterHeaterBloc>().add(UpdateScheduleEvent(
scheduleMode: value,
hours: state.hours,
minutes: state.minutes,
));
}
},
),
),
),
Expanded(
child: ListTile(
title: const Text('Schedule'),
leading: Radio<ScheduleModes>(
value: ScheduleModes.schedule,
groupValue: state.scheduleMode,
onChanged: (ScheduleModes? value) {
if (value != null) {
context.read<WaterHeaterBloc>().add(UpdateScheduleEvent(
scheduleMode: value,
hours: state.hours,
minutes: state.minutes,
));
}
},
),
),
),
Expanded(
child: ListTile(
title: const Text('Circulate'),
leading: Radio<ScheduleModes>(
value: ScheduleModes.circulate,
groupValue: state.scheduleMode,
onChanged: (ScheduleModes? value) {
if (value != null) {
context.read<WaterHeaterBloc>().add(UpdateScheduleEvent(
scheduleMode: value,
hours: state.hours,
minutes: state.minutes,
));
}
},
),
),
),
Expanded(
child: ListTile(
title: const Text('Inching'),
leading: Radio<ScheduleModes>(
value: ScheduleModes.inching,
groupValue: state.scheduleMode,
onChanged: (ScheduleModes? value) {
if (value != null) {
context.read<WaterHeaterBloc>().add(UpdateScheduleEvent(
scheduleMode: value,
hours: state.hours,
minutes: state.minutes,
));
}
},
),
),
),
],
),
const SizedBox(height: 20),
if (state.scheduleMode == ScheduleModes.countdown ||
state.scheduleMode == ScheduleModes.inching) ...[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Hours input
_buildTimeInputField(
label: 'h',
initialValue: state.hours.toString(),
onChanged: (value) {
int hours = int.tryParse(value) ?? 0;
context.read<WaterHeaterBloc>().add(UpdateScheduleEvent(
scheduleMode: state.scheduleMode,
hours: hours,
minutes: state.minutes,
));
},
),
const SizedBox(width: 10),
// Minutes input
_buildTimeInputField(
label: 'm',
initialValue: state.minutes.toString(),
onChanged: (value) {
int minutes = int.tryParse(value) ?? 0;
context.read<WaterHeaterBloc>().add(UpdateScheduleEvent(
scheduleMode: state.scheduleMode,
hours: state.hours,
minutes: minutes,
));
},
),
],
),
],
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.of(context)
.pop(); // Close the dialog or scheduling view
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey[400],
),
child: const Text('Cancel'),
),
const SizedBox(width: 20),
ElevatedButton(
onPressed: () {
// Handle saving schedule logic
},
child: const Text('Save'),
),
],
),
],
),
);
}
Widget _buildTimeInputField({
required String label,
required String initialValue,
required Function(String) onChanged,
}) {
return Column(
children: [
Text(label, style: const TextStyle(fontSize: 18)),
SizedBox(
width: 50,
child: TextField(
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
decoration: const InputDecoration(border: UnderlineInputBorder()),
onChanged: onChanged,
controller: TextEditingController(text: initialValue),
),
),
],
);
}
}