This commit is contained in:
kleponijo 2026-05-13 22:40:30 +07:00
parent 2d2c8c0cab
commit 2ff3bd3306
4 changed files with 22 additions and 21 deletions

View File

@ -99,6 +99,7 @@ class EvaporasiBloc extends Bloc<EvaporasiEvent, EvaporasiState> {
weatherStatus: status, weatherStatus: status,
willRain: rain, willRain: rain,
listData: listData, listData: listData,
currentData: history.isNotEmpty ? history.last : null,
isLoading: false, isLoading: false,
)); ));
@ -116,17 +117,9 @@ class EvaporasiBloc extends Bloc<EvaporasiEvent, EvaporasiState> {
final previous = final previous =
state.history.isNotEmpty ? state.history.last.timestamp : null; state.history.isNotEmpty ? state.history.last.timestamp : null;
final updatedHistory = List<Evaporasi>.from(state.history)..add(event.data);
final isDuplicate =
previous != null && event.data.timestamp.toUtc() == previous.toUtc();
// Update bucket berdasarkan timestamp event (bukan jam lokal sekarang). // Update bucket berdasarkan timestamp event (bukan jam lokal sekarang).
final updated = final updated = List<double>.from(state.dailyValues);
isDuplicate ? state.dailyValues : List<double>.from(state.dailyValues); final updatedTemp = List<double>.from(state.dailyTemperatures);
final updatedTemp = isDuplicate
? state.dailyTemperatures
: List<double>.from(state.dailyTemperatures);
final eventTime = event.data.timestamp; final eventTime = event.data.timestamp;
final now = DateTime.now(); final now = DateTime.now();
@ -147,8 +140,6 @@ class EvaporasiBloc extends Bloc<EvaporasiEvent, EvaporasiState> {
_emitEvaporasiAlert(status, rain, event.data.evaporasi); _emitEvaporasiAlert(status, rain, event.data.evaporasi);
emit(state.copyWith( emit(state.copyWith(
history: updatedHistory,
listData: updatedHistory,
currentValue: event.data.evaporasi, currentValue: event.data.evaporasi,
temperature: event.data.suhu, temperature: event.data.suhu,
waterLevel: event.data.tinggiAir, waterLevel: event.data.tinggiAir,
@ -156,6 +147,7 @@ class EvaporasiBloc extends Bloc<EvaporasiEvent, EvaporasiState> {
dailyTemperatures: updatedTemp, dailyTemperatures: updatedTemp,
weatherStatus: status, weatherStatus: status,
willRain: rain, willRain: rain,
currentData: event.data,
)); ));
} }

View File

@ -31,6 +31,8 @@ class EvaporasiState extends Equatable {
final String weatherStatus; final String weatherStatus;
final bool willRain; final bool willRain;
final Evaporasi? currentData; // data realtime terbaru
final bool isLoading; final bool isLoading;
const EvaporasiState({ const EvaporasiState({
@ -51,6 +53,7 @@ class EvaporasiState extends Equatable {
this.history = const [], this.history = const [],
this.weatherStatus = 'Baik', this.weatherStatus = 'Baik',
this.willRain = false, this.willRain = false,
this.currentData,
this.isLoading = true, this.isLoading = true,
}); });
@ -72,6 +75,7 @@ class EvaporasiState extends Equatable {
List<Evaporasi>? history, List<Evaporasi>? history,
String? weatherStatus, String? weatherStatus,
bool? willRain, bool? willRain,
Evaporasi? currentData,
bool? isLoading, bool? isLoading,
}) { }) {
return EvaporasiState( return EvaporasiState(
@ -92,6 +96,7 @@ class EvaporasiState extends Equatable {
history: history ?? this.history, history: history ?? this.history,
weatherStatus: weatherStatus ?? this.weatherStatus, weatherStatus: weatherStatus ?? this.weatherStatus,
willRain: willRain ?? this.willRain, willRain: willRain ?? this.willRain,
currentData: currentData ?? this.currentData,
isLoading: isLoading ?? this.isLoading, isLoading: isLoading ?? this.isLoading,
); );
} }
@ -115,7 +120,7 @@ class EvaporasiState extends Equatable {
history, history,
weatherStatus, weatherStatus,
willRain, willRain,
currentData,
isLoading, isLoading,
]; ];
} }

View File

@ -290,15 +290,21 @@ class _EvaporasiScreenState extends State<EvaporasiScreen> {
/// 🧾 LIST DATA EVAPORASI /// 🧾 LIST DATA EVAPORASI
/// ========================= /// =========================
Widget _evaporasiList(EvaporasiState state) { Widget _evaporasiList(EvaporasiState state) {
final data = state.viewMode == EvaporasiViewMode.customDate && final allData = [...state.history];
if (state.currentData != null) {
allData.add(state.currentData!);
}
final data = (state.viewMode == EvaporasiViewMode.customDate &&
state.selectedDate != null state.selectedDate != null
? state.history ? allData
.where((e) => .where((e) =>
e.timestamp.year == state.selectedDate!.year && e.timestamp.year == state.selectedDate!.year &&
e.timestamp.month == state.selectedDate!.month && e.timestamp.month == state.selectedDate!.month &&
e.timestamp.day == state.selectedDate!.day) e.timestamp.day == state.selectedDate!.day)
.toList() .toList()
: state.history; : List.of(allData))
..sort((a, b) => b.timestamp.compareTo(a.timestamp));
if (data.isEmpty) { if (data.isEmpty) {
return Container( return Container(
@ -423,7 +429,6 @@ class _EvaporasiScreenState extends State<EvaporasiScreen> {
} }
String _formatDateInfo(DateTime date) { String _formatDateInfo(DateTime date) {
final now = DateTime.now(); final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day); final today = DateTime(now.year, now.month, now.day);
@ -439,4 +444,3 @@ class _EvaporasiScreenState extends State<EvaporasiScreen> {
} }
} }
} }

View File

@ -96,7 +96,7 @@ class Evaporasi {
// Default timestamp: fallback now (kalau field waktu tidak ada). // Default timestamp: fallback now (kalau field waktu tidak ada).
// Catatan: untuk Firebase seharusnya timestamp dikirim konsisten (ms atau ISO string). // Catatan: untuk Firebase seharusnya timestamp dikirim konsisten (ms atau ISO string).
DateTime timestamp = DateTime.now(); DateTime timestamp = DateTime.fromMillisecondsSinceEpoch(0);
// dukung beberapa kemungkinan penamaan timestamp // dukung beberapa kemungkinan penamaan timestamp
final rawTimestamp = json['timestamp'] ?? json['time'] ?? json['datetime']; final rawTimestamp = json['timestamp'] ?? json['time'] ?? json['datetime'];
@ -120,7 +120,7 @@ class Evaporasi {
} else { } else {
final parsed = DateTime.tryParse(s); final parsed = DateTime.tryParse(s);
if (parsed != null) { if (parsed != null) {
timestamp = parsed; timestamp = parsed.toLocal();
} }
} }
} }
@ -129,7 +129,7 @@ class Evaporasi {
final datetimeStr = json['datetime'] as String?; final datetimeStr = json['datetime'] as String?;
if (datetimeStr != null) { if (datetimeStr != null) {
final parsed = DateTime.tryParse(datetimeStr); final parsed = DateTime.tryParse(datetimeStr);
if (parsed != null) timestamp = parsed; if (parsed != null) timestamp = parsed.toLocal();
} }
final waktuStr = json['waktu'] as String?; final waktuStr = json['waktu'] as String?;