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.
123 lines
4.8 KiB
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');
|
|
}
|
|
}
|
|
|
|
|