E32221324_Iot_Running/lib/screens/monitoring_screen.dart

118 lines
3.7 KiB
Dart

import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'result_screen.dart';
class MonitoringScreen extends StatefulWidget {
final String userId;
const MonitoringScreen({Key? key, required this.userId}) : super(key: key);
@override
State<MonitoringScreen> createState() => _MonitoringScreenState();
}
class _MonitoringScreenState extends State<MonitoringScreen> {
late DatabaseReference _activityRef;
StreamSubscription<DatabaseEvent>? _subscription;
bool _navigated = false;
@override
void initState() {
super.initState();
final db = FirebaseDatabase.instanceFor(
app: Firebase.app(),
databaseURL: "https://ta-running-default-rtdb.asia-southeast1.firebasedatabase.app",
);
_activityRef = db.ref("activities/${widget.userId}");
_subscription = _activityRef.onValue.listen((event) {
final raw = event.snapshot.value;
if (raw is Map) {
final data = Map<String, dynamic>.from(raw);
// ✅ Cek dan simpan startTime jika status == 'running' dan startTime belum ada
if (data['status'] == 'running' && data['startTime'] == null) {
final now = DateTime.now().toUtc(); // ambil SEKALI dalam UTC
final nowMillis = now.millisecondsSinceEpoch;
final nowIso = now.toIso8601String();
_activityRef.update({
'startTime': nowMillis,
'laps/lap_0/timestamp': nowIso,
});
print("⏱️ startTime dan lap_0 disimpan ke RTDB: $nowIso");
}
// ✅ Saat status 'done', proses navigasi dan simpan durasi
if (!_navigated && data['status'] == 'done') {
_navigated = true;
_subscription?.cancel();
int? dur;
if (data['startTime'] != null) {
final now = DateTime.now().millisecondsSinceEpoch;
dur = now - (data['startTime'] as int);
_activityRef.update({'duration': dur});
data['duration'] = dur;
}
final type = data['type'];
final rawJarak = data['jarak'];
final satuan = data['satuan'] ?? 'M';
double jarakKm = 0;
if (rawJarak != null) {
jarakKm = satuan == 'KM'
? (rawJarak as num).toDouble()
: (rawJarak as num).toDouble() / 1000.0;
}
if (type == 'non-lintasan' && jarakKm > 0 && dur != null) {
final durSec = dur / 1000.0;
final pacePerKmSec = durSec / jarakKm;
_activityRef.update({'pace_sec_per_km': pacePerKmSec});
data['pace_sec_per_km'] = pacePerKmSec;
}
data['uidTag'] = widget.userId;
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => ResultScreen(activityData: data),
),
);
}
}
});
}
@override
void dispose() {
_subscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return const Scaffold(
backgroundColor: Colors.white,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(color: Colors.blueAccent),
SizedBox(height: 20),
Text(
'Aktivitas sedang berlangsung...',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
],
),
),
);
}
}