feat: enhance SIM management with state tracking and UI updates
This commit is contained in:
parent
c8ea9204ff
commit
71485a4346
@ -11,6 +11,7 @@ class CallService {
|
||||
static String? currentPhoneNumber;
|
||||
static String? currentDisplayName;
|
||||
static Uint8List? currentThumbnail;
|
||||
static int? currentSimSlot; // Track which SIM slot is being used
|
||||
static bool _isCallPageVisible = false;
|
||||
static Map<String, dynamic>? _pendingCall;
|
||||
static bool wasPhoneLocked = false;
|
||||
@ -20,15 +21,38 @@ class CallService {
|
||||
final _callStateController = StreamController<String>.broadcast();
|
||||
final _audioStateController =
|
||||
StreamController<Map<String, dynamic>>.broadcast();
|
||||
final _simStateController = StreamController<int?>.broadcast();
|
||||
Map<String, dynamic>? _currentAudioState;
|
||||
|
||||
static final GlobalKey<NavigatorState> navigatorKey =
|
||||
GlobalKey<NavigatorState>();
|
||||
|
||||
Stream<String> get callStateStream => _callStateController.stream;
|
||||
Stream<Map<String, dynamic>> get audioStateStream =>
|
||||
_audioStateController.stream;
|
||||
Stream<int?> get simStateStream => _simStateController.stream;
|
||||
Map<String, dynamic>? get currentAudioState => _currentAudioState;
|
||||
// Getter for current SIM slot
|
||||
static int? get getCurrentSimSlot => currentSimSlot;
|
||||
// Get SIM display name for the current call
|
||||
static String? getCurrentSimDisplayName() {
|
||||
if (currentSimSlot == null) return null;
|
||||
return "SIM ${currentSimSlot! + 1}";
|
||||
}
|
||||
|
||||
// Cancel pending SIM switch (used when user manually hangs up)
|
||||
void cancelPendingSimSwitch() {
|
||||
if (_pendingSimSwitch != null) {
|
||||
print('CallService: Canceling pending SIM switch due to manual hangup');
|
||||
_pendingSimSwitch = null;
|
||||
_manualHangupFlag = true; // Mark that hangup was manual
|
||||
print('CallService: Manual hangup flag set to $_manualHangupFlag');
|
||||
} else {
|
||||
print(
|
||||
'CallService: No pending SIM switch to cancel, but setting manual hangup flag');
|
||||
_manualHangupFlag =
|
||||
true; // Still mark as manual even if no pending switch
|
||||
}
|
||||
}
|
||||
|
||||
CallService() {
|
||||
_channel.setMethodCallHandler((call) async {
|
||||
@ -73,9 +97,15 @@ class CallService {
|
||||
'CallService: State changed to $state, wasPhoneLocked: $wasPhoneLocked');
|
||||
_callStateController.add(state);
|
||||
if (state == "disconnected" || state == "disconnecting") {
|
||||
// Only close call page if there's no pending SIM switch
|
||||
if (_pendingSimSwitch == null) {
|
||||
// Close call page if no pending SIM switch OR if it was a manual hangup
|
||||
if (_pendingSimSwitch == null || _manualHangupFlag) {
|
||||
_closeCallPage();
|
||||
// Only reset manual hangup flag after successful page close
|
||||
if (_manualHangupFlag) {
|
||||
print(
|
||||
'CallService: Resetting manual hangup flag after page close');
|
||||
_manualHangupFlag = false;
|
||||
}
|
||||
}
|
||||
if (wasPhoneLocked) {
|
||||
await _channel.invokeMethod("callEndedFromFlutter");
|
||||
@ -127,9 +157,8 @@ class CallService {
|
||||
case "callRemoved":
|
||||
wasPhoneLocked = call.arguments["wasPhoneLocked"] as bool? ?? false;
|
||||
print(
|
||||
'CallService: Call ended/removed, wasPhoneLocked: $wasPhoneLocked');
|
||||
// Only close call page if there's no pending SIM switch
|
||||
if (_pendingSimSwitch == null) {
|
||||
'CallService: Call ended/removed, wasPhoneLocked: $wasPhoneLocked'); // Only close call page if there's no pending SIM switch AND no manual hangup in progress
|
||||
if (_pendingSimSwitch == null && !_manualHangupFlag) {
|
||||
_closeCallPage();
|
||||
}
|
||||
if (wasPhoneLocked) {
|
||||
@ -138,6 +167,8 @@ class CallService {
|
||||
currentPhoneNumber = null;
|
||||
currentDisplayName = null;
|
||||
currentThumbnail = null;
|
||||
currentSimSlot = null; // Reset SIM slot when call ends
|
||||
_simStateController.add(null); // Notify UI that SIM is cleared
|
||||
_activeCallNumber = null;
|
||||
break;
|
||||
case "incomingCallFromNotification":
|
||||
@ -493,6 +524,8 @@ class CallService {
|
||||
currentPhoneNumber = phoneNumber;
|
||||
currentDisplayName = displayName ?? phoneNumber;
|
||||
currentThumbnail = thumbnail;
|
||||
currentSimSlot = simSlot; // Track the SIM slot being used
|
||||
_simStateController.add(simSlot); // Notify UI of SIM change
|
||||
if (displayName == null || thumbnail == null) {
|
||||
await _fetchContactInfo(phoneNumber);
|
||||
}
|
||||
@ -519,6 +552,7 @@ class CallService {
|
||||
|
||||
// Pending SIM switch data
|
||||
static Map<String, dynamic>? _pendingSimSwitch;
|
||||
static bool _manualHangupFlag = false; // Track if hangup was manual
|
||||
|
||||
// Getter to check if there's a pending SIM switch
|
||||
static bool get hasPendingSimSwitch => _pendingSimSwitch != null;
|
||||
@ -583,13 +617,15 @@ class CallService {
|
||||
print('CallService: Executing pending SIM switch redial');
|
||||
|
||||
// Wait a moment to ensure the previous call is fully disconnected
|
||||
await Future.delayed(const Duration(milliseconds: 1000));
|
||||
|
||||
// Store the new call info for the redial
|
||||
await Future.delayed(const Duration(
|
||||
milliseconds: 1000)); // Store the new call info for the redial
|
||||
currentPhoneNumber = switchData['phoneNumber'];
|
||||
currentDisplayName = switchData['displayName'];
|
||||
currentThumbnail =
|
||||
switchData['thumbnail']; // Make the new call with the selected SIM
|
||||
currentThumbnail = switchData['thumbnail'];
|
||||
currentSimSlot = switchData['simSlot']; // Track the new SIM slot
|
||||
_simStateController.add(switchData['simSlot']); // Notify UI of SIM change
|
||||
|
||||
// Make the new call with the selected SIM
|
||||
final result = await _channel.invokeMethod('makeGsmCall', {
|
||||
'phoneNumber': switchData['phoneNumber'],
|
||||
'simSlot': switchData['simSlot'],
|
||||
|
@ -36,6 +36,7 @@ class _CallPageState extends State<CallPage> {
|
||||
String _callStatus = "Calling...";
|
||||
StreamSubscription<String>? _callStateSubscription;
|
||||
StreamSubscription<Map<String, dynamic>>? _audioStateSubscription;
|
||||
StreamSubscription<int?>? _simStateSubscription;
|
||||
bool _isCallActive = true; // Track if call is still active
|
||||
|
||||
bool get isNumberUnknown => widget.displayName == widget.phoneNumber;
|
||||
@ -46,6 +47,7 @@ class _CallPageState extends State<CallPage> {
|
||||
_checkInitialCallState();
|
||||
_listenToCallState();
|
||||
_listenToAudioState();
|
||||
_listenToSimState();
|
||||
_setInitialAudioState();
|
||||
}
|
||||
|
||||
@ -54,6 +56,7 @@ class _CallPageState extends State<CallPage> {
|
||||
_callTimer?.cancel();
|
||||
_callStateSubscription?.cancel();
|
||||
_audioStateSubscription?.cancel();
|
||||
_simStateSubscription?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -103,15 +106,8 @@ class _CallPageState extends State<CallPage> {
|
||||
} else if (state == "disconnected" || state == "disconnecting") {
|
||||
_callTimer?.cancel();
|
||||
_callStatus = "Call Ended";
|
||||
_isCallActive =
|
||||
false; // Only navigate back if there's no pending SIM switch
|
||||
if (!CallService.hasPendingSimSwitch) {
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
if (mounted && Navigator.canPop(context)) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
});
|
||||
}
|
||||
_isCallActive = false;
|
||||
// Let CallService handle navigation - don't navigate from here
|
||||
} else {
|
||||
_callStatus = "Calling...";
|
||||
_isCallActive = true;
|
||||
@ -132,6 +128,17 @@ class _CallPageState extends State<CallPage> {
|
||||
});
|
||||
}
|
||||
|
||||
void _listenToSimState() {
|
||||
_simStateSubscription = _callService.simStateStream.listen((simSlot) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
// UI will update automatically because we're listening to the stream
|
||||
// The SIM display will show the new SIM slot
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _startCallTimer() {
|
||||
_callTimer?.cancel();
|
||||
_callTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||
@ -274,7 +281,12 @@ class _CallPageState extends State<CallPage> {
|
||||
}
|
||||
|
||||
try {
|
||||
print('CallPage: Initiating hangUp');
|
||||
print(
|
||||
'CallPage: Initiating manual hangUp - canceling any pending SIM switch');
|
||||
|
||||
// Cancel any pending SIM switch since user is manually hanging up
|
||||
_callService.cancelPendingSimSwitch();
|
||||
|
||||
final result = await _callService.hangUpCall(context);
|
||||
print('CallPage: Hang up result: $result');
|
||||
} catch (e) {
|
||||
@ -386,6 +398,29 @@ class _CallPageState extends State<CallPage> {
|
||||
color: Colors.white70,
|
||||
),
|
||||
),
|
||||
// Show SIM information if available
|
||||
if (CallService.getCurrentSimDisplayName() != null)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 4.0),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0, vertical: 2.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue.withOpacity(0.2),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: Colors.blue.withOpacity(0.5),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
CallService.getCurrentSimDisplayName()!,
|
||||
style: TextStyle(
|
||||
fontSize: statusFontSize - 2,
|
||||
color: Colors.lightBlueAccent,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user