feat: improve call handling with manual hangup support and UI updates

This commit is contained in:
AlexisDanlos 2025-06-18 18:58:05 +02:00 committed by stcb
parent 71485a4346
commit 68761b6e44
2 changed files with 59 additions and 17 deletions

View File

@ -47,10 +47,8 @@ class CallService {
_manualHangupFlag = true; // Mark that hangup was manual _manualHangupFlag = true; // Mark that hangup was manual
print('CallService: Manual hangup flag set to $_manualHangupFlag'); print('CallService: Manual hangup flag set to $_manualHangupFlag');
} else { } else {
print( print('CallService: No pending SIM switch to cancel');
'CallService: No pending SIM switch to cancel, but setting manual hangup flag'); // Don't set manual hangup flag if there's no SIM switch to cancel
_manualHangupFlag =
true; // Still mark as manual even if no pending switch
} }
} }
@ -97,8 +95,15 @@ class CallService {
'CallService: State changed to $state, wasPhoneLocked: $wasPhoneLocked'); 'CallService: State changed to $state, wasPhoneLocked: $wasPhoneLocked');
_callStateController.add(state); _callStateController.add(state);
if (state == "disconnected" || state == "disconnecting") { if (state == "disconnected" || state == "disconnecting") {
print('CallService: ========== CALL DISCONNECTED ==========');
print(
'CallService: _pendingSimSwitch: ${_pendingSimSwitch != null}');
print('CallService: _manualHangupFlag: $_manualHangupFlag');
print('CallService: _isCallPageVisible: $_isCallPageVisible');
// Close call page if no pending SIM switch OR if it was a manual hangup // Close call page if no pending SIM switch OR if it was a manual hangup
if (_pendingSimSwitch == null || _manualHangupFlag) { if (_pendingSimSwitch == null || _manualHangupFlag) {
print('CallService: Condition met, calling _closeCallPage()');
_closeCallPage(); _closeCallPage();
// Only reset manual hangup flag after successful page close // Only reset manual hangup flag after successful page close
if (_manualHangupFlag) { if (_manualHangupFlag) {
@ -106,6 +111,8 @@ class CallService {
'CallService: Resetting manual hangup flag after page close'); 'CallService: Resetting manual hangup flag after page close');
_manualHangupFlag = false; _manualHangupFlag = false;
} }
} else {
print('CallService: NOT closing call page - condition not met');
} }
if (wasPhoneLocked) { if (wasPhoneLocked) {
await _channel.invokeMethod("callEndedFromFlutter"); await _channel.invokeMethod("callEndedFromFlutter");
@ -156,10 +163,24 @@ class CallService {
case "callEnded": case "callEnded":
case "callRemoved": case "callRemoved":
wasPhoneLocked = call.arguments["wasPhoneLocked"] as bool? ?? false; wasPhoneLocked = call.arguments["wasPhoneLocked"] as bool? ?? false;
print( print('CallService: ========== CALL ENDED/REMOVED ==========');
'CallService: Call ended/removed, wasPhoneLocked: $wasPhoneLocked'); // Only close call page if there's no pending SIM switch AND no manual hangup in progress print('CallService: wasPhoneLocked: $wasPhoneLocked');
if (_pendingSimSwitch == null && !_manualHangupFlag) { print('CallService: _pendingSimSwitch: ${_pendingSimSwitch != null}');
print('CallService: _manualHangupFlag: $_manualHangupFlag');
print('CallService: _isCallPageVisible: $_isCallPageVisible');
// Only close call page if there's no pending SIM switch OR if it was a manual hangup during SIM switch
if (_pendingSimSwitch == null || _manualHangupFlag) {
print('CallService: Condition met, calling _closeCallPage()');
_closeCallPage(); _closeCallPage();
// Reset manual hangup flag after closing page
if (_manualHangupFlag) {
print(
'CallService: Resetting manual hangup flag after callEnded');
_manualHangupFlag = false;
}
} else {
print('CallService: NOT closing call page - condition not met');
} }
if (wasPhoneLocked) { if (wasPhoneLocked) {
await _channel.invokeMethod("callEndedFromFlutter"); await _channel.invokeMethod("callEndedFromFlutter");
@ -388,7 +409,7 @@ class CallService {
return; return;
} }
_activeCallNumber = currentPhoneNumber; _activeCallNumber = currentPhoneNumber;
Navigator.pushReplacement( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: const RouteSettings(name: '/call'), settings: const RouteSettings(name: '/call'),
@ -468,7 +489,7 @@ class CallService {
} }
print( print(
'CallService: Closing call page, _isCallPageVisible: $_isCallPageVisible'); 'CallService: Closing call page, _isCallPageVisible: $_isCallPageVisible, _pendingSimSwitch: ${_pendingSimSwitch != null}, _manualHangupFlag: $_manualHangupFlag');
if (Navigator.canPop(context)) { if (Navigator.canPop(context)) {
print('CallService: Popping call page'); print('CallService: Popping call page');
Navigator.pop(context); Navigator.pop(context);
@ -556,18 +577,34 @@ class CallService {
// Getter to check if there's a pending SIM switch // Getter to check if there's a pending SIM switch
static bool get hasPendingSimSwitch => _pendingSimSwitch != null; static bool get hasPendingSimSwitch => _pendingSimSwitch != null;
Future<Map<String, dynamic>> hangUpCall(BuildContext context) async { Future<Map<String, dynamic>> hangUpCall(BuildContext context) async {
try { try {
print('CallService: Hanging up call'); print('CallService: ========== HANGUP INITIATED ==========');
print('CallService: _pendingSimSwitch: ${_pendingSimSwitch != null}');
print('CallService: _manualHangupFlag: $_manualHangupFlag');
print('CallService: _isCallPageVisible: $_isCallPageVisible');
final result = await _channel.invokeMethod('hangUpCall'); final result = await _channel.invokeMethod('hangUpCall');
print('CallService: hangUpCall result: $result'); print('CallService: hangUpCall result: $result');
final resultMap = Map<String, dynamic>.from(result as Map); final resultMap = Map<String, dynamic>.from(result as Map);
if (resultMap["status"] != "ended") { if (resultMap["status"] != "ended") {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Failed to end call")), SnackBar(content: Text("Failed to end call")),
); );
} else {
// If hangup was successful, ensure call page closes after a short delay
// This is a fallback in case the native call state events don't fire properly
Future.delayed(const Duration(milliseconds: 1500), () {
if (_isCallPageVisible) {
print(
'CallService: FALLBACK - Force closing call page after hangup');
_closeCallPage();
_manualHangupFlag = false; // Reset flag
}
});
} }
return resultMap; return resultMap;
} catch (e) { } catch (e) {
print("CallService: Error hanging up call: $e"); print("CallService: Error hanging up call: $e");

View File

@ -284,6 +284,12 @@ class _CallPageState extends State<CallPage> {
print( print(
'CallPage: Initiating manual hangUp - canceling any pending SIM switch'); 'CallPage: Initiating manual hangUp - canceling any pending SIM switch');
// Immediately mark call as inactive to allow page navigation
setState(() {
_isCallActive = false;
_callStatus = "Ending Call...";
});
// Cancel any pending SIM switch since user is manually hanging up // Cancel any pending SIM switch since user is manually hanging up
_callService.cancelPendingSimSwitch(); _callService.cancelPendingSimSwitch();
@ -327,13 +333,12 @@ class _CallPageState extends State<CallPage> {
print( print(
'CallPage: Building UI, _callStatus: $_callStatus, route: ${ModalRoute.of(context)?.settings.name ?? "unknown"}'); 'CallPage: Building UI, _callStatus: $_callStatus, route: ${ModalRoute.of(context)?.settings.name ?? "unknown"}');
return PopScope( return PopScope(
canPop: !_isCallActive, canPop:
true, // Always allow popping - CallService manages when it's appropriate
onPopInvoked: (didPop) { onPopInvoked: (didPop) {
if (!didPop && _isCallActive) { print(
ScaffoldMessenger.of(context).showSnackBar( 'CallPage: PopScope onPopInvoked - didPop: $didPop, _isCallActive: $_isCallActive, _callStatus: $_callStatus');
SnackBar(content: Text('Cannot leave during an active call')), // No longer prevent popping during active calls - CallService handles this
);
}
}, },
child: Scaffold( child: Scaffold(
body: Container( body: Container(