You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudsolutions-atoms/lib/services/app_lifecycle_observer.dart

123 lines
4.8 KiB
Dart

import 'dart:developer';
import 'package:flutter/widgets.dart';
import 'package:test_sa/core/di/service_locator.dart';
import 'package:test_sa/modules/cx_module/chat/services/call_manager.dart';
/// App lifecycle observer to handle pending calls when app resumes
class AppLifecycleObserver with WidgetsBindingObserver {
static final AppLifecycleObserver _instance = AppLifecycleObserver._internal();
factory AppLifecycleObserver() => _instance;
AppLifecycleObserver._internal();
bool _isInitialized = false;
bool _hasCheckedPendingCall = false;
/// Initialize the lifecycle observer
void initialize() {
if (_isInitialized) {
log('⚠️ [LIFECYCLE] Already initialized', name: 'AppLifecycleObserver');
return;
}
log('🔧 [LIFECYCLE] Initializing app lifecycle observer', name: 'AppLifecycleObserver');
WidgetsBinding.instance.addObserver(this);
_isInitialized = true;
log('✅ [LIFECYCLE] Observer initialized', name: 'AppLifecycleObserver');
// Check for pending calls immediately on app start
_checkPendingCallsOnStart();
}
/// Dispose the observer
void dispose() {
if (_isInitialized) {
log('🧹 [LIFECYCLE] Disposing lifecycle observer', name: 'AppLifecycleObserver');
WidgetsBinding.instance.removeObserver(this);
_isInitialized = false;
}
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
log('═══════════════════════════════════════════', name: 'AppLifecycleObserver');
log('🔄 [LIFECYCLE] App state changed: ${state.name}', name: 'AppLifecycleObserver');
switch (state) {
case AppLifecycleState.resumed:
log('✅ [LIFECYCLE] App resumed - checking for pending calls', name: 'AppLifecycleObserver');
_onAppResumed();
break;
case AppLifecycleState.inactive:
log('⏸️ [LIFECYCLE] App inactive', name: 'AppLifecycleObserver');
break;
case AppLifecycleState.paused:
log('⏸️ [LIFECYCLE] App paused', name: 'AppLifecycleObserver');
break;
case AppLifecycleState.detached:
log('🔴 [LIFECYCLE] App detached', name: 'AppLifecycleObserver');
break;
case AppLifecycleState.hidden:
log('🔴 [LIFECYCLE] App hidden', name: 'AppLifecycleObserver');
break;
}
log('═══════════════════════════════════════════', name: 'AppLifecycleObserver');
}
/// Check for pending calls when app starts
Future<void> _checkPendingCallsOnStart() async {
try {
// Wait a bit for app to fully initialize
await Future.delayed(const Duration(milliseconds: 500));
log('═══════════════════════════════════════════', name: 'AppLifecycleObserver');
log('🔍 [LIFECYCLE] Checking for pending calls on app start...', name: 'AppLifecycleObserver');
if (getIt.isRegistered<CallManager>()) {
final callManager = getIt<CallManager>();
await callManager.checkForPendingCalls();
_hasCheckedPendingCall = true;
log('✅ [LIFECYCLE] Pending call check complete', name: 'AppLifecycleObserver');
} else {
log('⚠️ [LIFECYCLE] CallManager not registered yet', name: 'AppLifecycleObserver');
}
log('═══════════════════════════════════════════', name: 'AppLifecycleObserver');
} catch (e, stackTrace) {
log('❌ [LIFECYCLE] Error checking pending calls on start: $e\nStack: $stackTrace',
name: 'AppLifecycleObserver');
}
}
/// Handle app resumed state
Future<void> _onAppResumed() async {
try {
// Check for pending calls if we haven't already
if (!_hasCheckedPendingCall) {
log('🔍 [LIFECYCLE] First resume - checking for pending calls', name: 'AppLifecycleObserver');
if (getIt.isRegistered<CallManager>()) {
final callManager = getIt<CallManager>();
await callManager.checkForPendingCalls();
_hasCheckedPendingCall = true;
}
}
// Handle pending navigation (if call was accepted while app was launching)
if (getIt.isRegistered<CallManager>()) {
final callManager = getIt<CallManager>();
await callManager.handlePendingNavigation();
}
} catch (e, stackTrace) {
log('❌ [LIFECYCLE] Error handling app resumed: $e\nStack: $stackTrace',
name: 'AppLifecycleObserver');
}
}
/// Reset state (for testing)
void reset() {
_hasCheckedPendingCall = false;
log('🔄 [LIFECYCLE] State reset', name: 'AppLifecycleObserver');
}
}