push save and stop buttons

This commit is contained in:
ashrafzarkanisala
2024-09-19 01:31:52 +03:00
parent ba95f6774b
commit b3807f2980
6 changed files with 179 additions and 45 deletions

View File

@ -12,7 +12,6 @@ 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,37 +22,23 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
FutureOr<void> _updateScheduleEvent(
UpdateScheduleEvent event,
Emitter<WaterHeaterState> emit,
) {
) async {
final currentState = state as WaterHeaterScheduleViewState;
final countdownRemaining = currentState.isActive
? currentState.countdownRemaining
: Duration(hours: event.hours, minutes: event.minutes);
emit(WaterHeaterScheduleViewState(
scheduleMode: event.scheduleMode,
hours: event.hours,
minutes: event.minutes,
isActive: true,
hours: countdownRemaining!.inHours,
minutes: countdownRemaining.inMinutes % 60,
isActive: currentState.isActive,
countdownRemaining: countdownRemaining,
));
}
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,
) {
if (state is WaterHeaterScheduleViewState) {
final currentState = state as WaterHeaterScheduleViewState;
emit(WaterHeaterScheduleViewState(
scheduleMode: currentState.scheduleMode,
hours: currentState.hours,
minutes: currentState.minutes,
isActive: false,
));
if (currentState.isActive) {
_startCountdown(countdownRemaining, emit);
}
}
@ -65,22 +50,39 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
emit(WaterHeaterDeviceStatusLoaded(deviceStatus));
await _runDebounce(
final success = await _runDebounce(
deviceId: event.deviceId,
code: event.code,
value: event.value,
oldValue: oldValue,
emit: emit,
);
if (success &&
(event.code == "countdown_1" || event.code == "switch_inching")) {
final countdownDuration = Duration(seconds: event.value);
emit(WaterHeaterScheduleViewState(
scheduleMode: deviceStatus.scheduleMode,
hours: countdownDuration.inHours,
minutes: (countdownDuration.inMinutes % 60),
isActive: true,
countdownRemaining: countdownDuration,
));
_startCountdown(countdownDuration, emit);
}
}
Future<void> _runDebounce({
Future<bool> _runDebounce({
required String deviceId,
required String code,
required dynamic value,
required dynamic oldValue,
required Emitter<WaterHeaterState> emit,
}) async {
final completer = Completer<bool>();
if (_timer != null) {
_timer!.cancel();
}
@ -94,11 +96,17 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
if (!status) {
_revertValueAndEmit(deviceId, code, oldValue, emit);
completer.complete(false);
} else {
completer.complete(true);
}
} catch (e) {
_revertValueAndEmit(deviceId, code, oldValue, emit);
completer.complete(false);
}
});
return completer.future;
}
void _revertValueAndEmit(String deviceId, String code, dynamic oldValue,
@ -140,12 +148,81 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
deviceStatus =
WaterHeaterStatusModel.fromJson(event.deviceId, status.status);
emit(WaterHeaterDeviceStatusLoaded(deviceStatus));
if (deviceStatus.countdownHours > 0 ||
deviceStatus.countdownMinutes > 0) {
final remainingDuration = Duration(
hours: deviceStatus.countdownHours,
minutes: deviceStatus.countdownMinutes,
);
emit(WaterHeaterScheduleViewState(
scheduleMode: deviceStatus.scheduleMode,
hours: deviceStatus.countdownHours,
minutes: deviceStatus.countdownMinutes,
isActive: true,
countdownRemaining: remainingDuration,
));
_startCountdown(remainingDuration, emit);
} else {
emit(WaterHeaterScheduleViewState(
scheduleMode: deviceStatus.scheduleMode,
hours: 0,
minutes: 0,
isActive: false,
));
}
} catch (e) {
emit(WaterHeaterFailedState(error: e.toString()));
}
}
void _startCountdown(Duration duration, Emitter<WaterHeaterState> emit) {
_timer?.cancel();
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
final state = this.state as WaterHeaterScheduleViewState;
final remaining = state.countdownRemaining! - const Duration(seconds: 1);
if (remaining.isNegative || remaining == Duration.zero) {
_timer?.cancel();
emit(WaterHeaterScheduleViewState(
scheduleMode: state.scheduleMode,
hours: 0,
minutes: 0,
isActive: false,
countdownRemaining: Duration.zero,
));
} else {
emit(WaterHeaterScheduleViewState(
scheduleMode: state.scheduleMode,
hours: remaining.inHours,
minutes: remaining.inMinutes % 60,
isActive: true,
countdownRemaining: remaining,
));
}
});
}
FutureOr<void> _stopScheduleEvent(
StopScheduleEvent event,
Emitter<WaterHeaterState> emit,
) {
_timer?.cancel();
deviceStatus = deviceStatus.copyWith(
countdownHours: 0,
countdownMinutes: 0,
scheduleMode: ScheduleModes.countdown,
);
emit(const WaterHeaterScheduleViewState(
scheduleMode: ScheduleModes.countdown,
hours: 0,
minutes: 0,
isActive: false,
));
}
@override
Future<void> close() {
_timer?.cancel();

View File

@ -51,6 +51,6 @@ class WaterHeaterFetchBatchStatusEvent extends WaterHeaterEvent {
List<Object?> get props => [deviceId];
}
class ShowScheduleViewEvent extends WaterHeaterEvent {
const ShowScheduleViewEvent();
}
// class ShowScheduleViewEvent extends WaterHeaterEvent {
// const ShowScheduleViewEvent();
// }

View File

@ -45,14 +45,17 @@ class WaterHeaterScheduleViewState extends WaterHeaterState {
final int hours;
final int minutes;
final bool isActive;
final Duration? countdownRemaining;
const WaterHeaterScheduleViewState({
required this.scheduleMode,
required this.hours,
required this.minutes,
required this.isActive,
this.countdownRemaining,
});
@override
List<Object> get props => [scheduleMode, hours, minutes];
List<Object?> get props =>
[scheduleMode, hours, minutes, isActive, countdownRemaining];
}

View File

@ -23,8 +23,7 @@ class WaterHeaterStatusModel {
factory WaterHeaterStatusModel.fromJson(String id, List<Status> jsonList) {
late bool heaterSwitch = false;
late int countdownHours = 0;
late int countdownMinutes = 0;
late int countdownInSeconds = 0;
late String relayStatus = '';
late String cycleTiming = '';
late ScheduleModes scheduleMode = ScheduleModes.countdown;
@ -35,7 +34,7 @@ class WaterHeaterStatusModel {
heaterSwitch = status.value ?? false;
break;
case 'countdown_1':
countdownHours = status.value ?? 0;
countdownInSeconds = status.value ?? 0;
break;
case 'relay_status':
relayStatus = status.value ?? 'memory';
@ -49,6 +48,10 @@ class WaterHeaterStatusModel {
}
}
final countdownHours = countdownInSeconds ~/ 3600;
final countdownMinutes =
(countdownInSeconds % 3600) ~/ 60;
return WaterHeaterStatusModel(
uuid: id,
heaterSwitch: heaterSwitch,

View File

@ -75,7 +75,7 @@ class WaterHeaterDeviceControl extends StatelessWidget
),
GestureDetector(
onTap: () {
context.read<WaterHeaterBloc>().add(const ShowScheduleViewEvent());
// context.read<WaterHeaterBloc>().add(const ShowScheduleViewEvent());
showDialog(
context: context,
builder: (ctx) => BlocProvider.value(

View File

@ -208,9 +208,11 @@ class BuildScheduleView extends StatelessWidget {
Center(
child: SizedBox(
width: 400,
height: 50,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: DefaultButton(
@ -227,10 +229,59 @@ class BuildScheduleView extends StatelessWidget {
),
const SizedBox(width: 20),
Expanded(
child: DefaultButton(
child: (state.countdownRemaining != null &&
state.isActive)
? DefaultButton(
height: 40,
onPressed: () {},
backgroundColor: ColorsManager.primaryColor,
onPressed: () {
late String code;
if (state.scheduleMode ==
ScheduleModes.countdown) {
code = 'countdown_1';
} else if (state.scheduleMode ==
ScheduleModes.inching) {
code = 'switch_inching';
}
context
.read<WaterHeaterBloc>()
.add(StopScheduleEvent());
context.read<WaterHeaterBloc>().add(
ToggleWaterHeaterEvent(
deviceId: status.uuid,
code: code,
value: 0,
),
);
},
backgroundColor: Colors.red,
child: const Text('Stop'),
)
: DefaultButton(
height: 40,
onPressed: () {
late String code;
if (state.scheduleMode ==
ScheduleModes.countdown) {
code = 'countdown_1';
} else if (state.scheduleMode ==
ScheduleModes.inching) {
code = 'switch_inching';
}
context.read<WaterHeaterBloc>().add(
ToggleWaterHeaterEvent(
deviceId: status.uuid,
code: code,
// value is time in seconds
value: Duration(
hours: state.hours,
minutes:
state.minutes)
.inSeconds,
),
);
},
backgroundColor:
ColorsManager.primaryColor,
child: const Text('Save'),
),
),