foreground calling implemented and working fine

ui_ux_rollout_merge_audio_video_call
WaseemAbbasi22 4 weeks ago
parent 71a2be931f
commit ea0087e6f9

@ -186,15 +186,15 @@ class WebRTCService {
// Setup peer connection event handlers
_setupPeerConnectionListeners();
// CRITICAL FIX: Enable speakerphone by default for audio calls
// This ensures audio plays through the loudspeaker instead of the quiet earpiece
log('🔊 [WebRTC] Enabling speakerphone by default for audio call...', name: 'WebRTCService');
// CRITICAL FIX: Keep speakerphone OFF by default for audio calls
// User can manually enable it if needed via the speaker button
log('🔇 [WebRTC] Keeping speakerphone OFF by default for audio call...', name: 'WebRTCService');
try {
await Helper.setSpeakerphoneOn(true);
log('✅ [WebRTC] Speakerphone enabled', name: 'WebRTCService');
await Helper.setSpeakerphoneOn(false);
log('✅ [WebRTC] Speakerphone disabled (earpiece mode)', name: 'WebRTCService');
} catch (e) {
log('⚠️ [WebRTC] Failed to enable speakerphone: $e', name: 'WebRTCService');
// Continue anyway - user can manually enable it
log('⚠️ [WebRTC] Failed to disable speakerphone: $e', name: 'WebRTCService');
// Continue anyway - not critical
}
if (kDebugMode) {

@ -1,5 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@ -44,7 +42,13 @@ class _ChatWidgetState extends State<ChatWidget> {
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
Provider.of<ChatProvider>(context, listen: false).reset();
// CRITICAL FIX: Don't reset if already initialized with same request
// This prevents closing SignalR connection when navigating between pages
final chatProvider = Provider.of<ChatProvider>(context, listen: false);
if (chatProvider.referenceID != widget.requestId) {
// Only reset if it's a different request
chatProvider.reset();
}
getChatToken();
});
}

@ -85,6 +85,11 @@ class CallManager extends ChangeNotifier {
try {
log('🔧 [CallManager] Initializing...', name: 'CallManager');
// CRITICAL FIX: Cache credentials for background call handling
_cachedUserId = userId;
_cachedAuthToken = authToken;
_cachedEmployeeNumber = employeeNumber;
// CRITICAL FIX: Don't re-initialize if already initialized with same USER credentials
// conversationId can change (different chats) - that's OK, just update it
// Only re-initialize if USER changes (userId, authToken, employeeNumber)
@ -380,46 +385,60 @@ class CallManager extends ChangeNotifier {
log(' Video: $isVideoCall', name: 'CallManager');
// CRITICAL FIX: Auto-initialize CallManager if not already initialized
// This handles the case when app is in background and context is null
if (_userId == null || _authToken == null) {
log('⚠️ [INCOMING] CallManager not initialized - attempting auto-initialization...', name: 'CallManager');
// Try to get credentials from ChatProvider
try {
final chatProvider = Provider.of<ChatProvider>(navigatorKey.currentContext!, listen: false);
final chatLoginResponse = chatProvider.chatLoginResponse;
final sender = chatProvider.sender; // Get sender for employee number
if (chatLoginResponse != null) {
log('🔧 [INCOMING] Found credentials in ChatProvider', name: 'CallManager');
log(' User ID: ${chatLoginResponse.userId}', name: 'CallManager');
log(' Employee Number: ${sender?.employeeNumber ?? "NOT AVAILABLE"}', name: 'CallManager');
await initialize(
userId: chatLoginResponse.userId.toString(),
authToken: chatLoginResponse.token ?? '',
conversationId: extraData?['conversationId'] as String?,
moduleId: extraData?['moduleId'] as String?,
referenceId: extraData?['referenceId'] as String?,
employeeNumber: sender?.employeeNumber, // Get from sender participant
);
log('✅ [INCOMING] Auto-initialization successful', name: 'CallManager');
} else {
log('❌ [INCOMING] No credentials available in ChatProvider', name: 'CallManager');
// Show error to user
final context = navigatorKey.currentContext;
if (context != null) {
CallErrorHandler.showGenericError(context, 'Unable to receive call. Please login to chat first.');
// CRITICAL FIX: Try cached credentials first (for background calls)
if (_cachedUserId != null && _cachedAuthToken != null && _cachedEmployeeNumber != null) {
log('🔧 [INCOMING] Using cached credentials (app in background)', name: 'CallManager');
log(' Cached User ID: $_cachedUserId', name: 'CallManager');
log(' Cached Employee Number: $_cachedEmployeeNumber', name: 'CallManager');
await initialize(
userId: _cachedUserId!,
authToken: _cachedAuthToken!,
conversationId: extraData?['conversationId'] as String?,
moduleId: extraData?['moduleId'] as String?,
referenceId: extraData?['referenceId'] as String?,
employeeNumber: _cachedEmployeeNumber,
);
log('✅ [INCOMING] Auto-initialization successful (from cache)', name: 'CallManager');
}
// Try to get credentials from ChatProvider (app in foreground)
else if (navigatorKey.currentContext != null) {
try {
final chatProvider = Provider.of<ChatProvider>(navigatorKey.currentContext!, listen: false);
final chatLoginResponse = chatProvider.chatLoginResponse;
final sender = chatProvider.sender; // Get sender for employee number
if (chatLoginResponse != null) {
log('🔧 [INCOMING] Found credentials in ChatProvider', name: 'CallManager');
log(' User ID: ${chatLoginResponse.userId}', name: 'CallManager');
log(' Employee Number: ${sender?.employeeNumber ?? "NOT AVAILABLE"}', name: 'CallManager');
await initialize(
userId: chatLoginResponse.userId.toString(),
authToken: chatLoginResponse.token ?? '',
conversationId: extraData?['conversationId'] as String?,
moduleId: extraData?['moduleId'] as String?,
referenceId: extraData?['referenceId'] as String?,
employeeNumber: sender?.employeeNumber, // Get from sender participant
);
log('✅ [INCOMING] Auto-initialization successful (from ChatProvider)', name: 'CallManager');
} else {
log('❌ [INCOMING] No credentials available', name: 'CallManager');
return;
}
} catch (e) {
log('❌ [INCOMING] Auto-initialization failed: $e', name: 'CallManager');
return;
}
} catch (e) {
log('❌ [INCOMING] Auto-initialization failed: $e', name: 'CallManager');
// Show error to user
final context = navigatorKey.currentContext;
if (context != null) {
CallErrorHandler.showGenericError(context, 'Unable to receive call. Please open chat first.');
}
} else {
log('❌ [INCOMING] No cached credentials and no context available', name: 'CallManager');
log(' This means user never logged into chat in this session', name: 'CallManager');
return;
}
}
@ -871,10 +890,10 @@ class CallManager extends ChangeNotifier {
log('🎵 [WEBRTC] Initializing for audio call', name: 'CallManager');
await _webrtcService!.initializeForAudioCall();
// CRITICAL FIX: Speaker is enabled by default in WebRTC service
// CRITICAL FIX: Speaker is OFF by default in WebRTC service (earpiece mode)
// Update the CallManager state to reflect this
_isSpeakerOn = true;
log('✅ [WEBRTC] Speaker state synchronized: ON', name: 'CallManager');
_isSpeakerOn = false;
log('✅ [WEBRTC] Speaker state synchronized: OFF (earpiece mode)', name: 'CallManager');
notifyListeners();
} else {
log('📹 [WEBRTC] Initializing for video call', name: 'CallManager');

Loading…
Cancel
Save