updated the sheet
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:miler/views/helpers/constants/apiconstants.dart';
|
||||
import 'package:miler/Models/riders/riders_models.dart';
|
||||
import 'package:miler/providers/Riderlog/riderlog_provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@@ -16,6 +15,7 @@ import 'package:miler/background/foreground_service.dart' as fg;
|
||||
import 'package:miler/utils/kalman_filter.dart';
|
||||
import 'package:miler/utils/mqtt_service.dart';
|
||||
import 'package:miler/data/device_telemetry.dart';
|
||||
import 'package:miler/data/heartbeat.dart';
|
||||
import 'package:miler/views/helpers/constants/mqtt_constants.dart';
|
||||
import 'package:battery_plus/battery_plus.dart';
|
||||
import 'package:miler/controllers/connectivity_mixin.dart';
|
||||
@@ -235,7 +235,7 @@ class RiderLogController extends GetxController
|
||||
|
||||
// ✅ Check if there are active pickup to set status
|
||||
final bool hasActivePickups = prefs.getBool('has_live_pickup') ?? false;
|
||||
final String riderStatus = hasActivePickups ? 'active' : 'idle';
|
||||
final String riderStatus = heartbeatStatus(hasActiveWork: hasActivePickups);
|
||||
final String orderId = prefs.getString('current_riding_order_id') ?? '';
|
||||
debugPrint(
|
||||
'[RIDERLOG][CREATE LOGIN NOW] Active pickup: $hasActivePickups -> status: $riderStatus',
|
||||
@@ -315,7 +315,7 @@ class RiderLogController extends GetxController
|
||||
|
||||
// 1. Lane: Status
|
||||
mqttService.updateStatus(
|
||||
riderStatus == 'active' ? 'Active' : MqttConstants.statusOnline,
|
||||
riderStatus == 'On_Pickup' ? 'Active' : MqttConstants.statusOnline,
|
||||
);
|
||||
|
||||
// 2. Lane: Profile (Send only if significantly changed or first time)
|
||||
@@ -448,7 +448,7 @@ class RiderLogController extends GetxController
|
||||
// Check status for offline fallback too
|
||||
final bool hasActivePickups =
|
||||
prefs.getBool('has_live_pickup') ?? false;
|
||||
final String riderStatus = hasActivePickups ? 'active' : 'idle';
|
||||
final String riderStatus = heartbeatStatus(hasActiveWork: hasActivePickups);
|
||||
|
||||
final Map<String, dynamic> payload = {
|
||||
...baseTemplate,
|
||||
@@ -520,10 +520,19 @@ class RiderLogController extends GetxController
|
||||
await prefs.setInt('onduty', on ? 1 : 0);
|
||||
if (on) {
|
||||
await createLoginNowV2();
|
||||
final int interval = prefs.getInt('logseconds') ?? 0;
|
||||
if (interval > 0) {
|
||||
startAutoCreateLoginLoop(seconds: interval);
|
||||
}
|
||||
// ── Going on duty always starts the heartbeat ──
|
||||
//
|
||||
// This was gated on `interval > 0`, reading a stored zero as a
|
||||
// decision not to beat. The v1 login has no `logseconds` to store, so
|
||||
// the gate was shut on every rider: duty went on, one log was posted
|
||||
// by the call above, and nothing followed it — no telemetry trail and
|
||||
// no location writes for the rest of the shift.
|
||||
//
|
||||
// There is no cadence at which a rider on duty should not report, so
|
||||
// there is no branch here any more. [resolveLogSeconds] supplies the
|
||||
// floor when the hub has not set one.
|
||||
final int interval = resolveLogSeconds(prefs.getInt('logseconds'));
|
||||
startAutoCreateLoginLoop(seconds: interval);
|
||||
|
||||
// Ensure foreground logging notification is started when going on-duty
|
||||
try {
|
||||
@@ -590,15 +599,45 @@ class RiderLogController extends GetxController
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the periodic heartbeat is currently running on the stream path.
|
||||
///
|
||||
/// ── Why a test needs to be able to see this ──
|
||||
///
|
||||
/// The `logseconds` bug was invisible from outside the class. Duty went on,
|
||||
/// the API accepted it, one log was posted by the immediate call — and the
|
||||
/// loop that was supposed to follow it simply never started. Nothing threw,
|
||||
/// nothing logged an error, and the only symptom was a console panel that had
|
||||
/// been blank for so long it read as a backend problem.
|
||||
///
|
||||
/// Android normally runs the heartbeat as a foreground service instead, and
|
||||
/// leaves this null; the test host is never Android, so the stream path is
|
||||
/// the one under test. See [startAutoCreateLoginLoop].
|
||||
@visibleForTesting
|
||||
bool get autoLoopRunning => _autoLoginSubscription != null;
|
||||
|
||||
// Start periodic createRiderLog calls based on seconds (or prefs 'logseconds')
|
||||
// ✅ CRITICAL: When there are active pickup, use 30 seconds (same as pickup logs)
|
||||
// Otherwise, use the configured logseconds interval
|
||||
void startAutoCreateLoginLoop({int? seconds}) async {
|
||||
/// `Future<void>`, not `void`. It was fire-and-forget, which meant no caller
|
||||
/// could wait for the loop to actually be up — and the one place that most
|
||||
/// wanted to, [setOnDuty], had no way to tell whether the heartbeat it had
|
||||
/// just asked for existed. Every existing call site ignores the future and is
|
||||
/// unchanged by this.
|
||||
Future<void> startAutoCreateLoginLoop({int? seconds}) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
// ✅ Check if there are active pickup - if yes, use 30 seconds (same as pickup logs)
|
||||
final bool hasActivePickups = prefs.getBool('has_live_pickup') ?? false;
|
||||
final int baseInterval = seconds ?? (prefs.getInt('logseconds') ?? 0);
|
||||
// ── The configured cadence, or the floor under it ──
|
||||
//
|
||||
// `?? 0` here was the second half of the same bug as the one in
|
||||
// [setOnDuty]: a caller that passes no `seconds` — the app-resume path in
|
||||
// `main.dart` is one — fell through to a stored zero and then returned at
|
||||
// the `interval <= 0` guard below, so the loop the resume was trying to
|
||||
// revive silently did not start. See [resolveLogSeconds].
|
||||
final int baseInterval = resolveLogSeconds(
|
||||
seconds ?? prefs.getInt('logseconds'),
|
||||
);
|
||||
|
||||
// When there are active pickup, post rider logs every 30 seconds (matching pickup logs)
|
||||
// Otherwise, use the configured interval
|
||||
@@ -610,12 +649,20 @@ class RiderLogController extends GetxController
|
||||
);
|
||||
}
|
||||
|
||||
await stopAutoCreateLoginLoop(); // Cancel existing subscription
|
||||
// Stop before start, which is what keeps this method safe to call from the
|
||||
// three places that do — going on duty, resuming the app, and a pickup
|
||||
// going live. Whichever arrives last wins, and there is never a second
|
||||
// loop: the subscription is cancelled and the foreground service stopped
|
||||
// before either is created again.
|
||||
await stopAutoCreateLoginLoop();
|
||||
|
||||
// Attempt to flush offline logs on loop start
|
||||
flushOfflineLogs();
|
||||
|
||||
if (interval <= 0) return;
|
||||
// No `interval <= 0` guard. [resolveLogSeconds] cannot return one, and the
|
||||
// guard that used to be here is what turned a missing `logseconds` into a
|
||||
// rider who never reported. Duty state decides whether the loop runs; the
|
||||
// cadence only decides how often.
|
||||
final int onduty = prefs.getInt('onduty') ?? 0;
|
||||
if (onduty != 1) {
|
||||
debugPrint('[RIDERLOG][AUTO LOOP] Not starting - onduty=$onduty');
|
||||
@@ -1049,9 +1096,6 @@ class RiderLogController extends GetxController
|
||||
final breakhoursDouble = duration.inSeconds / 3600.0;
|
||||
|
||||
// Debug logs for terminal visibility
|
||||
debugPrint(
|
||||
'[BREAK][UPDATE] URL: ${ApiConstants.mainRoute == 'live' ? ApiConstants.updateBreakRiderLogLive : ApiConstants.updateBreakRiderLogDev}',
|
||||
);
|
||||
debugPrint(
|
||||
'[BREAK][UPDATE] Fields: breakid=$breakid, logid=$logid, userid=$userid, partnerid=$partnerid, shiftid=$shiftid, breakend=$breakend, breakhours=$breakhoursDouble, lat=$latitude, lng=$longitude',
|
||||
);
|
||||
@@ -1107,7 +1151,7 @@ class RiderLogController extends GetxController
|
||||
|
||||
// ✅ Check if there are active pickup to set status
|
||||
final bool hasActivePickups = prefs.getBool('has_live_pickup') ?? false;
|
||||
final String riderStatus = hasActivePickups ? 'active' : 'idle';
|
||||
final String riderStatus = heartbeatStatus(hasActiveWork: hasActivePickups);
|
||||
|
||||
// Resolve rider display name (username) from prefs to include in log
|
||||
String? username = prefs.getString('username');
|
||||
|
||||
Reference in New Issue
Block a user