mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
push save and stop buttons
This commit is contained in:
@ -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();
|
||||
|
@ -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();
|
||||
// }
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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'),
|
||||
),
|
||||
),
|
||||
|
Reference in New Issue
Block a user