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()) {
|
WaterHeaterBloc() : super(WaterHeaterInitial()) {
|
||||||
on<WaterHeaterFetchStatusEvent>(_fetchWaterHeaterStatus);
|
on<WaterHeaterFetchStatusEvent>(_fetchWaterHeaterStatus);
|
||||||
on<ToggleWaterHeaterEvent>(_controlWaterHeater);
|
on<ToggleWaterHeaterEvent>(_controlWaterHeater);
|
||||||
on<ShowScheduleViewEvent>(_showScheduleView);
|
|
||||||
on<UpdateScheduleEvent>(_updateScheduleEvent);
|
on<UpdateScheduleEvent>(_updateScheduleEvent);
|
||||||
on<StopScheduleEvent>(_stopScheduleEvent);
|
on<StopScheduleEvent>(_stopScheduleEvent);
|
||||||
}
|
}
|
||||||
@ -23,37 +22,23 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
FutureOr<void> _updateScheduleEvent(
|
FutureOr<void> _updateScheduleEvent(
|
||||||
UpdateScheduleEvent event,
|
UpdateScheduleEvent event,
|
||||||
Emitter<WaterHeaterState> emit,
|
Emitter<WaterHeaterState> emit,
|
||||||
) {
|
) async {
|
||||||
|
final currentState = state as WaterHeaterScheduleViewState;
|
||||||
|
|
||||||
|
final countdownRemaining = currentState.isActive
|
||||||
|
? currentState.countdownRemaining
|
||||||
|
: Duration(hours: event.hours, minutes: event.minutes);
|
||||||
|
|
||||||
emit(WaterHeaterScheduleViewState(
|
emit(WaterHeaterScheduleViewState(
|
||||||
scheduleMode: event.scheduleMode,
|
scheduleMode: event.scheduleMode,
|
||||||
hours: event.hours,
|
hours: countdownRemaining!.inHours,
|
||||||
minutes: event.minutes,
|
minutes: countdownRemaining.inMinutes % 60,
|
||||||
isActive: true,
|
isActive: currentState.isActive,
|
||||||
|
countdownRemaining: countdownRemaining,
|
||||||
));
|
));
|
||||||
}
|
|
||||||
|
|
||||||
FutureOr<void> _showScheduleView(
|
if (currentState.isActive) {
|
||||||
ShowScheduleViewEvent event, Emitter<WaterHeaterState> emit) {
|
_startCountdown(countdownRemaining, 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,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,22 +50,39 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
|
|
||||||
emit(WaterHeaterDeviceStatusLoaded(deviceStatus));
|
emit(WaterHeaterDeviceStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
await _runDebounce(
|
final success = await _runDebounce(
|
||||||
deviceId: event.deviceId,
|
deviceId: event.deviceId,
|
||||||
code: event.code,
|
code: event.code,
|
||||||
value: event.value,
|
value: event.value,
|
||||||
oldValue: oldValue,
|
oldValue: oldValue,
|
||||||
emit: emit,
|
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 deviceId,
|
||||||
required String code,
|
required String code,
|
||||||
required dynamic value,
|
required dynamic value,
|
||||||
required dynamic oldValue,
|
required dynamic oldValue,
|
||||||
required Emitter<WaterHeaterState> emit,
|
required Emitter<WaterHeaterState> emit,
|
||||||
}) async {
|
}) async {
|
||||||
|
final completer = Completer<bool>();
|
||||||
|
|
||||||
if (_timer != null) {
|
if (_timer != null) {
|
||||||
_timer!.cancel();
|
_timer!.cancel();
|
||||||
}
|
}
|
||||||
@ -94,11 +96,17 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
_revertValueAndEmit(deviceId, code, oldValue, emit);
|
_revertValueAndEmit(deviceId, code, oldValue, emit);
|
||||||
|
completer.complete(false);
|
||||||
|
} else {
|
||||||
|
completer.complete(true);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_revertValueAndEmit(deviceId, code, oldValue, emit);
|
_revertValueAndEmit(deviceId, code, oldValue, emit);
|
||||||
|
completer.complete(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _revertValueAndEmit(String deviceId, String code, dynamic oldValue,
|
void _revertValueAndEmit(String deviceId, String code, dynamic oldValue,
|
||||||
@ -140,12 +148,81 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
deviceStatus =
|
deviceStatus =
|
||||||
WaterHeaterStatusModel.fromJson(event.deviceId, status.status);
|
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) {
|
} catch (e) {
|
||||||
emit(WaterHeaterFailedState(error: e.toString()));
|
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
|
@override
|
||||||
Future<void> close() {
|
Future<void> close() {
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
|
@ -51,6 +51,6 @@ class WaterHeaterFetchBatchStatusEvent extends WaterHeaterEvent {
|
|||||||
List<Object?> get props => [deviceId];
|
List<Object?> get props => [deviceId];
|
||||||
}
|
}
|
||||||
|
|
||||||
class ShowScheduleViewEvent extends WaterHeaterEvent {
|
// class ShowScheduleViewEvent extends WaterHeaterEvent {
|
||||||
const ShowScheduleViewEvent();
|
// const ShowScheduleViewEvent();
|
||||||
}
|
// }
|
||||||
|
@ -45,14 +45,17 @@ class WaterHeaterScheduleViewState extends WaterHeaterState {
|
|||||||
final int hours;
|
final int hours;
|
||||||
final int minutes;
|
final int minutes;
|
||||||
final bool isActive;
|
final bool isActive;
|
||||||
|
final Duration? countdownRemaining;
|
||||||
|
|
||||||
const WaterHeaterScheduleViewState({
|
const WaterHeaterScheduleViewState({
|
||||||
required this.scheduleMode,
|
required this.scheduleMode,
|
||||||
required this.hours,
|
required this.hours,
|
||||||
required this.minutes,
|
required this.minutes,
|
||||||
required this.isActive,
|
required this.isActive,
|
||||||
|
this.countdownRemaining,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@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) {
|
factory WaterHeaterStatusModel.fromJson(String id, List<Status> jsonList) {
|
||||||
late bool heaterSwitch = false;
|
late bool heaterSwitch = false;
|
||||||
late int countdownHours = 0;
|
late int countdownInSeconds = 0;
|
||||||
late int countdownMinutes = 0;
|
|
||||||
late String relayStatus = '';
|
late String relayStatus = '';
|
||||||
late String cycleTiming = '';
|
late String cycleTiming = '';
|
||||||
late ScheduleModes scheduleMode = ScheduleModes.countdown;
|
late ScheduleModes scheduleMode = ScheduleModes.countdown;
|
||||||
@ -35,7 +34,7 @@ class WaterHeaterStatusModel {
|
|||||||
heaterSwitch = status.value ?? false;
|
heaterSwitch = status.value ?? false;
|
||||||
break;
|
break;
|
||||||
case 'countdown_1':
|
case 'countdown_1':
|
||||||
countdownHours = status.value ?? 0;
|
countdownInSeconds = status.value ?? 0;
|
||||||
break;
|
break;
|
||||||
case 'relay_status':
|
case 'relay_status':
|
||||||
relayStatus = status.value ?? 'memory';
|
relayStatus = status.value ?? 'memory';
|
||||||
@ -49,6 +48,10 @@ class WaterHeaterStatusModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final countdownHours = countdownInSeconds ~/ 3600;
|
||||||
|
final countdownMinutes =
|
||||||
|
(countdownInSeconds % 3600) ~/ 60;
|
||||||
|
|
||||||
return WaterHeaterStatusModel(
|
return WaterHeaterStatusModel(
|
||||||
uuid: id,
|
uuid: id,
|
||||||
heaterSwitch: heaterSwitch,
|
heaterSwitch: heaterSwitch,
|
||||||
|
@ -75,7 +75,7 @@ class WaterHeaterDeviceControl extends StatelessWidget
|
|||||||
),
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.read<WaterHeaterBloc>().add(const ShowScheduleViewEvent());
|
// context.read<WaterHeaterBloc>().add(const ShowScheduleViewEvent());
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (ctx) => BlocProvider.value(
|
builder: (ctx) => BlocProvider.value(
|
||||||
|
@ -208,9 +208,11 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
Center(
|
Center(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 400,
|
width: 400,
|
||||||
|
height: 50,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DefaultButton(
|
child: DefaultButton(
|
||||||
@ -227,12 +229,61 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: 20),
|
const SizedBox(width: 20),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DefaultButton(
|
child: (state.countdownRemaining != null &&
|
||||||
height: 40,
|
state.isActive)
|
||||||
onPressed: () {},
|
? DefaultButton(
|
||||||
backgroundColor: ColorsManager.primaryColor,
|
height: 40,
|
||||||
child: const Text('Save'),
|
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