initial commit: push everything
This commit is contained in:
183
lib/controllers/logcontroller.dart
Normal file
183
lib/controllers/logcontroller.dart
Normal file
@@ -0,0 +1,183 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'package:nearle/providers/deliverylog/deliverylog_provider.dart';
|
||||
import 'package:nearle/views/helpers/constants/apiconstants.dart';
|
||||
import 'package:nearle/background/foreground_service.dart' as fg;
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
|
||||
/// Controller for managing active delivery logs
|
||||
/// Now delegates to the background service for actual logging
|
||||
class LogController extends GetxController {
|
||||
final CreateDeliveryLogProvider _logProvider = CreateDeliveryLogProvider();
|
||||
|
||||
static const String _offlineLogKey = 'offline_delivery_logs';
|
||||
bool _isFlushing = false;
|
||||
|
||||
/// Start the delivery log streaming service (via foreground service)
|
||||
Future<void> startLogging() async {
|
||||
debugPrint('[ACTIVE_DELIVERY_LOG] Requesting start logging...');
|
||||
|
||||
// Attempt to flush offline logs on start
|
||||
flushOfflineLogs();
|
||||
|
||||
// Only show foreground notification when rider is actually on duty
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final int onduty = prefs.getInt('onduty') ?? 0;
|
||||
if (onduty != 1) {
|
||||
debugPrint(
|
||||
'[ACTIVE_DELIVERY_LOG] Skipping startLogging because onduty=$onduty',
|
||||
);
|
||||
return;
|
||||
}
|
||||
} catch (_) {
|
||||
// If prefs fail, continue with best-effort start
|
||||
}
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
if (await FlutterForegroundTask.isRunningService) {
|
||||
debugPrint('[ACTIVE_DELIVERY_LOG] Foreground service already running');
|
||||
return;
|
||||
}
|
||||
|
||||
debugPrint(
|
||||
'[ACTIVE_DELIVERY_LOG] Starting foreground service for delivery logs',
|
||||
);
|
||||
|
||||
FlutterForegroundTask.init(
|
||||
androidNotificationOptions: AndroidNotificationOptions(
|
||||
channelId: 'nearle_bg_service',
|
||||
channelName: 'Background Service',
|
||||
channelDescription:
|
||||
'Keeps Nearle online updates running in background.',
|
||||
channelImportance: NotificationChannelImportance.LOW,
|
||||
priority: NotificationPriority.LOW,
|
||||
),
|
||||
iosNotificationOptions: const IOSNotificationOptions(
|
||||
showNotification: true,
|
||||
playSound: false,
|
||||
),
|
||||
foregroundTaskOptions: ForegroundTaskOptions(
|
||||
interval: 30000, // 30 seconds
|
||||
isOnceEvent: false,
|
||||
autoRunOnBoot: false,
|
||||
allowWakeLock: true,
|
||||
allowWifiLock: true,
|
||||
),
|
||||
);
|
||||
|
||||
// Check permissions before starting service to prevent Android 14 crash
|
||||
final permission = await Geolocator.checkPermission();
|
||||
if (permission == LocationPermission.denied ||
|
||||
permission == LocationPermission.deniedForever) {
|
||||
debugPrint(
|
||||
'[ACTIVE_DELIVERY_LOG] Location permission missing, skipping service start',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await FlutterForegroundTask.startService(
|
||||
notificationTitle: 'Nearle is running',
|
||||
notificationText: 'You are Currently on Duty !',
|
||||
callback: fg.riderLogCallback,
|
||||
);
|
||||
} catch (e) {
|
||||
debugPrint('[ACTIVE_DELIVERY_LOG] Failed to start service: $e');
|
||||
}
|
||||
} else {
|
||||
debugPrint(
|
||||
'[ACTIVE_DELIVERY_LOG] iOS/Web not fully supported for background service yet',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Stop the delivery log streaming service
|
||||
/// Note: This might stop rider logs too if they share the service.
|
||||
/// Usually we only stop if the user goes off-duty or logs out.
|
||||
void stopLogging() {
|
||||
debugPrint(
|
||||
'[ACTIVE_DELIVERY_LOG] Stop logging requested (no-op to preserve rider logs)',
|
||||
);
|
||||
// We do not stop the service here because it might be running for Rider Logs.
|
||||
// The service should be stopped by RiderLogController when going off-duty.
|
||||
}
|
||||
|
||||
// ---------------- Offline Queue Logic (Foreground Helper) ----------------
|
||||
|
||||
/// Call this on app start or network restoration
|
||||
Future<void> flushOfflineLogs() async {
|
||||
if (_isFlushing) return;
|
||||
_isFlushing = true;
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final List<String> queue = prefs.getStringList(_offlineLogKey) ?? [];
|
||||
if (queue.isEmpty) return;
|
||||
|
||||
debugPrint(
|
||||
'[ACTIVE_DELIVERY_LOG][OFFLINE] Flushing ${queue.length} offline logs...',
|
||||
);
|
||||
|
||||
final List<String> remaining = [];
|
||||
bool anySuccess = false;
|
||||
|
||||
// Determine API endpoint
|
||||
final url = ApiConstants.mainRoute == 'live'
|
||||
? ApiConstants.createDeliveryLogLive
|
||||
: ApiConstants.createDeliveryLogDev;
|
||||
|
||||
for (final itemStr in queue) {
|
||||
try {
|
||||
final Map<String, dynamic> item = jsonDecode(itemStr);
|
||||
final String orderId = item['orderId'] ?? '';
|
||||
final Map<String, dynamic> payload = Map<String, dynamic>.from(
|
||||
item['payload'] ?? {},
|
||||
);
|
||||
|
||||
if (payload.isEmpty) continue;
|
||||
|
||||
debugPrint(
|
||||
'[ACTIVE_DELIVERY_LOG][OFFLINE] Retrying for orderId: $orderId',
|
||||
);
|
||||
|
||||
final result = await _logProvider
|
||||
.createDeliveryLog(url, payload)
|
||||
.timeout(const Duration(seconds: 8));
|
||||
|
||||
if (result != null) {
|
||||
debugPrint(
|
||||
'[ACTIVE_DELIVERY_LOG][OFFLINE] Success for orderId: $orderId',
|
||||
);
|
||||
anySuccess = true;
|
||||
} else {
|
||||
remaining.add(itemStr);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint(
|
||||
'[ACTIVE_DELIVERY_LOG][OFFLINE] Error processing item: $e',
|
||||
);
|
||||
remaining.add(itemStr);
|
||||
}
|
||||
}
|
||||
|
||||
if (anySuccess || remaining.length != queue.length) {
|
||||
await prefs.setStringList(_offlineLogKey, remaining);
|
||||
debugPrint(
|
||||
'[ACTIVE_DELIVERY_LOG][OFFLINE] Flush complete. Remaining: ${remaining.length}',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('[ACTIVE_DELIVERY_LOG][OFFLINE] Flush error: $e');
|
||||
} finally {
|
||||
_isFlushing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user