Begin adding the work data visualizer

This commit is contained in:
zontreck 2025-05-15 22:49:18 -07:00
parent 7e78ed323d
commit 5bc49b4cff
9 changed files with 294 additions and 13 deletions

View file

@ -1,15 +1,14 @@
import 'dart:async';
import 'dart:convert';
import 'dart:math' as math;
import 'dart:ui';
import 'package:geolocator/geolocator.dart';
import 'package:libac_dart/utils/TimeUtils.dart';
import 'package:libac_dart/nbt/Stream.dart';
import 'package:timetrack/consts.dart';
class SessionData {
static int StartTime = 0;
static get StartTimeAsDateTime =>
DateTime.fromMillisecondsSinceEpoch(StartTime * 1000);
static DateTime StartTime = DateTime(0);
static bool IsOnTheClock = false;
@ -19,12 +18,121 @@ class SessionData {
static Trip? currentTrip;
static List<Position> positions = [];
static late StreamSubscription<Position> _listener;
static Callbacks Calls = Callbacks();
/// This flag is usually set when data is loaded from a saved state. Or when accessed using the Web version of the app.
static bool IsReadOnly = false;
static double GetTotalBasePay() {
double total = 0;
for (var trip in Trips) {
total += trip.BasePay;
}
return total;
}
static double GetTotalTips() {
double total = 0;
for (var trip in Trips) {
for (var drop in trip.deliveries) {
total += drop.TipAmount;
}
}
return total;
}
static double GetTotalPay() {
return GetTotalBasePay() + GetTotalTips();
}
static double GetTotalMiles() {
double total = 0;
total = _totalMilesTraveled(
positions,
minDistanceMeters: 5,
maxDistanceMeters: 512,
);
return total;
}
static String GetTotalMilesAsString() {
double miles = GetTotalMiles();
if (miles == 0) return "0.0";
List<String> split = miles.toString().split(".");
StringBuilder out = StringBuilder();
out.append(split[0]);
out.append(".");
out.append(split[1].substring(0, 4));
return out.toString();
}
//** Begin AI Generated code */
/// Converts meters miles.
static const _metersPerMile = 1609.344;
/// Radius of the earth in meters (WGS84 mean radius).
static const _earthRadiusM = 6371000.0;
static double _haversineMeters(
double lat1,
double lon1,
double lat2,
double lon2,
) {
final dLat = _deg2rad(lat2 - lat1);
final dLon = _deg2rad(lon2 - lon1);
final a =
math.sin(dLat / 2) * math.sin(dLat / 2) +
math.cos(_deg2rad(lat1)) *
math.cos(_deg2rad(lat2)) *
math.sin(dLon / 2) *
math.sin(dLon / 2);
return _earthRadiusM * 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a));
}
static double _deg2rad(double deg) => deg * math.pi / 180.0;
/// Returns total miles traveled after basic GPSnoise cleanup.
///
/// * [minDistanceMeters] drop segments shorter than this (jitter).
/// * [maxDistanceMeters] drop segments longer than this (impossible jump).
static double _totalMilesTraveled(
List<Position> positions, {
double minDistanceMeters = 5,
double? maxDistanceMeters,
}) {
if (positions.length < 2) return 0;
var meters = 0.0;
for (var i = 1; i < positions.length; i++) {
final p1 = positions[i - 1];
final p2 = positions[i];
final d = _haversineMeters(
p1.latitude,
p1.longitude,
p2.latitude,
p2.longitude,
);
if (d < minDistanceMeters) continue; // too small jitter
if (maxDistanceMeters != null && d > maxDistanceMeters)
continue; // glitch
meters += d;
}
return meters / _metersPerMile;
}
//** End AI Generated code */
static Future<void> Login() async {
StartTime = TimeUtils.getUnixTimestamp();
StartTime = DateTime.now();
IsOnTheClock = true;
bool hasGPS;
@ -60,6 +168,8 @@ class SessionData {
return;
}
positions.add(pos);
SessionData.Calls.dispatch();
});
}
@ -226,3 +336,17 @@ class Trip {
return trip;
}
}
class Callbacks {
VoidCallback? HomeCallback;
VoidCallback? MapCallback;
VoidCallback? UpdateSettingsCallback;
VoidCallback? WorkDataCallback;
void dispatch() {
if (HomeCallback != null) HomeCallback!();
if (MapCallback != null) MapCallback!();
if (UpdateSettingsCallback != null) UpdateSettingsCallback!();
if (WorkDataCallback != null) WorkDataCallback!();
}
}