diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 75c680b..a62656f 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -57,8 +57,11 @@
This app requires microphone access to for call.
UIBackgroundModes
+ processing
fetch
remote-notification
+ voip
+
FirebaseAppDelegateProxyEnabled
diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart
index f714662..3d82570 100644
--- a/lib/classes/notifications.dart
+++ b/lib/classes/notifications.dart
@@ -8,7 +8,10 @@ import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
import 'package:huawei_push/huawei_push.dart' as huawei_push;
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
+import 'package:mohem_flutter_app/classes/voip_chat_call.dart';
+import 'package:mohem_flutter_app/provider/chat_call_provider.dart';
import 'package:permission_handler/permission_handler.dart';
+import 'package:uuid/uuid.dart';
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
@@ -130,4 +133,6 @@ Future backgroundMessageHandler(RemoteMessage message) async {
await Firebase.initializeApp();
Utils.saveStringFromPrefs("isAppOpendByChat", "false");
Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString());
+
+ ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), data: message);
}
diff --git a/lib/classes/voip_chat_call.dart b/lib/classes/voip_chat_call.dart
new file mode 100644
index 0000000..f96fb19
--- /dev/null
+++ b/lib/classes/voip_chat_call.dart
@@ -0,0 +1,64 @@
+import 'dart:convert';
+
+import 'package:firebase_messaging/firebase_messaging.dart';
+import 'package:flutter_callkit_incoming/entities/entities.dart';
+import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
+import 'package:mohem_flutter_app/main.dart';
+import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
+
+class ChatVoipCall {
+ static final ChatVoipCall _instance = ChatVoipCall._internal();
+
+ ChatVoipCall._internal();
+
+ factory ChatVoipCall() => _instance;
+
+ Future showCallkitIncoming({required String uuid, required RemoteMessage data}) async {
+ logger.d(data.data["user_chat_history_response"]);
+
+ SingleUserChatModel callerData = SingleUserChatModel.fromJson(jsonDecode(data.data["user_chat_history_response"]));
+ var params = CallKitParams(
+ id: uuid,
+ nameCaller: callerData.currentUserName,
+ appName: 'Mohemm',
+ avatar: 'https://i.pravatar.cc/100',
+ handle: '0123456789',
+ type: 0,
+ duration: 30000,
+ textAccept: 'Accept',
+ textDecline: 'Decline',
+ textMissedCall: 'Missed call',
+ textCallback: 'Call back',
+ extra: {'userId': '1a2b3c4d'},
+ headers: {'apiKey': 'Abc@123!', 'platform': 'flutter'},
+ android: const AndroidParams(
+ isCustomNotification: true,
+ isShowLogo: false,
+ isShowCallback: false,
+ isShowMissedCallNotification: true,
+ ringtonePath: 'system_ringtone_default',
+ backgroundColor: '#0955fa',
+ backgroundUrl: 'assets/test.png',
+ actionColor: '#4CAF50',
+ ),
+ ios: IOSParams(
+ iconName: 'CallKitLogo',
+ handleType: '',
+ supportsVideo: true,
+ maximumCallGroups: 2,
+ maximumCallsPerCallGroup: 1,
+ audioSessionMode: 'default',
+ audioSessionActive: true,
+ audioSessionPreferredSampleRate: 44100.0,
+ audioSessionPreferredIOBufferDuration: 0.005,
+ supportsDTMF: true,
+ supportsHolding: true,
+ supportsGrouping: false,
+ supportsUngrouping: false,
+ ringtonePath: 'system_ringtone_default',
+ ),
+ );
+ logger.d(callerData.targetUserId);
+ await FlutterCallkitIncoming.showCallkitIncoming(params);
+ }
+}
diff --git a/lib/provider/chat_call_provider.dart b/lib/provider/chat_call_provider.dart
index 06c5201..af8b100 100644
--- a/lib/provider/chat_call_provider.dart
+++ b/lib/provider/chat_call_provider.dart
@@ -3,6 +3,9 @@ import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_callkit_incoming/entities/android_params.dart';
+import 'package:flutter_callkit_incoming/entities/call_kit_params.dart';
+import 'package:flutter_callkit_incoming/entities/ios_params.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:just_audio/just_audio.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
@@ -13,6 +16,7 @@ import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/call/chat_incoming_call_screen.dart';
import 'package:mohem_flutter_app/ui/chat/call/start_call_screen.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
+import 'package:uuid/uuid.dart';
class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
///////////////////// Web RTC Video Calling //////////////////////
@@ -31,6 +35,7 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
bool isVideoCall = false;
bool isCallStarted = false;
bool isFrontCamera = true;
+ bool isOnIncomingCallPage = false;
/// WebRTC Connection Variables
bool _offer = false;
@@ -210,32 +215,33 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
print("--------------------- On Incoming Call ---------------------------------------");
dynamic items = params!.toList();
logger.d(items);
- Map json = {
- "callerID": items[0]["id"],
- "callerName": items[0]["userName"],
- "callerEmail": items[0]["email"],
- "callerTitle": items[0]["title"],
- "callerPhone": null,
- "receiverID": AppState().chatDetails!.response!.id,
- "receiverName": AppState().chatDetails!.response!.userName,
- "receiverEmail": AppState().chatDetails!.response!.email,
- "receiverTitle": AppState().chatDetails!.response!.title,
- "receiverPhone": AppState().chatDetails!.response!.phone,
- "title": AppState().chatDetails!.response!.userName!.replaceAll(".", " "),
- "callType": items[1] ? "Video" : "Audio",
- };
-
- CallDataModel callData = CallDataModel.fromJson(json);
- await Navigator.push(
- providerContext,
- MaterialPageRoute(
- builder: (BuildContext context) =>
- IncomingCall(
- isVideoCall: items[1] ? true : false,
- outGoingCallData: callData,
- ),
- ),
- );
+ if (!isOnIncomingCallPage) {
+ Map json = {
+ "callerID": items[0]["id"],
+ "callerName": items[0]["userName"],
+ "callerEmail": items[0]["email"],
+ "callerTitle": items[0]["title"],
+ "callerPhone": null,
+ "receiverID": AppState().chatDetails!.response!.id,
+ "receiverName": AppState().chatDetails!.response!.userName,
+ "receiverEmail": AppState().chatDetails!.response!.email,
+ "receiverTitle": AppState().chatDetails!.response!.title,
+ "receiverPhone": AppState().chatDetails!.response!.phone,
+ "title": AppState().chatDetails!.response!.userName!.replaceAll(".", " "),
+ "callType": items[1] ? "Video" : "Audio",
+ };
+ CallDataModel callData = CallDataModel.fromJson(json);
+ await Navigator.push(
+ providerContext,
+ MaterialPageRoute(
+ builder: (BuildContext context) => IncomingCall(
+ isVideoCall: items[1] ? true : false,
+ outGoingCallData: callData,
+ ),
+ ),
+ );
+ isOnIncomingCallPage = true;
+ }
}
void onCallDeclinedAsync(List