From 2e22bfb48319f23476c5c5cbb54ea4e4c07416ff Mon Sep 17 00:00:00 2001 From: Aamir Muhammad Date: Wed, 21 Jun 2023 10:56:45 +0300 Subject: [PATCH] End Call --- android/app/proguard-rules.pro | 6 ++ .../com/mohem_flutter_app/MainActivity.kt | 53 ---------------- lib/classes/chat_call_kit.dart | 56 +++++++++++------ lib/ui/landing/dashboard_screen.dart | 19 +++--- lib/ui/login/login_screen.dart | 31 +++++---- lib/ui/login/verify_last_login_screen.dart | 63 +++++++++++++++++++ 6 files changed, 135 insertions(+), 93 deletions(-) diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro index aa82ce6..419bd27 100644 --- a/android/app/proguard-rules.pro +++ b/android/app/proguard-rules.pro @@ -9,6 +9,12 @@ -keep class com.huawei.hms.**{*;} -keep class com.huawei.hms.flutter.**{*;} -keep class com.hiennv.flutter_callkit_incoming.** { *; } +-keep class microsoft.aspnet.signalr.client.hubs.** { *; } +-keep class com.microsoft.signalr.** { *; } +-keep class tvi.webrtc.** { *; } +-keep interface com.microsoft.signalr.** { *; } + + -repackageclasses ## Flutter wrapper diff --git a/android/app/src/main/kotlin/com/mohem_flutter_app/MainActivity.kt b/android/app/src/main/kotlin/com/mohem_flutter_app/MainActivity.kt index acae0fd..aafee53 100644 --- a/android/app/src/main/kotlin/com/mohem_flutter_app/MainActivity.kt +++ b/android/app/src/main/kotlin/com/mohem_flutter_app/MainActivity.kt @@ -14,66 +14,13 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import okhttp3.MediaType.Companion.toMediaTypeOrNull -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.RequestBody.Companion.toRequestBody -import okhttp3.Response import java.io.IOException class MainActivity : FlutterFragmentActivity() { - private val CHANNEL = "com.example.httpchannel/http" - private lateinit var httpClient: OkHttpClient override fun configureFlutterEngine(flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) - MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> - if (call.method == "executeHttpPostRequest") { - val arguments = call.arguments as? Map -// val argument1 = arguments?.get("argument1") -// val argument2 = arguments?.get("argument2") - println("Argument : $arguments") - // println("Argument 2: $argument2") - GlobalScope.launch { - val response = executeHttpPostRequest(arguments) - withContext(Dispatchers.Main) { - result.success(response) - } - } - } else { - result.notImplemented() - } - } - - } - private suspend fun executeHttpPostRequest(payload: String ): String { - val url = "https://api.example.com/data" - // val jsonRequestBody = "{\"key\":\"value\"}" // Replace with your desired request body - - val request = Request.Builder() - .url(url) - .post(payload.toRequestBody("application/json".toMediaTypeOrNull())) - .build() - - return try { - val response: Response = httpClient.newCall(request).execute() - response.body?.string() ?: "" - } catch (e: IOException) { - e.printStackTrace() - "" - } - } - - override fun onResume() { - super.onResume() - httpClient = OkHttpClient() - } - - override fun onPause() { - super.onPause() - httpClient.dispatcher.cancelAll() - } } \ No newline at end of file diff --git a/lib/classes/chat_call_kit.dart b/lib/classes/chat_call_kit.dart index 128f8d8..da0683f 100644 --- a/lib/classes/chat_call_kit.dart +++ b/lib/classes/chat_call_kit.dart @@ -1,8 +1,11 @@ import 'dart:convert'; +import 'dart:io'; import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_callkit_incoming/entities/entities.dart'; import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; +import 'package:logger/logger.dart'; import 'package:mohem_flutter_app/api/chat/chat_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; @@ -14,6 +17,7 @@ import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' a import 'package:mohem_flutter_app/models/chat/incoming_call_model.dart'; import 'package:mohem_flutter_app/provider/chat_call_provider.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:signalr_netcore/hub_connection.dart'; import 'package:signalr_netcore/signalr_client.dart'; import 'package:workmanager/workmanager.dart'; @@ -64,8 +68,6 @@ class ChatVoipCall { duration: 20000, textAccept: 'Accept', textDecline: 'Decline', - textMissedCall: 'Missed call', - textCallback: 'Call back', extra: { "loginDetails": autoLoginData.toJson(), "callerDetails": callerData.toJson(), @@ -76,8 +78,6 @@ class ChatVoipCall { android: const AndroidParams( isCustomNotification: true, isShowLogo: false, - isShowCallback: false, - isShowMissedCallNotification: true, ringtonePath: 'system_ringtone_default', backgroundColor: '#0955fa', backgroundUrl: 'assets/test.png', @@ -108,33 +108,49 @@ class ChatVoipCall { Future declineCall({var payload}) async { IncomingCallModel data = IncomingCallModel.fromJson(jsonDecode(payload)); + if (isUserOnline) { HubConnection _hc = await makeHub(sessionData: data); await _hc.start(); if (_hc.state == HubConnectionState.Connected) { if (data.extra != null) { - _hc.invoke("HangUpAsync", args: [ - data.extra!.callerDetails!.currentUserId!, - data.extra!.callerDetails!.targetUserId!, - ]); - _hc.invoke("UpdateUserStatusAsync", args: [ - int.parse(data.extra!.callerDetails!.currentUserId.toString()), - 1, - ]); + await _hc.invoke("HangUpAsync", args: [data.extra!.callerDetails!.currentUserId!, data.extra!.callerDetails!.targetUserId!]); + await _hc.invoke("UpdateUserStatusAsync", args: [int.parse(data.extra!.callerDetails!.currentUserId.toString()), 1]); FlutterCallkitIncoming.endAllCalls(); chatHubConnection = _hc; } } } else { - try { - var response = await platform.invokeMethod( - 'executeHttpPostRequest', {"currentUserID": data.extra!.callerDetails!.targetUserId, "targetUserID": data.extra!.callerDetails!.currentUserId, "token": data.extra!.loginDetails!.token}); - print('HTTP POST response: $response'); - } on PlatformException catch (e) { - print('Error invoking method: ${e.message}'); - } - // await ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!); + // Future.delayed(const Duration(seconds: 3), () { + // ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!); + // }); + // HubConnection _hc = await makeHub(sessionData: data); + // await _hc.start(); + // if (_hc.state == HubConnectionState.Connected) { + // logger.log(Level.info, "HUB-EVENT"); + // await _hc.invoke("HangUpAsync", args: [ + // data.extra!.callerDetails!.currentUserId!, + // data.extra!.callerDetails!.targetUserId!, + // ]); + // FlutterCallkitIncoming.endAllCalls(); + // await _hc.stop(); + // } } + + // + // try { + // var response = await platform.invokeMethod( + // 'executeHttpPostRequest', {"currentUserID": data.extra!.callerDetails!.targetUserId, "targetUserID": data.extra!.callerDetails!.currentUserId, "token": data.extra!.loginDetails!.token}); + // print('HTTP POST response: $response'); + // Future.delayed(Duration(seconds: 3), () { + // ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!); + // }); + // } on PlatformException catch (e) { + // print('Error invoking method: ${e.message}'); + // } + +//await ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!); +// logger.log(Level.error, "API-EVENT-END"); } Future makeHub({required IncomingCallModel sessionData}) async { diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 28575cd..28de133 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -21,6 +21,7 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/main.dart'; +import 'package:mohem_flutter_app/models/chat/incoming_call_model.dart'; import 'package:mohem_flutter_app/models/itg/itg_main_response.dart'; import 'package:mohem_flutter_app/models/itg/itg_response_model.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; @@ -41,6 +42,7 @@ import 'package:mohem_flutter_app/widgets/shimmer/offers_shimmer_widget.dart'; import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:signalr_netcore/signalr_client.dart'; +import 'package:http/http.dart' as http; class DashboardScreen extends StatefulWidget { DashboardScreen({Key? key}) : super(key: key); @@ -83,26 +85,27 @@ class _DashboardScreenState extends State with WidgetsBindingOb try { FlutterCallkitIncoming.onEvent.listen((CallEvent? event) async { switch (event!.event) { - case Event.ACTION_CALL_INCOMING: + case Event.actionCallIncoming: break; - case Event.ACTION_CALL_START: + case Event.actionCallStart: break; - case Event.ACTION_CALL_ACCEPT: + case Event.actionCallAccept: if (mounted) { moveToCallScreen(); } break; - case Event.ACTION_CALL_DECLINE: + case Event.actionCallDecline: Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("inComingCallData", "null"); - await ChatVoipCall().declineCall(payload: jsonEncode(event.body)); + FlutterCallkitIncoming.endAllCalls(); + break; - case Event.ACTION_CALL_ENDED: + case Event.actionCallEnded: Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("inComingCallData", "null"); FlutterCallkitIncoming.endAllCalls(); break; - case Event.ACTION_CALL_TIMEOUT: + case Event.actionCallTimeout: Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("inComingCallData", "null"); FlutterCallkitIncoming.endAllCalls(); @@ -160,7 +163,7 @@ class _DashboardScreenState extends State with WidgetsBindingOb gotoChat(context); }); } else { - await cProvider.buildHubConnection(context: context, ccProvider: chatCallProvider); + await cProvider.buildHubConnection(context: context, ccProvider: chatCallProvider); Future.delayed(const Duration(seconds: 2), () { cProvider.invokeChatCounter(userId: AppState().chatDetails!.response!.id!); }); diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 33ababb..01cdb7c 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -14,6 +14,7 @@ import 'package:flutter_callkit_incoming/entities/call_event.dart'; import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; import 'package:flutter_ios_voip_kit/call_state_type.dart'; import 'package:flutter_ios_voip_kit/flutter_ios_voip_kit.dart'; +import 'package:logger/logger.dart'; import 'package:mohem_flutter_app/api/chat/chat_api_client.dart'; // import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; @@ -32,6 +33,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/chat/call.dart'; import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart'; +import 'package:mohem_flutter_app/models/chat/incoming_call_model.dart'; import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart'; import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; @@ -40,10 +42,10 @@ import 'package:mohem_flutter_app/models/privilege_list_model.dart'; import 'package:mohem_flutter_app/ui/chat/call/chat_incoming_call_screen.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart'; +import 'package:http/http.dart' as http; // import 'package:safe_device/safe_device.dart'; import 'package:wifi_iot/wifi_iot.dart'; -import 'package:workmanager/workmanager.dart'; class LoginScreen extends StatefulWidget { LoginScreen({Key? key}) : super(key: key); @@ -57,6 +59,7 @@ class LoginScreen extends StatefulWidget { class _LoginScreenState extends State with WidgetsBindingObserver { TextEditingController username = TextEditingController(); TextEditingController password = TextEditingController(); + MethodChannel platform = MethodChannel('com.hiennv.flutter_callkit_incoming'); CheckMobileAppVersionModel? _checkMobileAppVersion; MemberLoginListModel? _memberLoginList; @@ -87,7 +90,9 @@ class _LoginScreenState extends State with WidgetsBindingObserver { // if (kReleaseMode) { // checkDeviceSafety(); // } - callListeners(); + if (Platform.isAndroid) { + callListeners(); + } WidgetsBinding.instance.addObserver(this); setupVoIPCallBacks(); } @@ -189,38 +194,40 @@ class _LoginScreenState extends State with WidgetsBindingObserver { try { FlutterCallkitIncoming.onEvent.listen((CallEvent? event) async { switch (event!.event) { - case Event.ACTION_CALL_INCOMING: + case Event.actionCallIncoming: break; - case Event.ACTION_CALL_START: + case Event.actionCallStart: break; - case Event.ACTION_CALL_ACCEPT: + case Event.actionCallAccept: if (mounted) { isIncomingCall = true; moveToCallScreen(); } break; - case Event.ACTION_CALL_DECLINE: + case Event.actionCallDecline: Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("inComingCallData", "null"); - await ChatVoipCall().declineCall(payload: jsonEncode(event.body)); + FlutterCallkitIncoming.endAllCalls(); break; - case Event.ACTION_CALL_ENDED: + case Event.actionCallEnded: Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("inComingCallData", "null"); FlutterCallkitIncoming.endAllCalls(); break; - case Event.ACTION_CALL_TIMEOUT: + case Event.actionCallTimeout: Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("inComingCallData", "null"); FlutterCallkitIncoming.endAllCalls(); break; } }); - } on Exception {} + } on Exception { + logger.log(Level.info, "EXCEPTION-ON-EVENTS"); + } } - - + + Future moveToCallScreen() async { dynamic calls = await FlutterCallkitIncoming.activeCalls(); if (calls is List) { diff --git a/lib/ui/login/verify_last_login_screen.dart b/lib/ui/login/verify_last_login_screen.dart index b6b5953..3ac6cde 100644 --- a/lib/ui/login/verify_last_login_screen.dart +++ b/lib/ui/login/verify_last_login_screen.dart @@ -3,6 +3,8 @@ import 'dart:io'; import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_callkit_incoming/entities/call_event.dart'; +import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; import 'package:flutter_svg/svg.dart'; import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; @@ -53,9 +55,70 @@ class _VerifyLastLoginScreenState extends State { void initState() { _getAvailableBiometrics(); // setDefault(); + if (Platform.isAndroid) { + callListeners(); + } super.initState(); } + + Future callListeners() async { + try { + FlutterCallkitIncoming.onEvent.listen((CallEvent? event) async { + switch (event!.event) { + case Event.actionCallIncoming: + // await ChatVoipCall().declineCall(payload: jsonEncode(event.body)); + break; + case Event.actionCallStart: + break; + case Event.actionCallAccept: + if (mounted) { + // isIncomingCall = true; + moveToCallScreen(); + } + break; + case Event.actionCallDecline: + Utils.saveStringFromPrefs("isIncomingCall", "false"); + Utils.saveStringFromPrefs("inComingCallData", "null"); + FlutterCallkitIncoming.endAllCalls(); + + break; + case Event.actionCallEnded: + Utils.saveStringFromPrefs("isIncomingCall", "false"); + Utils.saveStringFromPrefs("inComingCallData", "null"); + FlutterCallkitIncoming.endAllCalls(); + break; + case Event.actionCallTimeout: + Utils.saveStringFromPrefs("isIncomingCall", "false"); + Utils.saveStringFromPrefs("inComingCallData", "null"); + FlutterCallkitIncoming.endAllCalls(); + break; + } + }); + } on Exception { + } + } + + Future moveToCallScreen() async { + dynamic calls = await FlutterCallkitIncoming.activeCalls(); + if (calls is List) { + if (calls.isNotEmpty) { + if (Platform.isAndroid) { + Utils.hideLoading(context); + } + var pageRoute = MaterialPageRoute(builder: (context) => StartCallPage()); + Navigator.push(context, pageRoute).whenComplete(() { + // checkFirebaseToken(); + }); + } else { + FlutterCallkitIncoming.endAllCalls(); + Utils.showToast("Something wen't wrong"); + } + } + } + + + @override Widget build(BuildContext context) { mobileLoginInfoListModel ??= ModalRoute.of(context)!.settings.arguments as GetMobileLoginInfoListModel;