Compare commits
	
		
			48 Commits 
		
	
	
		
			master
			...
			developmen
		
	
	| @ -0,0 +1,27 @@ | ||||
| -ignorewarnings | ||||
| -keepattributes *Annotation* | ||||
| -keepattributes Exceptions | ||||
| -keepattributes InnerClasses | ||||
| -keepattributes Signature | ||||
| -keepattributes SourceFile,LineNumberTable | ||||
| -keep class com.huawei.hianalytics.**{*;} | ||||
| -keep class com.huawei.updatesdk.**{*;} | ||||
| -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 | ||||
| -keep class io.flutter.app.** { *; } | ||||
| -keep class io.flutter.plugin.**  { *; } | ||||
| -keep class io.flutter.util.**  { *; } | ||||
| -keep class io.flutter.view.**  { *; } | ||||
| -keep class io.flutter.**  { *; } | ||||
| -keep class io.flutter.plugins.**  { *; } | ||||
| -dontwarn io.flutter.embedding.** | ||||
| @ -0,0 +1,318 @@ | ||||
| //package com.mohem_flutter_app | ||||
| //import kotlinx.coroutines.Dispatchers | ||||
| //import kotlinx.coroutines.GlobalScope | ||||
| //import kotlinx.coroutines.launch | ||||
| //import okhttp3.* | ||||
| //import okhttp3.MediaType.Companion.toMediaType | ||||
| //import okhttp3.RequestBody.Companion.toRequestBody | ||||
| //import java.io.IOException | ||||
| // | ||||
| //class NativeIncomingCallDecline { | ||||
| //    fun declineCall(currentUserID: String, targetUserID: String, token: String) { | ||||
| //        println("--------------- Inside Decline Call ----------------") | ||||
| //        val url = "https://apiderichat.hmg.com/api/user/calldecline" | ||||
| //        val payload = """ | ||||
| //        { | ||||
| //            "currentUserId": "$targetUserID", | ||||
| //            "targetUserId": "$currentUserID", | ||||
| //            "secretKey": "derichatmobileuser", | ||||
| //            "targetUserToken": "$token" | ||||
| //        } | ||||
| //        """.trimIndent() | ||||
| // | ||||
| //        val jsonMediaType = "application/json".toMediaType() | ||||
| // | ||||
| //        GlobalScope.launch(Dispatchers.IO) { | ||||
| //            val client = OkHttpClient() | ||||
| //            val requestBody = payload.toRequestBody(jsonMediaType) | ||||
| //            val request = Request.Builder() | ||||
| //                    .url(url) | ||||
| //                    .post(requestBody) | ||||
| //                    .build() | ||||
| // | ||||
| //            client.newCall(request).enqueue(object : Callback { | ||||
| //                override fun onResponse(call: Call, response: Response) { | ||||
| //                    if (response.isSuccessful) { | ||||
| //                        val responseData = response.body?.string() | ||||
| //                        println("API Successful. Response data: $responseData") | ||||
| //                    } else { | ||||
| //                        val errorMessage = response.body?.string() | ||||
| //                        println("API Failed. Error message: $errorMessage") | ||||
| //                    } | ||||
| //                } | ||||
| // | ||||
| //                override fun onFailure(call: Call, e: IOException) { | ||||
| //                    println("API Request Failed. Exception: ${e.message}") | ||||
| //                } | ||||
| //            }) | ||||
| //        } | ||||
| //    } | ||||
| //} | ||||
| // | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| //This code is included into CallkitIncomingBroadcastReceiver.kt file under Flutter_callKit_incoming Package | ||||
| //Below is the Whole Code | ||||
| 
 | ||||
| // Implemented Libraries into Kotlin  | ||||
| //  implementation 'com.squareup.okhttp3:okhttp:4.9.1' | ||||
| //  implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0' | ||||
| 
 | ||||
| //package com.hiennv.flutter_callkit_incoming | ||||
| //import android.annotation.SuppressLint | ||||
| //import android.content.BroadcastReceiver | ||||
| //import android.content.Context | ||||
| //import android.content.Intent | ||||
| //import android.os.Build | ||||
| //import android.os.Bundle | ||||
| //import android.util.Log | ||||
| ////http | ||||
| //import okhttp3.MediaType.Companion.toMediaType | ||||
| //import okhttp3.OkHttpClient | ||||
| //import okhttp3.Request | ||||
| //import okhttp3.RequestBody.Companion.toRequestBody | ||||
| // | ||||
| //// Async | ||||
| //import kotlinx.coroutines.Dispatchers | ||||
| //import kotlinx.coroutines.GlobalScope | ||||
| //import kotlinx.coroutines.launch | ||||
| // | ||||
| //class CallkitIncomingBroadcastReceiver : BroadcastReceiver() { | ||||
| // | ||||
| //    companion object { | ||||
| //        private const val TAG = "CallkitIncomingReceiver" | ||||
| // | ||||
| //        fun getIntent(context: Context, action: String, data: Bundle?) = | ||||
| //                Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { | ||||
| //                    this.action = "${context.packageName}.${action}" | ||||
| //                    putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) | ||||
| //                } | ||||
| // | ||||
| //        fun getIntentIncoming(context: Context, data: Bundle?) = | ||||
| //                Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { | ||||
| //                    action = "${context.packageName}.${CallkitConstants.ACTION_CALL_INCOMING}" | ||||
| //                    putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) | ||||
| //                } | ||||
| // | ||||
| //        fun getIntentStart(context: Context, data: Bundle?) = | ||||
| //                Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { | ||||
| //                    action = "${context.packageName}.${CallkitConstants.ACTION_CALL_START}" | ||||
| //                    putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) | ||||
| //                } | ||||
| // | ||||
| //        fun getIntentAccept(context: Context, data: Bundle?) = | ||||
| //                Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { | ||||
| //                    action = "${context.packageName}.${CallkitConstants.ACTION_CALL_ACCEPT}" | ||||
| //                    putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) | ||||
| //                } | ||||
| // | ||||
| //        fun getIntentDecline(context: Context, data: Bundle?) = | ||||
| //                Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { | ||||
| //                    action = "${context.packageName}.${CallkitConstants.ACTION_CALL_DECLINE}" | ||||
| //                    putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) | ||||
| //                } | ||||
| // | ||||
| //        fun getIntentEnded(context: Context, data: Bundle?) = | ||||
| //                Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { | ||||
| //                    action = "${context.packageName}.${CallkitConstants.ACTION_CALL_ENDED}" | ||||
| //                    putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) | ||||
| //                } | ||||
| // | ||||
| //        fun getIntentTimeout(context: Context, data: Bundle?) = | ||||
| //                Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { | ||||
| //                    action = "${context.packageName}.${CallkitConstants.ACTION_CALL_TIMEOUT}" | ||||
| //                    putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) | ||||
| //                } | ||||
| // | ||||
| //        fun getIntentCallback(context: Context, data: Bundle?) = | ||||
| //                Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { | ||||
| //                    action = "${context.packageName}.${CallkitConstants.ACTION_CALL_CALLBACK}" | ||||
| //                    putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) | ||||
| //                } | ||||
| //    } | ||||
| // | ||||
| // | ||||
| //    @SuppressLint("MissingPermission") | ||||
| //    override fun onReceive(context: Context, intent: Intent) { | ||||
| //        val callkitNotificationManager = CallkitNotificationManager(context) | ||||
| //        val action = intent.action ?: return | ||||
| //        val data = intent.extras?.getBundle(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA) ?: return | ||||
| // | ||||
| //        when (action) { | ||||
| //            "${context.packageName}.${CallkitConstants.ACTION_CALL_INCOMING}" -> { | ||||
| //                try { | ||||
| //                    callkitNotificationManager.showIncomingNotification(data) | ||||
| //                    sendEventFlutter(CallkitConstants.ACTION_CALL_INCOMING, data) | ||||
| //                    addCall(context, Data.fromBundle(data)) | ||||
| //                    if (callkitNotificationManager.incomingChannelEnabled()) { | ||||
| //                        val soundPlayerServiceIntent = | ||||
| //                                Intent(context, CallkitSoundPlayerService::class.java) | ||||
| //                        soundPlayerServiceIntent.putExtras(data) | ||||
| //                        context.startService(soundPlayerServiceIntent) | ||||
| //                    } | ||||
| //                } catch (error: Exception) { | ||||
| //                    Log.e(TAG, null, error) | ||||
| //                } | ||||
| //            } | ||||
| // | ||||
| //            "${context.packageName}.${CallkitConstants.ACTION_CALL_START}" -> { | ||||
| //                try { | ||||
| //                    sendEventFlutter(CallkitConstants.ACTION_CALL_START, data) | ||||
| //                    addCall(context, Data.fromBundle(data), true) | ||||
| //                } catch (error: Exception) { | ||||
| //                    Log.e(TAG, null, error) | ||||
| //                } | ||||
| //            } | ||||
| // | ||||
| //            "${context.packageName}.${CallkitConstants.ACTION_CALL_ACCEPT}" -> { | ||||
| //                try { | ||||
| //                    sendEventFlutter(CallkitConstants.ACTION_CALL_ACCEPT, data) | ||||
| //                    context.stopService(Intent(context, CallkitSoundPlayerService::class.java)) | ||||
| //                    callkitNotificationManager.clearIncomingNotification(data, true) | ||||
| //                    addCall(context, Data.fromBundle(data), true) | ||||
| //                } catch (error: Exception) { | ||||
| //                    Log.e(TAG, null, error) | ||||
| //                } | ||||
| //            } | ||||
| // | ||||
| //            "${context.packageName}.${CallkitConstants.ACTION_CALL_DECLINE}" -> { | ||||
| //                try { | ||||
| //                    sendEventFlutter(CallkitConstants.ACTION_CALL_DECLINE, data) | ||||
| //                    context.stopService(Intent(context, CallkitSoundPlayerService::class.java)) | ||||
| //                    callkitNotificationManager.clearIncomingNotification(data, false) | ||||
| //                    removeCall(context, Data.fromBundle(data)) | ||||
| //                    println("----------- Code By Aamir on 2222-----------------------"); | ||||
| //                    var callData = data.getSerializable(CallkitConstants.EXTRA_CALLKIT_EXTRA) as HashMap<String, Any?> | ||||
| //                    val token = (callData["loginDetails"] as HashMap<*, *>)["token"] as? String | ||||
| //                    val targetUserId = (callData["callerDetails"] as HashMap<*, *>)["targetUserId"] as? Int | ||||
| //                    val currentUserId = (callData["callerDetails"] as HashMap<*, *>)["currentUserId"] as? Int | ||||
| //                    delineCall(currentUserID = currentUserId, targetUserID = targetUserId, token = token) | ||||
| //                    println("----------- Code By Aamir On BroadCast -----------------------"); | ||||
| //                } catch (error: Exception) { | ||||
| //                    Log.e(TAG, null, error) | ||||
| //                } | ||||
| //            } | ||||
| // | ||||
| //            "${context.packageName}.${CallkitConstants.ACTION_CALL_ENDED}" -> { | ||||
| //                try { | ||||
| //                    sendEventFlutter(CallkitConstants.ACTION_CALL_ENDED, data) | ||||
| //                    context.stopService(Intent(context, CallkitSoundPlayerService::class.java)) | ||||
| //                    callkitNotificationManager.clearIncomingNotification(data, false) | ||||
| //                    removeCall(context, Data.fromBundle(data)) | ||||
| //                } catch (error: Exception) { | ||||
| //                    Log.e(TAG, null, error) | ||||
| //                } | ||||
| //            } | ||||
| // | ||||
| //            "${context.packageName}.${CallkitConstants.ACTION_CALL_TIMEOUT}" -> { | ||||
| //                try { | ||||
| //                    sendEventFlutter(CallkitConstants.ACTION_CALL_TIMEOUT, data) | ||||
| //                    context.stopService(Intent(context, CallkitSoundPlayerService::class.java)) | ||||
| //                    if (data.getBoolean(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_SHOW, true)) { | ||||
| //                        callkitNotificationManager.showMissCallNotification(data) | ||||
| //                    } | ||||
| //                    removeCall(context, Data.fromBundle(data)) | ||||
| //                } catch (error: Exception) { | ||||
| //                    Log.e(TAG, null, error) | ||||
| //                } | ||||
| //            } | ||||
| // | ||||
| //            "${context.packageName}.${CallkitConstants.ACTION_CALL_CALLBACK}" -> { | ||||
| //                try { | ||||
| //                    callkitNotificationManager.clearMissCallNotification(data) | ||||
| //                    sendEventFlutter(CallkitConstants.ACTION_CALL_CALLBACK, data) | ||||
| //                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { | ||||
| //                        val closeNotificationPanel = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS) | ||||
| //                        context.sendBroadcast(closeNotificationPanel) | ||||
| //                    } | ||||
| //                } catch (error: Exception) { | ||||
| //                    Log.e(TAG, null, error) | ||||
| //                } | ||||
| //            } | ||||
| //        } | ||||
| //    } | ||||
| // | ||||
| // | ||||
| //    private fun delineCall(currentUserID: Int?, targetUserID: Int?, token: String?) { | ||||
| //        println("--------------- Inside Decline Call ----------------"); | ||||
| //        val url = "https://apiderichat.hmg.com/api/user/calldecline" | ||||
| //        val payload = """ | ||||
| //        { | ||||
| //            "currentUserId": $targetUserID, | ||||
| //            "targetUserId": $currentUserID, | ||||
| //            "secretKey": "derichatmobileuser", | ||||
| //            "targetUserToken": "$token" | ||||
| //        } | ||||
| //    """.trimIndent() | ||||
| // | ||||
| // | ||||
| //        val jsonMediaType = "application/json".toMediaType() | ||||
| // | ||||
| //        GlobalScope.launch(Dispatchers.IO) { | ||||
| //            val client = OkHttpClient() | ||||
| //            val requestBody = payload.toRequestBody(jsonMediaType) | ||||
| //            val request = Request.Builder() | ||||
| //                    .url(url) | ||||
| //                    .post(requestBody) | ||||
| //                    .build() | ||||
| // | ||||
| //            client.newCall(request).execute().use { response -> | ||||
| //                if (response.isSuccessful) { | ||||
| //                    val responseData = response.body?.string() | ||||
| //                    println("API Successful. Response data: $responseData") | ||||
| //                } else { | ||||
| //                    val errorMessage = response.body?.string() | ||||
| //                    println("API Failed. Error message: $errorMessage") | ||||
| //                } | ||||
| //            } | ||||
| //        } | ||||
| //         | ||||
| // | ||||
| //    } | ||||
| // | ||||
| // | ||||
| //    private fun sendEventFlutter(event: String, data: Bundle) { | ||||
| //        val android = mapOf( | ||||
| //                "isCustomNotification" to data.getBoolean(CallkitConstants.EXTRA_CALLKIT_IS_CUSTOM_NOTIFICATION, false), | ||||
| //                "isCustomSmallExNotification" to data.getBoolean( | ||||
| //                        CallkitConstants.EXTRA_CALLKIT_IS_CUSTOM_SMALL_EX_NOTIFICATION, | ||||
| //                        false | ||||
| //                ), | ||||
| //                "ringtonePath" to data.getString(CallkitConstants.EXTRA_CALLKIT_RINGTONE_PATH, ""), | ||||
| //                "backgroundColor" to data.getString(CallkitConstants.EXTRA_CALLKIT_BACKGROUND_COLOR, ""), | ||||
| //                "backgroundUrl" to data.getString(CallkitConstants.EXTRA_CALLKIT_BACKGROUND_URL, ""), | ||||
| //                "actionColor" to data.getString(CallkitConstants.EXTRA_CALLKIT_ACTION_COLOR, ""), | ||||
| //                "incomingCallNotificationChannelName" to data.getString( | ||||
| //                        CallkitConstants.EXTRA_CALLKIT_INCOMING_CALL_NOTIFICATION_CHANNEL_NAME, | ||||
| //                        "" | ||||
| //                ), | ||||
| //                "missedCallNotificationChannelName" to data.getString( | ||||
| //                        CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_NOTIFICATION_CHANNEL_NAME, | ||||
| //                        "" | ||||
| //                ), | ||||
| //        ) | ||||
| //        val notification = mapOf( | ||||
| //                "id" to data.getInt(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_ID), | ||||
| //                "showNotification" to data.getBoolean(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_SHOW), | ||||
| //                "count" to data.getInt(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_COUNT), | ||||
| //                "subtitle" to data.getString(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_SUBTITLE), | ||||
| //                "callbackText" to data.getString(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_CALLBACK_TEXT), | ||||
| //                "isShowCallback" to data.getBoolean(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_CALLBACK_SHOW), | ||||
| //        ) | ||||
| //        val forwardData = mapOf( | ||||
| //                "id" to data.getString(CallkitConstants.EXTRA_CALLKIT_ID, ""), | ||||
| //                "nameCaller" to data.getString(CallkitConstants.EXTRA_CALLKIT_NAME_CALLER, ""), | ||||
| //                "avatar" to data.getString(CallkitConstants.EXTRA_CALLKIT_AVATAR, ""), | ||||
| //                "number" to data.getString(CallkitConstants.EXTRA_CALLKIT_HANDLE, ""), | ||||
| //                "type" to data.getInt(CallkitConstants.EXTRA_CALLKIT_TYPE, 0), | ||||
| //                "duration" to data.getLong(CallkitConstants.EXTRA_CALLKIT_DURATION, 0L), | ||||
| //                "textAccept" to data.getString(CallkitConstants.EXTRA_CALLKIT_TEXT_ACCEPT, ""), | ||||
| //                "textDecline" to data.getString(CallkitConstants.EXTRA_CALLKIT_TEXT_DECLINE, ""), | ||||
| //                "extra" to data.getSerializable(CallkitConstants.EXTRA_CALLKIT_EXTRA)!!, | ||||
| //                "missedCallNotification" to notification, | ||||
| //                "android" to android | ||||
| //        ) | ||||
| //        FlutterCallkitIncomingPlugin.sendEvent(event, forwardData) | ||||
| //    } | ||||
| //} | ||||
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								| @ -0,0 +1,170 @@ | ||||
| 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'; | ||||
| import 'package:mohem_flutter_app/classes/utils.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_single_user_chat_list_model.dart'; | ||||
| import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as ALM; | ||||
| 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:mohem_flutter_app/ui/landing/dashboard_screen.dart'; | ||||
| import 'package:path_provider/path_provider.dart'; | ||||
| import 'package:signalr_netcore/hub_connection.dart'; | ||||
| import 'package:signalr_netcore/signalr_client.dart'; | ||||
| 
 | ||||
| class ChatVoipCall { | ||||
|   static final ChatVoipCall _instance = ChatVoipCall._internal(); | ||||
| 
 | ||||
|   ChatVoipCall._internal(); | ||||
| 
 | ||||
|   factory ChatVoipCall() => _instance; | ||||
| 
 | ||||
|   late ChatProviderModel prov; | ||||
|   late ChatCallProvider cProv; | ||||
|   dynamic inCallData; | ||||
|   bool isUserOnline = false; | ||||
|   dynamic callData; | ||||
|   static const platform = MethodChannel('com.example.httpchannel/http'); | ||||
| 
 | ||||
|   Future<void> showCallkitIncoming({required String uuid, RemoteMessage? data, CallDataModel? incomingCallData, bool background = false}) async { | ||||
|     await FlutterCallkitIncoming.endAllCalls(); | ||||
|     ALM.Response autoLoginData; | ||||
|     SingleUserChatModel callerData; | ||||
|     if (data!.data["user_token_response"] == null || data.data["user_token_response"].isEmpty) { | ||||
|       // Online & App Logged In | ||||
|       ALM.Response sharedDetails = ALM.Response.fromJson(jsonDecode(await Utils.getStringFromPrefs("userLoginChatDetails"))); | ||||
|       autoLoginData = ALM.Response.fromJson(AppState().getchatUserDetails == null ? sharedDetails.toJson() : AppState().getchatUserDetails!.response!.toJson()); | ||||
|       dynamic items = jsonDecode(data.data["user_chat_history_response"]); | ||||
|       callerData = SingleUserChatModel( | ||||
|           targetUserId: items["CurrentUserId"], | ||||
|           targetUserEmail: items["CurrentUserEmail"], | ||||
|           targetUserName: items["CurrentUserName"].split("@").first, | ||||
|           currentUserId: autoLoginData.id, | ||||
|           currentUserEmail: autoLoginData.email, | ||||
|           currentUserName: autoLoginData.userName, | ||||
|           chatEventId: 3); | ||||
|       isUserOnline = true; | ||||
|     } else { | ||||
|       // Offline or App in Background or App is At Verify Screen | ||||
|       autoLoginData = ALM.Response.fromJson(jsonDecode(data.data["user_token_response"])); | ||||
|       callerData = SingleUserChatModel.fromJson(json.decode(data.data["user_chat_history_response"])); | ||||
|     } | ||||
|     CallKitParams params = CallKitParams( | ||||
|       id: uuid, | ||||
|       nameCaller: callerData.targetUserName, | ||||
|       appName: 'Mohemm', | ||||
|       handle: '', | ||||
|       type: 0, | ||||
|       duration: 20000, | ||||
|       textAccept: 'Accept', | ||||
|       textDecline: 'Decline', | ||||
|       extra: { | ||||
|         "loginDetails": autoLoginData.toJson(), | ||||
|         "callerDetails": callerData.toJson(), | ||||
|         'isIncomingCall': true, | ||||
|         'isUserOnline': isUserOnline, | ||||
|         'callType': data.data["callType"], | ||||
|       }, | ||||
|       android: const AndroidParams( | ||||
|         isCustomNotification: true, | ||||
|         isShowLogo: false, | ||||
|         ringtonePath: 'system_ringtone_default', | ||||
|         backgroundColor: '#0955fa', | ||||
|         backgroundUrl: 'assets/test.png', | ||||
|         actionColor: '#4CAF50', | ||||
|       ), | ||||
|       ios: IOSParams( | ||||
|         iconName: 'Mohemm', | ||||
|         handleType: '', | ||||
|         supportsVideo: true, | ||||
|         maximumCallGroups: 2, | ||||
|         maximumCallsPerCallGroup: 1, | ||||
|         audioSessionMode: 'default', | ||||
|         audioSessionActive: true, | ||||
|         audioSessionPreferredSampleRate: 38000.0, | ||||
|         audioSessionPreferredIOBufferDuration: 0.005, | ||||
|         supportsDTMF: true, | ||||
|         supportsHolding: true, | ||||
|         supportsGrouping: false, | ||||
|         supportsUngrouping: false, | ||||
|         ringtonePath: 'system_ringtone_default', | ||||
|       ), | ||||
|     ); | ||||
|     if (callerData.chatEventId == 3) { | ||||
|       await Utils.saveStringFromPrefs("isIncomingCall", "true"); | ||||
|       await FlutterCallkitIncoming.showCallkitIncoming(params); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Future<void> declineCall({  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) { | ||||
|           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 { | ||||
|       // 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<HubConnection> makeHub({required IncomingCallModel sessionData}) async { | ||||
|     late HubConnection hc; | ||||
|     try { | ||||
|       HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); | ||||
|       hc = HubConnectionBuilder() | ||||
|           .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${sessionData.extra!.loginDetails!.id}&source=Desktop&access_token=${sessionData.extra?.loginDetails!.token}", options: httpOp) | ||||
|           .withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build(); | ||||
|       return hc; | ||||
|     } catch (e) { | ||||
|       print(e); | ||||
|       return hc; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,333 @@ | ||||
| // To parse this JSON data, do | ||||
| // | ||||
| //     final incomingCallModel = incomingCallModelFromJson(jsonString); | ||||
| 
 | ||||
| import 'dart:convert'; | ||||
| 
 | ||||
| class IncomingCallModel { | ||||
|   String? actionColor; | ||||
|   String? appName; | ||||
|   Args? args; | ||||
|   String? avatar; | ||||
|   String? backgroundColor; | ||||
|   String? backgroundUrl; | ||||
|   int? duration; | ||||
|   Extra? extra; | ||||
|   String? from; | ||||
|   String? handle; | ||||
|   Args? headers; | ||||
|   String? id; | ||||
|   bool? isAccepted; | ||||
|   bool? isCustomNotification; | ||||
|   bool? isCustomSmallExNotification; | ||||
|   bool? isShowCallback; | ||||
|   bool? isShowLogo; | ||||
|   bool? isShowMissedCallNotification; | ||||
|   String? nameCaller; | ||||
|   String? ringtonePath; | ||||
|   String? textAccept; | ||||
|   String? textCallback; | ||||
|   String? textDecline; | ||||
|   String? textMissedCall; | ||||
|   int? type; | ||||
|   String? uuid; | ||||
| 
 | ||||
|   IncomingCallModel({ | ||||
|     this.actionColor, | ||||
|     this.appName, | ||||
|     this.args, | ||||
|     this.avatar, | ||||
|     this.backgroundColor, | ||||
|     this.backgroundUrl, | ||||
|     this.duration, | ||||
|     this.extra, | ||||
|     this.from, | ||||
|     this.handle, | ||||
|     this.headers, | ||||
|     this.id, | ||||
|     this.isAccepted, | ||||
|     this.isCustomNotification, | ||||
|     this.isCustomSmallExNotification, | ||||
|     this.isShowCallback, | ||||
|     this.isShowLogo, | ||||
|     this.isShowMissedCallNotification, | ||||
|     this.nameCaller, | ||||
|     this.ringtonePath, | ||||
|     this.textAccept, | ||||
|     this.textCallback, | ||||
|     this.textDecline, | ||||
|     this.textMissedCall, | ||||
|     this.type, | ||||
|     this.uuid, | ||||
|   }); | ||||
| 
 | ||||
|   factory IncomingCallModel.fromRawJson(String str) => IncomingCallModel.fromJson(json.decode(str)); | ||||
| 
 | ||||
|   String toRawJson() => json.encode(toJson()); | ||||
| 
 | ||||
|   factory IncomingCallModel.fromJson(Map<String, dynamic> json) => IncomingCallModel( | ||||
|         actionColor: json["actionColor"], | ||||
|         appName: json["appName"], | ||||
|         args: json["args"] == null ? null : Args.fromJson(json["args"]), | ||||
|         avatar: json["avatar"], | ||||
|         backgroundColor: json["backgroundColor"], | ||||
|         backgroundUrl: json["backgroundUrl"], | ||||
|         duration: json["duration"] == null ? null : json["duration"].toInt(), | ||||
|         extra: json["extra"] == null ? null : Extra.fromJson(json["extra"]), | ||||
|         from: json["from"], | ||||
|         handle: json["handle"], | ||||
|         headers: json["headers"] == null ? null : Args.fromJson(json["headers"]), | ||||
|         id: json["id"], | ||||
|         isAccepted: json["isAccepted"], | ||||
|         isCustomNotification: json["isCustomNotification"], | ||||
|         isCustomSmallExNotification: json["isCustomSmallExNotification"], | ||||
|         isShowCallback: json["isShowCallback"], | ||||
|         isShowLogo: json["isShowLogo"], | ||||
|         isShowMissedCallNotification: json["isShowMissedCallNotification"], | ||||
|         nameCaller: json["nameCaller"], | ||||
|         ringtonePath: json["ringtonePath"], | ||||
|         textAccept: json["textAccept"], | ||||
|         textCallback: json["textCallback"], | ||||
|         textDecline: json["textDecline"], | ||||
|         textMissedCall: json["textMissedCall"], | ||||
|         type: json["type"] == null ? null : json["type"].toInt(), | ||||
|         uuid: json["uuid"], | ||||
|       ); | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() => { | ||||
|         "actionColor": actionColor, | ||||
|         "appName": appName, | ||||
|         "args": args?.toJson(), | ||||
|         "avatar": avatar, | ||||
|         "backgroundColor": backgroundColor, | ||||
|         "backgroundUrl": backgroundUrl, | ||||
|         "duration": duration, | ||||
|         "extra": extra?.toJson(), | ||||
|         "from": from, | ||||
|         "handle": handle, | ||||
|         "headers": headers?.toJson(), | ||||
|         "id": id, | ||||
|         "isAccepted": isAccepted, | ||||
|         "isCustomNotification": isCustomNotification, | ||||
|         "isCustomSmallExNotification": isCustomSmallExNotification, | ||||
|         "isShowCallback": isShowCallback, | ||||
|         "isShowLogo": isShowLogo, | ||||
|         "isShowMissedCallNotification": isShowMissedCallNotification, | ||||
|         "nameCaller": nameCaller, | ||||
|         "ringtonePath": ringtonePath, | ||||
|         "textAccept": textAccept, | ||||
|         "textCallback": textCallback, | ||||
|         "textDecline": textDecline, | ||||
|         "textMissedCall": textMissedCall, | ||||
|         "type": type, | ||||
|         "uuid": uuid, | ||||
|       }; | ||||
| } | ||||
| 
 | ||||
| class Args { | ||||
|   Args(); | ||||
| 
 | ||||
|   factory Args.fromRawJson(String str) => Args.fromJson(json.decode(str)); | ||||
| 
 | ||||
|   String toRawJson() => json.encode(toJson()); | ||||
| 
 | ||||
|   factory Args.fromJson(Map<String, dynamic> json) => Args(); | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() => {}; | ||||
| } | ||||
| 
 | ||||
| class Extra { | ||||
|   LoginDetails? loginDetails; | ||||
|   bool? isIncomingCall; | ||||
|   CallerDetails? callerDetails; | ||||
|   String? callType; | ||||
| 
 | ||||
|   Extra({ | ||||
|     this.loginDetails, | ||||
|     this.isIncomingCall, | ||||
|     this.callerDetails, | ||||
|     this.callType, | ||||
|   }); | ||||
| 
 | ||||
|   factory Extra.fromRawJson(String str) => Extra.fromJson(json.decode(str)); | ||||
| 
 | ||||
|   String toRawJson() => json.encode(toJson()); | ||||
| 
 | ||||
|   factory Extra.fromJson(Map<String, dynamic> json) => Extra( | ||||
|         loginDetails: json["loginDetails"] == null ? null : LoginDetails.fromJson(json["loginDetails"]), | ||||
|         isIncomingCall: json["isIncomingCall"], | ||||
|         callType: json["callType"], | ||||
|         callerDetails: json["callerDetails"] == null ? null : CallerDetails.fromJson(json["callerDetails"]), | ||||
|       ); | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() => { | ||||
|         "loginDetails": loginDetails?.toJson(), | ||||
|         "isIncomingCall": isIncomingCall, | ||||
|         "callType": callType, | ||||
|         "callerDetails": callerDetails?.toJson(), | ||||
|       }; | ||||
| } | ||||
| 
 | ||||
| class CallerDetails { | ||||
|   int? userChatHistoryId; | ||||
|   String? contant; | ||||
|   FileTypeResponse? fileTypeResponse; | ||||
|   String? currentUserName; | ||||
|   String? targetUserEmail; | ||||
|   String? conversationId; | ||||
|   String? encryptedTargetUserId; | ||||
|   int? targetUserId; | ||||
|   bool? isSeen; | ||||
|   int? userChatHistoryLineId; | ||||
|   bool? isDelivered; | ||||
|   String? targetUserName; | ||||
|   int? currentUserId; | ||||
|   DateTime? createdDate; | ||||
|   String? currentUserEmail; | ||||
|   String? contantNo; | ||||
|   int? chatEventId; | ||||
|   String? encryptedTargetUserName; | ||||
|   int? chatSource; | ||||
| 
 | ||||
|   CallerDetails({ | ||||
|     this.userChatHistoryId, | ||||
|     this.contant, | ||||
|     this.fileTypeResponse, | ||||
|     this.currentUserName, | ||||
|     this.targetUserEmail, | ||||
|     this.conversationId, | ||||
|     this.encryptedTargetUserId, | ||||
|     this.targetUserId, | ||||
|     this.isSeen, | ||||
|     this.userChatHistoryLineId, | ||||
|     this.isDelivered, | ||||
|     this.targetUserName, | ||||
|     this.currentUserId, | ||||
|     this.createdDate, | ||||
|     this.currentUserEmail, | ||||
|     this.contantNo, | ||||
|     this.chatEventId, | ||||
|     this.encryptedTargetUserName, | ||||
|     this.chatSource, | ||||
|   }); | ||||
| 
 | ||||
|   factory CallerDetails.fromRawJson(String str) => CallerDetails.fromJson(json.decode(str)); | ||||
| 
 | ||||
|   String toRawJson() => json.encode(toJson()); | ||||
| 
 | ||||
|   factory CallerDetails.fromJson(Map<String, dynamic> json) => CallerDetails( | ||||
|         userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"].toInt(), | ||||
|         contant: json["contant"], | ||||
|         fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]), | ||||
|         currentUserName: json["currentUserName"], | ||||
|         targetUserEmail: json["targetUserEmail"], | ||||
|         conversationId: json["conversationId"], | ||||
|         encryptedTargetUserId: json["encryptedTargetUserId"], | ||||
|         targetUserId: json["targetUserId"] == null ? null : json["targetUserId"].toInt(), | ||||
|         isSeen: json["isSeen"], | ||||
|         userChatHistoryLineId: json["userChatHistoryLineId"] == null ? null : json["userChatHistoryLineId"].toInt(), | ||||
|         isDelivered: json["isDelivered"], | ||||
|         targetUserName: json["targetUserName"], | ||||
|         currentUserId: json["currentUserId"] == null ? null : json["currentUserId"].toInt(), | ||||
|         createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]), | ||||
|         currentUserEmail: json["currentUserEmail"], | ||||
|         contantNo: json["contantNo"], | ||||
|         chatEventId: json["chatEventId"] == null ? null : json["chatEventId"].toInt(), | ||||
|         encryptedTargetUserName: json["encryptedTargetUserName"], | ||||
|         chatSource: json["chatSource"] == null ? null : json["chatSource"].toInt(), | ||||
|       ); | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() => { | ||||
|         "userChatHistoryId": userChatHistoryId, | ||||
|         "contant": contant, | ||||
|         "fileTypeResponse": fileTypeResponse?.toJson(), | ||||
|         "currentUserName": currentUserName, | ||||
|         "targetUserEmail": targetUserEmail, | ||||
|         "conversationId": conversationId, | ||||
|         "encryptedTargetUserId": encryptedTargetUserId, | ||||
|         "targetUserId": targetUserId, | ||||
|         "isSeen": isSeen, | ||||
|         "userChatHistoryLineId": userChatHistoryLineId, | ||||
|         "isDelivered": isDelivered, | ||||
|         "targetUserName": targetUserName, | ||||
|         "currentUserId": currentUserId, | ||||
|         "createdDate": createdDate?.toIso8601String(), | ||||
|         "currentUserEmail": currentUserEmail, | ||||
|         "contantNo": contantNo, | ||||
|         "chatEventId": chatEventId, | ||||
|         "encryptedTargetUserName": encryptedTargetUserName, | ||||
|         "chatSource": chatSource, | ||||
|       }; | ||||
| } | ||||
| 
 | ||||
| class FileTypeResponse { | ||||
|   int? fileTypeId; | ||||
| 
 | ||||
|   FileTypeResponse({ | ||||
|     this.fileTypeId, | ||||
|   }); | ||||
| 
 | ||||
|   factory FileTypeResponse.fromRawJson(String str) => FileTypeResponse.fromJson(json.decode(str)); | ||||
| 
 | ||||
|   String toRawJson() => json.encode(toJson()); | ||||
| 
 | ||||
|   factory FileTypeResponse.fromJson(Map<String, dynamic> json) => FileTypeResponse( | ||||
|         fileTypeId: json["fileTypeId"].toInt(), | ||||
|       ); | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() => { | ||||
|         "fileTypeId": fileTypeId, | ||||
|       }; | ||||
| } | ||||
| 
 | ||||
| class LoginDetails { | ||||
|   bool? isActiveCode; | ||||
|   int? id; | ||||
|   String? encryptedUserName; | ||||
|   String? userName; | ||||
|   String? title; | ||||
|   String? encryptedUserId; | ||||
|   String? email; | ||||
|   bool? isDomainUser; | ||||
|   String? token; | ||||
| 
 | ||||
|   LoginDetails({ | ||||
|     this.isActiveCode, | ||||
|     this.id, | ||||
|     this.encryptedUserName, | ||||
|     this.userName, | ||||
|     this.title, | ||||
|     this.encryptedUserId, | ||||
|     this.email, | ||||
|     this.isDomainUser, | ||||
|     this.token, | ||||
|   }); | ||||
| 
 | ||||
|   factory LoginDetails.fromRawJson(String str) => LoginDetails.fromJson(json.decode(str)); | ||||
| 
 | ||||
|   String toRawJson() => json.encode(toJson()); | ||||
| 
 | ||||
|   factory LoginDetails.fromJson(Map<String, dynamic> json) => LoginDetails( | ||||
|         isActiveCode: json["isActiveCode"], | ||||
|         id: json["id"] == null ? null : json["id"].toInt(), | ||||
|         encryptedUserName: json["encryptedUserName"], | ||||
|         userName: json["userName"], | ||||
|         title: json["title"], | ||||
|         encryptedUserId: json["encryptedUserId"], | ||||
|         email: json["email"], | ||||
|         isDomainUser: json["isDomainUser"], | ||||
|         token: json["token"], | ||||
|       ); | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() => { | ||||
|         "isActiveCode": isActiveCode, | ||||
|         "id": id, | ||||
|         "encryptedUserName": encryptedUserName, | ||||
|         "userName": userName, | ||||
|         "title": title, | ||||
|         "encryptedUserId": encryptedUserId, | ||||
|         "email": email, | ||||
|         "isDomainUser": isDomainUser, | ||||
|         "token": token, | ||||
|       }; | ||||
| } | ||||
| @ -0,0 +1,61 @@ | ||||
| // To parse this JSON data, do | ||||
| // | ||||
| //     final remoteIceCandidatePayLoad = remoteIceCandidatePayLoadFromJson(jsonString); | ||||
| 
 | ||||
| import 'dart:convert'; | ||||
| 
 | ||||
| class RemoteIceCandidatePayLoad { | ||||
|   RemoteIceCandidatePayLoad({ | ||||
|     this.target, | ||||
|     this.candidate, | ||||
|   }); | ||||
| 
 | ||||
|   int? target; | ||||
|   Candidate? candidate; | ||||
| 
 | ||||
|   factory RemoteIceCandidatePayLoad.fromRawJson(String str) => RemoteIceCandidatePayLoad.fromJson(json.decode(str)); | ||||
| 
 | ||||
|   String toRawJson() => json.encode(toJson()); | ||||
| 
 | ||||
|   factory RemoteIceCandidatePayLoad.fromJson(Map<String, dynamic> json) => RemoteIceCandidatePayLoad( | ||||
|     target: json["target"], | ||||
|     candidate: json["candidate"] == null ? null : Candidate.fromJson(json["candidate"]), | ||||
|   ); | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() => { | ||||
|     "target": target, | ||||
|     "candidate": candidate?.toJson(), | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| class Candidate { | ||||
|   Candidate({ | ||||
|     this.candidate, | ||||
|     this.sdpMid, | ||||
|     this.sdpMLineIndex, | ||||
|     this.usernameFragment, | ||||
|   }); | ||||
| 
 | ||||
|   String? candidate; | ||||
|   String? sdpMid; | ||||
|   int? sdpMLineIndex; | ||||
|   String? usernameFragment; | ||||
| 
 | ||||
|   factory Candidate.fromRawJson(String str) => Candidate.fromJson(json.decode(str)); | ||||
| 
 | ||||
|   String toRawJson() => json.encode(toJson()); | ||||
| 
 | ||||
|   factory Candidate.fromJson(Map<String, dynamic> json) => Candidate( | ||||
|     candidate: json["candidate"], | ||||
|     sdpMid: json["sdpMid"], | ||||
|     sdpMLineIndex: json["sdpMLineIndex"], | ||||
|     usernameFragment: json["usernameFragment"], | ||||
|   ); | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() => { | ||||
|     "candidate": candidate, | ||||
|     "sdpMid": sdpMid, | ||||
|     "sdpMLineIndex": sdpMLineIndex, | ||||
|     "usernameFragment": usernameFragment, | ||||
|   }; | ||||
| } | ||||
| @ -1,381 +1,558 @@ | ||||
| import 'dart:convert'; | ||||
| import 'dart:core'; | ||||
| import 'dart:io'; | ||||
| import 'dart:ui'; | ||||
| 
 | ||||
| import 'package:camera/camera.dart'; | ||||
| import 'package:draggable_widget/draggable_widget.dart'; | ||||
| import 'package:flutter/foundation.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; | ||||
| import 'package:flutter_svg/flutter_svg.dart'; | ||||
| import 'package:flutter_webrtc/flutter_webrtc.dart'; | ||||
| import 'package:mohem_flutter_app/app_state/app_state.dart'; | ||||
| import 'package:mohem_flutter_app/classes/colors.dart'; | ||||
| import 'package:mohem_flutter_app/classes/utils.dart'; | ||||
| import 'package:mohem_flutter_app/models/chat/call.dart'; | ||||
| 
 | ||||
| class IncomingCall extends StatefulWidget { | ||||
|   CallDataModel incomingCallData; | ||||
|   bool? isVideoCall; | ||||
| import 'package:mohem_flutter_app/extensions/int_extensions.dart'; | ||||
| import 'package:mohem_flutter_app/main.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/provider/chat_call_provider.dart'; | ||||
| import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| 
 | ||||
|   IncomingCall({Key? key, required this.incomingCallData, this.isVideoCall}) : super(key: key); | ||||
| bool isCallConnected = false; | ||||
| 
 | ||||
| class StartCallPage extends StatefulWidget { | ||||
|   @override | ||||
|   _IncomingCallState createState() => _IncomingCallState(); | ||||
|   _StartCallPageState createState() => _StartCallPageState(); | ||||
| } | ||||
| 
 | ||||
| class _IncomingCallState extends State<IncomingCall> with SingleTickerProviderStateMixin { | ||||
|   AnimationController? _animationController; | ||||
|   CameraController? _controller; | ||||
|   Future<void>? _initializeControllerFuture; | ||||
|   bool isCameraReady = false; | ||||
| class _StartCallPageState extends State<StartCallPage> { | ||||
|   DragController dragController = DragController(); | ||||
|   bool isOutGoingCall = false; | ||||
|   bool isIncomingCall = false; | ||||
|   late ChatCallProvider cProv; | ||||
|   late ChatProviderModel provider; | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     _animationController = AnimationController( | ||||
|       vsync: this, | ||||
|       duration: const Duration( | ||||
|         milliseconds: 500, | ||||
|       ), | ||||
|     ); | ||||
|     //_runAnimation(); | ||||
|     // connectSignaling(); | ||||
|     WidgetsBinding.instance.addPostFrameCallback( | ||||
|       (_) => _runAnimation(), | ||||
|     ); | ||||
| 
 | ||||
|     super.initState(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void dispose() { | ||||
|     super.dispose(); | ||||
|   } | ||||
| 
 | ||||
|   void startCall() async { | ||||
|     IncomingCallModel? sessionData; | ||||
|     dynamic calls = await FlutterCallkitIncoming.activeCalls(); | ||||
|     if (calls.isNotEmpty) { | ||||
|       sessionData =  IncomingCallModel.fromRawJson(jsonEncode(calls[0])); | ||||
|       print(sessionData.toRawJson()); | ||||
|       if (provider.isUserOnline) { | ||||
|         cProv.isUserOnline = provider.isUserOnline; | ||||
|         if (kDebugMode) { | ||||
|           print("====== Processing Incoming Call in Online State ========="); | ||||
|         } | ||||
|         await cProv.startIncomingCallViaKit(inCallData: sessionData!.extra!.callerDetails!.toJson(), isVCall: sessionData.extra!.callType == "video" ? true : false); | ||||
|         cProv.init(); | ||||
|         isCallConnected = true; | ||||
|       } else { | ||||
|         if (kDebugMode) { | ||||
|           print("====== Processing Incoming Call ========="); | ||||
|         } | ||||
|         cProv.isUserOnline = provider.isUserOnline; | ||||
|         await cProv.startIncomingCallViaKit(inCallData: sessionData!.extra!.callerDetails!.toJson(), isVCall: sessionData.extra!.callType == "video" ? true : false); | ||||
|         try { | ||||
|           AppState().setchatUserDetails = UserAutoLoginModel(response: Response.fromJson(sessionData.extra!.loginDetails!.toJson()), errorResponses: null); | ||||
|           await provider.buildHubConnection(context: context, ccProvider: cProv).whenComplete(() { | ||||
|             cProv.init(); | ||||
|             isCallConnected = true; | ||||
|           }); | ||||
|         } catch (e) { | ||||
|           logger.w(e); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void startIosCall() {} | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     cProv = context.read<ChatCallProvider>(); | ||||
|     provider = context.read<ChatProviderModel>(); | ||||
|     if (Platform.isAndroid) { | ||||
|       startCall(); | ||||
|     } else if (Platform.isIOS) { | ||||
|       startIosCall(); | ||||
|     } | ||||
|     return Scaffold( | ||||
|       body: FutureBuilder<void>( | ||||
|         future: _initializeControllerFuture, | ||||
|         builder: (BuildContext context, AsyncSnapshot<void> snapshot) { | ||||
|           if (snapshot.connectionState == ConnectionState.done) { | ||||
|             return Stack( | ||||
|       extendBody: true, | ||||
|       body: Consumer2<ChatCallProvider, ChatProviderModel>( | ||||
|         builder: (BuildContext context, ChatCallProvider provider, ChatProviderModel cpm, Widget? child) { | ||||
|           return provider.isIncomingCallLoader | ||||
|               ? const SizedBox( | ||||
|             width: double.infinity, | ||||
|             height: double.infinity, | ||||
|             child: Center(child: CircularProgressIndicator()), | ||||
|           ) | ||||
|               : provider.isIncomingCall | ||||
|               ? SizedBox( | ||||
|             width: double.infinity, | ||||
|             height: double.infinity, | ||||
|             child: Stack( | ||||
|               alignment: FractionalOffset.center, | ||||
|               children: <Widget>[ | ||||
|                 if (widget.isVideoCall!) | ||||
|                 if (!provider.isAudioCall && provider.isVideoCall) | ||||
|                   Positioned.fill( | ||||
|                     child: AspectRatio( | ||||
|                       aspectRatio: _controller!.value.aspectRatio, | ||||
|                       child: CameraPreview( | ||||
|                         _controller!, | ||||
|                     child: RTCVideoView( | ||||
|                       provider.remoteRenderer!, | ||||
|                       objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover, | ||||
|                       key: const Key('remote'), | ||||
|                     ), | ||||
|                   ), | ||||
|                 if (provider.isVideoCall) | ||||
|                   DraggableWidget( | ||||
|                     bottomMargin: 20, | ||||
|                     topMargin: 40, | ||||
|                     intialVisibility: true, | ||||
|                     horizontalSpace: 20, | ||||
|                     shadowBorderRadius: 50, | ||||
|                     initialPosition: AnchoringPosition.topLeft, | ||||
|                     dragController: dragController, | ||||
|                     normalShadow: const BoxShadow(spreadRadius: 0.0, blurRadius: 0.0), | ||||
|                     draggingShadow: const BoxShadow(spreadRadius: 0.0, blurRadius: 0.0), | ||||
|                     child: SizedBox( | ||||
|                       height: 200, | ||||
|                       width: 140, | ||||
|                       child: RTCVideoView( | ||||
|                         provider.localVideoRenderer!, | ||||
|                         mirror: true, | ||||
|                         objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover, | ||||
|                       ), | ||||
|                     ), | ||||
|                   ), | ||||
|                 Positioned.fill( | ||||
|                   child: ClipRect( | ||||
|                     child: BackdropFilter( | ||||
|                       filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), | ||||
|                       child: Container( | ||||
|                         decoration: BoxDecoration( | ||||
|                           color: MyColors.grey57Color.withOpacity( | ||||
|                             0.7, | ||||
|                 if (!provider.isVideoCall) | ||||
|                   Positioned.fill( | ||||
|                     child: ClipRect( | ||||
|                       child: BackdropFilter( | ||||
|                         filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0), | ||||
|                         child: Container( | ||||
|                           decoration: BoxDecoration( | ||||
|                             color: MyColors.grey57Color.withOpacity( | ||||
|                               0.3, | ||||
|                             ), | ||||
|                           ), | ||||
|                         ), | ||||
|                         child: Column( | ||||
|                           crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                           mainAxisSize: MainAxisSize.max, | ||||
|                           children: <Widget>[ | ||||
|                             Container( | ||||
|                               margin: const EdgeInsets.all(21.0), | ||||
|                               child: Row( | ||||
|                           child: Column( | ||||
|                             crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                             mainAxisSize: MainAxisSize.max, | ||||
|                             children: <Widget>[ | ||||
|                               40.height, | ||||
|                               Row( | ||||
|                                 crossAxisAlignment: CrossAxisAlignment.center, | ||||
|                                 mainAxisAlignment: MainAxisAlignment.center, | ||||
|                                 children: <Widget>[ | ||||
|                                   Image.asset( | ||||
|                                     "assets/images/logos/main_mohemm_logo.png", | ||||
|                                     height: 70, | ||||
|                                     width: 70, | ||||
|                                   ), | ||||
|                                   Container( | ||||
|                                     margin: const EdgeInsets.only( | ||||
|                                       left: 10.0, | ||||
|                                       right: 10.0, | ||||
|                                     ), | ||||
|                                     child: Column( | ||||
|                                       crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                                       mainAxisSize: MainAxisSize.min, | ||||
|                                       mainAxisAlignment: MainAxisAlignment.spaceAround, | ||||
|                                       children: const <Widget>[ | ||||
| 
 | ||||
|                                         // todo @aamir, need to use extension mehtods | ||||
|                                         Text( | ||||
|                                           "Aamir Saleem Ahmad", | ||||
|                                           style: TextStyle( | ||||
|                                             fontSize: 21, | ||||
|                                             fontWeight: FontWeight.bold, | ||||
|                                             color: MyColors.white, | ||||
|                                             letterSpacing: -1.26, | ||||
|                                             height: 23 / 12, | ||||
|                                     margin: const EdgeInsets.all(21.0), | ||||
|                                     child: Container( | ||||
|                                       margin: const EdgeInsets.only( | ||||
|                                         left: 10.0, | ||||
|                                         right: 10.0, | ||||
|                                       ), | ||||
|                                       child: Column( | ||||
|                                         crossAxisAlignment: CrossAxisAlignment.center, | ||||
|                                         mainAxisSize: MainAxisSize.min, | ||||
|                                         mainAxisAlignment: MainAxisAlignment.spaceAround, | ||||
|                                         children: <Widget>[ | ||||
|                                           SvgPicture.asset( | ||||
|                                             "assets/images/user.svg", | ||||
|                                             height: 70, | ||||
|                                             width: 70, | ||||
|                                             fit: BoxFit.cover, | ||||
|                                           ), | ||||
|                                           10.height, | ||||
|                                           Text( | ||||
|                                             provider.incomingCallData.targetUserName!, | ||||
|                                             style: const TextStyle( | ||||
|                                               fontSize: 21, | ||||
|                                               decoration: TextDecoration.none, | ||||
|                                               fontWeight: FontWeight.bold, | ||||
|                                               color: MyColors.white, | ||||
|                                               letterSpacing: -1.26, | ||||
|                                               height: 23 / 12, | ||||
|                                             ), | ||||
|                                           ), | ||||
|                                         ), | ||||
|                                         Text( | ||||
|                                           "Calling...", | ||||
|                                           style: TextStyle( | ||||
|                                             fontSize: 16, | ||||
|                                             fontWeight: FontWeight.w600, | ||||
|                                             color: Color( | ||||
|                                               0xffC6C6C6, | ||||
|                                           const Text( | ||||
|                                             "On Call", | ||||
|                                             style: TextStyle( | ||||
|                                               fontSize: 16, | ||||
|                                               decoration: TextDecoration.none, | ||||
|                                               fontWeight: FontWeight.w600, | ||||
|                                               color: Color( | ||||
|                                                 0xffC6C6C6, | ||||
|                                               ), | ||||
|                                               letterSpacing: -0.48, | ||||
|                                               height: 23 / 24, | ||||
|                                             ), | ||||
|                                             letterSpacing: -0.48, | ||||
|                                             height: 23 / 24, | ||||
|                                           ), | ||||
|                                         ), | ||||
|                                         SizedBox( | ||||
|                                           height: 2, | ||||
|                                         ), | ||||
|                                       ], | ||||
|                                           const SizedBox( | ||||
|                                             height: 2, | ||||
|                                           ), | ||||
|                                         ], | ||||
|                                       ), | ||||
|                                     ), | ||||
|                                   ), | ||||
|                                 ], | ||||
|                               ), | ||||
|                             ], | ||||
|                           ), | ||||
|                         ), | ||||
|                       ), | ||||
|                     ), | ||||
|                   ), | ||||
|                 Align( | ||||
|                   alignment: Alignment.bottomCenter, | ||||
|                   child: Container( | ||||
|                     padding: const EdgeInsets.only( | ||||
|                       bottom: 20, | ||||
|                       left: 40, | ||||
|                       right: 40, | ||||
|                     ), | ||||
|                     child: Row( | ||||
|                       mainAxisSize: MainAxisSize.max, | ||||
|                       mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                       children: <Widget>[ | ||||
|                         // if (provider.isVideoCall) | ||||
|                         RawMaterialButton( | ||||
|                           constraints: const BoxConstraints(), | ||||
|                           onPressed: () { | ||||
|                             provider.loudOn(); | ||||
|                           }, | ||||
|                           elevation: 2.0, | ||||
|                           fillColor: provider.isLoudSpeaker ? MyColors.textMixColor : Colors.grey, | ||||
|                           padding: const EdgeInsets.all( | ||||
|                             10.0, | ||||
|                           ), | ||||
|                           shape: const CircleBorder(), | ||||
|                           child: const Icon( | ||||
|                             Icons.volume_up, | ||||
|                             color: MyColors.white, | ||||
|                             size: 30.0, | ||||
|                           ), | ||||
|                         ), | ||||
|                         RawMaterialButton( | ||||
|                           constraints: const BoxConstraints(), | ||||
|                           onPressed: () { | ||||
|                             provider.camOff(); | ||||
|                           }, | ||||
|                           elevation: 2.0, | ||||
|                           fillColor: provider.isCamOff ? MyColors.textMixColor : Colors.grey, | ||||
|                           padding: const EdgeInsets.all( | ||||
|                             10.0, | ||||
|                           ), | ||||
|                           shape: const CircleBorder(), | ||||
|                           child: Icon( | ||||
|                             provider.isCamOff ? Icons.videocam_off : Icons.videocam, | ||||
|                             color: MyColors.white, | ||||
|                             size: 30.0, | ||||
|                           ), | ||||
|                         ), | ||||
|                         RawMaterialButton( | ||||
|                           constraints: const BoxConstraints(), | ||||
|                           onPressed: () { | ||||
|                             provider.switchCamera(); | ||||
|                           }, | ||||
|                           elevation: 2.0, | ||||
|                           fillColor: provider.isFrontCamera ? Colors.grey : MyColors.textMixColor, | ||||
|                           padding: const EdgeInsets.all( | ||||
|                             10.0, | ||||
|                           ), | ||||
|                           shape: const CircleBorder(), | ||||
|                           child: Icon( | ||||
|                             provider.isFrontCamera ? Icons.switch_camera_outlined : Icons.switch_camera, | ||||
|                             color: MyColors.white, | ||||
|                             size: 30.0, | ||||
|                           ), | ||||
|                         ), | ||||
|                         RawMaterialButton( | ||||
|                           constraints: const BoxConstraints(), | ||||
|                           onPressed: () { | ||||
|                             provider.micOff(); | ||||
|                           }, | ||||
|                           elevation: 2.0, | ||||
|                           fillColor: provider.isMicOff ? MyColors.textMixColor : Colors.grey, | ||||
|                           padding: const EdgeInsets.all( | ||||
|                             10.0, | ||||
|                           ), | ||||
|                           shape: const CircleBorder(), | ||||
|                           child: Icon( | ||||
|                             provider.isMicOff ? Icons.mic_off : Icons.mic, | ||||
|                             color: MyColors.white, | ||||
|                             size: 30.0, | ||||
|                           ), | ||||
|                         ), | ||||
|                         RawMaterialButton( | ||||
|                           constraints: const BoxConstraints(), | ||||
|                           onPressed: () { | ||||
|                             provider.endCall(isUserOnline: cpm.isUserOnline).then((bool value) { | ||||
|                               if (value) { | ||||
|                                 Navigator.of(context).pop(); | ||||
|                                 // print("Reintiiiiiiitttiiiiiiii"); | ||||
|                                 // provider.initStreams(); | ||||
|                               } | ||||
|                             }); | ||||
|                           }, | ||||
|                           elevation: 2.0, | ||||
|                           fillColor: MyColors.redA3Color, | ||||
|                           padding: const EdgeInsets.all( | ||||
|                             10.0, | ||||
|                           ), | ||||
|                           shape: const CircleBorder(), | ||||
|                           child: const Icon( | ||||
|                             Icons.call_end, | ||||
|                             color: MyColors.white, | ||||
|                             size: 30.0, | ||||
|                           ), | ||||
|                         ), | ||||
|                       ], | ||||
|                     ), | ||||
|                   ), | ||||
|                 ), | ||||
|               ], | ||||
|             ), | ||||
|           ) | ||||
|               : provider.isOutGoingCall | ||||
|               ? SizedBox( | ||||
|             width: double.infinity, | ||||
|             height: double.infinity, | ||||
|             child: Stack( | ||||
|               alignment: FractionalOffset.center, | ||||
|               children: <Widget>[ | ||||
|                 if (!provider.isAudioCall && provider.isVideoCall) | ||||
|                   Positioned.fill( | ||||
|                     child: RTCVideoView( | ||||
|                       provider.remoteRenderer!, | ||||
|                       objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover, | ||||
|                       key: const Key('remote'), | ||||
|                     ), | ||||
|                   ), | ||||
|                 if (provider.isVideoCall) | ||||
|                   DraggableWidget( | ||||
|                     bottomMargin: 20, | ||||
|                     topMargin: 40, | ||||
|                     intialVisibility: true, | ||||
|                     horizontalSpace: 20, | ||||
|                     shadowBorderRadius: 50, | ||||
|                     initialPosition: AnchoringPosition.topLeft, | ||||
|                     dragController: dragController, | ||||
|                     normalShadow: const BoxShadow(spreadRadius: 0.0, blurRadius: 0.0), | ||||
|                     draggingShadow: const BoxShadow(spreadRadius: 0.0, blurRadius: 0.0), | ||||
|                     child: SizedBox( | ||||
|                       height: 200, | ||||
|                       width: 140, | ||||
|                       child: RTCVideoView( | ||||
|                         provider.localVideoRenderer!, | ||||
|                         mirror: true, | ||||
|                         objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover, | ||||
|                       ), | ||||
|                     ), | ||||
|                   ), | ||||
|                 if (!provider.isVideoCall) | ||||
|                   Positioned.fill( | ||||
|                     child: ClipRect( | ||||
|                       child: BackdropFilter( | ||||
|                         filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0), | ||||
|                         child: Container( | ||||
|                           decoration: BoxDecoration( | ||||
|                             color: MyColors.grey57Color.withOpacity( | ||||
|                               0.3, | ||||
|                             ), | ||||
|                             // Container( | ||||
|                             //   margin: const EdgeInsets.all(21.0), | ||||
|                             //   width: MediaQuery.of(context).size.width, | ||||
|                             //   decoration: cardRadius(15.0, color: MyColors.black, elevation: null), | ||||
|                             //   child: Column( | ||||
|                             //     crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                             //     mainAxisSize: MainAxisSize.min, | ||||
|                             //     children: [ | ||||
|                             //       Container( | ||||
|                             //         padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 6.0), | ||||
|                             //         child: Text( | ||||
|                             //           "TranslationBase.of(context).appoInfo", | ||||
|                             //           style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.white, letterSpacing: -0.64, height: 23 / 12), | ||||
|                             //         ), | ||||
|                             //       ), | ||||
|                             //       Container( | ||||
|                             //         padding: const EdgeInsets.only(left: 16.0, right: 16.0), | ||||
|                             //         child: Text( | ||||
|                             //           "widget.incomingCallData.appointmentdate + widget.incomingCallData.appointmenttime", | ||||
|                             //           style: TextStyle(fontSize: 12.0, letterSpacing: -0.48, color: Color(0xff8E8E8E), fontWeight: FontWeight.w600), | ||||
|                             //         ), | ||||
|                             //       ), | ||||
|                             //       Container( | ||||
|                             //         padding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 21.0), | ||||
|                             //         child: Text( | ||||
|                             //           "widget.incomingCallData.clinicname", | ||||
|                             //           style: TextStyle(fontSize: 12.0, letterSpacing: -0.48, color: Color(0xff8E8E8E), fontWeight: FontWeight.w600), | ||||
|                             //         ), | ||||
|                             //       ), | ||||
|                             //     ], | ||||
|                             //   ), | ||||
|                             // ), | ||||
|                             const Spacer(), | ||||
|                             Container( | ||||
|                               margin: const EdgeInsets.only( | ||||
|                                 bottom: 70.0, | ||||
|                                 left: 49, | ||||
|                                 right: 49, | ||||
|                               ), | ||||
|                               child: Row( | ||||
|                                 mainAxisSize: MainAxisSize.max, | ||||
|                                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                           ), | ||||
|                           child: Column( | ||||
|                             crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                             mainAxisSize: MainAxisSize.max, | ||||
|                             children: <Widget>[ | ||||
|                               40.height, | ||||
|                               Row( | ||||
|                                 crossAxisAlignment: CrossAxisAlignment.center, | ||||
|                                 mainAxisAlignment: MainAxisAlignment.center, | ||||
|                                 children: <Widget>[ | ||||
|                                   RotationTransition( | ||||
|                                     turns: Tween( | ||||
|                                       begin: 0.0, | ||||
|                                       end: -.1, | ||||
|                                     ) | ||||
|                                         .chain( | ||||
|                                           CurveTween( | ||||
|                                             curve: Curves.elasticIn, | ||||
|                                           ), | ||||
|                                         ) | ||||
|                                         .animate( | ||||
|                                           _animationController!, | ||||
|                                         ), | ||||
|                                     child: RawMaterialButton( | ||||
|                                       onPressed: () { | ||||
|                                         _submit(); | ||||
|                                       }, | ||||
|                                       elevation: 2.0, | ||||
|                                       fillColor: MyColors.green2DColor, | ||||
|                                       padding: const EdgeInsets.all( | ||||
|                                         15.0, | ||||
|                                   Container( | ||||
|                                     margin: const EdgeInsets.all(21.0), | ||||
|                                     child: Container( | ||||
|                                       margin: const EdgeInsets.only( | ||||
|                                         left: 10.0, | ||||
|                                         right: 10.0, | ||||
|                                       ), | ||||
|                                       shape: const CircleBorder(), | ||||
|                                       child: const Icon( | ||||
|                                         Icons.call, | ||||
|                                         color: MyColors.white, | ||||
|                                         size: 35.0, | ||||
|                                       child: Column( | ||||
|                                         crossAxisAlignment: CrossAxisAlignment.center, | ||||
|                                         mainAxisSize: MainAxisSize.min, | ||||
|                                         mainAxisAlignment: MainAxisAlignment.spaceAround, | ||||
|                                         children: <Widget>[ | ||||
|                                           SvgPicture.asset( | ||||
|                                             "assets/images/user.svg", | ||||
|                                             height: 70, | ||||
|                                             width: 70, | ||||
|                                             fit: BoxFit.cover, | ||||
|                                           ), | ||||
|                                           10.height, | ||||
|                                           Text( | ||||
|                                             provider.outGoingCallData.receiverName!, | ||||
|                                             style: const TextStyle( | ||||
|                                               fontSize: 21, | ||||
|                                               decoration: TextDecoration.none, | ||||
|                                               fontWeight: FontWeight.bold, | ||||
|                                               color: MyColors.white, | ||||
|                                               letterSpacing: -1.26, | ||||
|                                               height: 23 / 12, | ||||
|                                             ), | ||||
|                                           ), | ||||
|                                           const Text( | ||||
|                                             "On Call", | ||||
|                                             style: TextStyle( | ||||
|                                               fontSize: 16, | ||||
|                                               decoration: TextDecoration.none, | ||||
|                                               fontWeight: FontWeight.w600, | ||||
|                                               color: Color( | ||||
|                                                 0xffC6C6C6, | ||||
|                                               ), | ||||
|                                               letterSpacing: -0.48, | ||||
|                                               height: 23 / 24, | ||||
|                                             ), | ||||
|                                           ), | ||||
|                                           const SizedBox( | ||||
|                                             height: 2, | ||||
|                                           ), | ||||
|                                         ], | ||||
|                                       ), | ||||
|                                     ), | ||||
|                                   ), | ||||
|                                   RawMaterialButton( | ||||
|                                     onPressed: () { | ||||
|                                       backToHome(); | ||||
|                                     }, | ||||
|                                     elevation: 2.0, | ||||
|                                     fillColor: MyColors.redA3Color, | ||||
|                                     padding: const EdgeInsets.all( | ||||
|                                       15.0, | ||||
|                                     ), | ||||
|                                     shape: const CircleBorder(), | ||||
|                                     child: const Icon( | ||||
|                                       Icons.call_end, | ||||
|                                       color: MyColors.white, | ||||
|                                       size: 35.0, | ||||
|                                     ), | ||||
|                                   ), | ||||
|                                 ], | ||||
|                               ), | ||||
|                             ), | ||||
|                           ], | ||||
|                             ], | ||||
|                           ), | ||||
|                         ), | ||||
|                       ), | ||||
|                     ), | ||||
|                   ), | ||||
|                 Align( | ||||
|                   alignment: Alignment.bottomCenter, | ||||
|                   child: Container( | ||||
|                     padding: const EdgeInsets.only( | ||||
|                       bottom: 20, | ||||
|                       left: 40, | ||||
|                       right: 40, | ||||
|                     ), | ||||
|                     child: Row( | ||||
|                       mainAxisSize: MainAxisSize.max, | ||||
|                       mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                       children: <Widget>[ | ||||
|                         // if (provider.isVideoCall) | ||||
|                         RawMaterialButton( | ||||
|                           constraints: const BoxConstraints(), | ||||
|                           onPressed: () { | ||||
|                             provider.loudOn(); | ||||
|                           }, | ||||
|                           elevation: 2.0, | ||||
|                           fillColor: provider.isLoudSpeaker ? MyColors.textMixColor : Colors.grey, | ||||
|                           padding: const EdgeInsets.all( | ||||
|                             10.0, | ||||
|                           ), | ||||
|                           shape: const CircleBorder(), | ||||
|                           child: const Icon( | ||||
|                             Icons.volume_up, | ||||
|                             color: MyColors.white, | ||||
|                             size: 30.0, | ||||
|                           ), | ||||
|                         ), | ||||
|                         RawMaterialButton( | ||||
|                           constraints: const BoxConstraints(), | ||||
|                           onPressed: () { | ||||
|                             provider.camOff(); | ||||
|                           }, | ||||
|                           elevation: 2.0, | ||||
|                           fillColor: provider.isCamOff ? MyColors.textMixColor : Colors.grey, | ||||
|                           padding: const EdgeInsets.all( | ||||
|                             10.0, | ||||
|                           ), | ||||
|                           shape: const CircleBorder(), | ||||
|                           child: Icon( | ||||
|                             provider.isCamOff ? Icons.videocam_off : Icons.videocam, | ||||
|                             color: MyColors.white, | ||||
|                             size: 30.0, | ||||
|                           ), | ||||
|                         ), | ||||
|                         RawMaterialButton( | ||||
|                           constraints: const BoxConstraints(), | ||||
|                           onPressed: () { | ||||
|                             provider.switchCamera(); | ||||
|                           }, | ||||
|                           elevation: 2.0, | ||||
|                           fillColor: provider.isFrontCamera ? Colors.grey : MyColors.textMixColor, | ||||
|                           padding: const EdgeInsets.all( | ||||
|                             10.0, | ||||
|                           ), | ||||
|                           shape: const CircleBorder(), | ||||
|                           child: Icon( | ||||
|                             provider.isFrontCamera ? Icons.switch_camera_outlined : Icons.switch_camera, | ||||
|                             color: MyColors.white, | ||||
|                             size: 30.0, | ||||
|                           ), | ||||
|                         ), | ||||
|                         RawMaterialButton( | ||||
|                           constraints: const BoxConstraints(), | ||||
|                           onPressed: () { | ||||
|                             provider.micOff(); | ||||
|                           }, | ||||
|                           elevation: 2.0, | ||||
|                           fillColor: provider.isMicOff ? MyColors.textMixColor : Colors.grey, | ||||
|                           padding: const EdgeInsets.all( | ||||
|                             10.0, | ||||
|                           ), | ||||
|                           shape: const CircleBorder(), | ||||
|                           child: Icon( | ||||
|                             provider.isMicOff ? Icons.mic_off : Icons.mic, | ||||
|                             color: MyColors.white, | ||||
|                             size: 30.0, | ||||
|                           ), | ||||
|                         ), | ||||
|                         RawMaterialButton( | ||||
|                           constraints: const BoxConstraints(), | ||||
|                           onPressed: () { | ||||
|                             provider.endCall(isUserOnline: cpm.isUserOnline).then((bool value) { | ||||
|                               if (value) { | ||||
|                                 Navigator.of(context).pop(); | ||||
|                               } | ||||
|                             }); | ||||
|                           }, | ||||
|                           elevation: 2.0, | ||||
|                           fillColor: MyColors.redA3Color, | ||||
|                           padding: const EdgeInsets.all( | ||||
|                             10.0, | ||||
|                           ), | ||||
|                           shape: const CircleBorder(), | ||||
|                           child: const Icon( | ||||
|                             Icons.call_end, | ||||
|                             color: MyColors.white, | ||||
|                             size: 30.0, | ||||
|                           ), | ||||
|                         ), | ||||
|                       ], | ||||
|                     ), | ||||
|                   ), | ||||
|                 ), | ||||
|               ], | ||||
|             ); | ||||
|           } else { | ||||
|             return const Center( | ||||
|               child: CircularProgressIndicator(), | ||||
|             ); | ||||
|           } | ||||
|             ), | ||||
|           ) | ||||
|               : const SizedBox(); | ||||
|         }, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   void _runAnimation() async { | ||||
|     List<CameraDescription> cameras = await availableCameras(); | ||||
|     CameraDescription firstCamera = cameras[1]; | ||||
|     _controller = CameraController( | ||||
|       firstCamera, | ||||
|       ResolutionPreset.medium, | ||||
|     ); | ||||
|     _initializeControllerFuture = _controller!.initialize(); | ||||
|     setState(() {}); | ||||
|     // setAudioFile(); | ||||
|     for (int i = 0; i < 100; i++) { | ||||
|       await _animationController!.forward(); | ||||
|       await _animationController!.reverse(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Future<void> _submit() async { | ||||
|     try { | ||||
|       // backToHome(); | ||||
|       // final roomModel = RoomModel(name: widget.incomingCallData.name, token: widget.incomingCallData.sessionId, identity: widget.incomingCallData.identity); | ||||
|       await _controller?.dispose(); | ||||
| 
 | ||||
|       // changeCallStatusAPI(4); | ||||
| 
 | ||||
|       // if (_session != null && _signaling != null) { | ||||
|       //   await Navigator.of(context).pushReplacement( | ||||
|       //     MaterialPageRoute( | ||||
|       //       // fullscreenDialog: true, | ||||
|       //       builder: (BuildContext context) { | ||||
|       //         // if (widget.incomingCallData.isWebRTC == "true") { | ||||
|       //         return StartVideoCall(signaling: _signaling, session: _session); | ||||
|       // | ||||
|       //         // else { | ||||
|       //         //   return OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: widget.incomingCallData.sessionId, token: widget.incomingCallData.token); | ||||
|       //         // } | ||||
|       // | ||||
|       //         //   return VideoCallWebPage(receiverId: widget.incomingCallData.receiverID, callerId: widget.incomingCallData.callerID); // Web WebRTC VideoCall | ||||
|       // | ||||
|       //         //   return CallHomePage(receiverId: widget.incomingCallData.receiverID, callerId: widget.incomingCallData.callerID); // App WebRTC VideoCall | ||||
|       //       }, | ||||
|       //     ), | ||||
|       //   ); | ||||
|       // } else { | ||||
|       //   // Invalid Params/Data | ||||
|       //   Utils.showToast("Failed to establish connection with server"); | ||||
|       // } | ||||
|     } catch (err) { | ||||
|       print(err); | ||||
|       // await PlatformExceptionAlertDialog( | ||||
|       //   exception: err, | ||||
|       // ).show(context); | ||||
| 
 | ||||
|       Utils.showToast(err.toString()); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // void changeCallStatusAPI(int sessionStatus) { | ||||
|   //   LiveCareService service = new LiveCareService(); | ||||
|   //   service.endCallAPI(widget.incomingCallData.sessionId, sessionStatus, context).then((res) {}).catchError((err) { | ||||
|   //     print(err); | ||||
|   //   }); | ||||
|   // } | ||||
| 
 | ||||
|   void backToHome() async { | ||||
|     // final connected = await signaling.declineCall(widget.incomingCallData.callerID, widget.incomingCallData.receiverID); | ||||
|     // LandingPage.isOpenCallPage = false; | ||||
|     // _signaling | ||||
|     _animationController!.dispose(); | ||||
|     // player.stop(); | ||||
|     // changeCallStatusAPI(3); | ||||
|     // _signaling.bye(_session, callRejected: true); | ||||
|     // _signaling.callDisconnected(_session, callRejected: true); | ||||
|     Navigator.of(context).pop(); | ||||
|   } | ||||
| 
 | ||||
|   // | ||||
|   // void disposeAudioResources() async { | ||||
|   //   await player.dispose(); | ||||
|   // } | ||||
|   // | ||||
|   // void setAudioFile() async { | ||||
|   //   player.stop(); | ||||
|   //   await player.setVolume(1.0); // full volume | ||||
|   //   try { | ||||
|   //     await player.setAsset('assets/sounds/ring_60Sec.mp3').then((value) { | ||||
|   //       player.setLoopMode(LoopMode.one); // loop ring sound | ||||
|   //       player.play(); | ||||
|   //     }).catchError((err) { | ||||
|   //       print("Error: $err"); | ||||
|   //     }); | ||||
|   //   } catch (e) { | ||||
|   //     print("Error: $e"); | ||||
|   //   } | ||||
|   // } | ||||
|   // | ||||
|   // void connectSignaling({@required bool iAmCaller = false}) async { | ||||
|   //   print("----------------- + Signaling Connection Started ---------------------------"); | ||||
|   //   var caller = widget.incomingCallData.callerID; | ||||
|   //   var receiver = widget.incomingCallData.receiverID; | ||||
|   //   var host = widget.incomingCallData.server; | ||||
|   // | ||||
|   //   var selfRole = iAmCaller ? "Caller" : "Receiver"; | ||||
|   //   var selfId = iAmCaller ? caller : receiver; | ||||
|   //   var selfUser = SocketUser(id: selfId, name: "$selfRole-$selfId", userAgent: DeviceInfo.userAgent, moreInfo: {}); | ||||
|   // | ||||
|   //   var remoteRole = !iAmCaller ? "Caller" : "Receiver"; | ||||
|   //   var remoteId = !iAmCaller ? caller : receiver; | ||||
|   //   var remoteUser = SocketUser(id: remoteId, name: "$remoteRole-$remoteId", userAgent: DeviceInfo.userAgent, moreInfo: {}); | ||||
|   // | ||||
|   //   var sessionId = "$caller-$receiver"; | ||||
|   //   _session = SessionOneToOne(id: sessionId, local_user: selfUser, remote_user: remoteUser); | ||||
|   // | ||||
|   //   _signaling = Signaling(host, session: _session); | ||||
|   //   await _signaling.connect(); | ||||
|   // | ||||
|   //   if (_signaling.state == SignalingState.Open) { | ||||
|   //     return; | ||||
|   //   } | ||||
|   // } | ||||
| 
 | ||||
|   BoxDecoration cardRadius(double radius, {required Color color, double? elevation}) { | ||||
|     return BoxDecoration( | ||||
|       shape: BoxShape.rectangle, | ||||
|       color: color ?? Colors.white, | ||||
|       borderRadius: BorderRadius.all( | ||||
|         Radius.circular(radius), | ||||
|       ), | ||||
|       boxShadow: <BoxShadow>[ | ||||
|         BoxShadow( | ||||
|           color: const Color( | ||||
|             0xff000000, | ||||
|           ).withOpacity( | ||||
|             .05, | ||||
|           ), | ||||
|           //spreadRadius: 5, | ||||
|           blurRadius: elevation ?? 27, | ||||
|           offset: const Offset( | ||||
|             -2, | ||||
|             3, | ||||
|           ), | ||||
|         ), | ||||
|       ], | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// if (Platform.isAndroid) { | ||||
| //       SystemNavigator.pop(); | ||||
| //     } else if (Platform.isIOS) { | ||||
| //       exit(0); | ||||
| //     } | ||||
|  | ||||
| @ -0,0 +1,171 @@ | ||||
| // import 'dart:async'; | ||||
| // import 'dart:io'; | ||||
| // import 'package:flutter/material.dart'; | ||||
| // | ||||
| // class DraggableCam extends StatefulWidget { | ||||
| //   //final Size availableScreenSize; | ||||
| //   final Widget child; | ||||
| //   final double scaleFactor; | ||||
| //  // final Stream<bool> onButtonBarVisible; | ||||
| //  // final Stream<double> onButtonBarHeight; | ||||
| // | ||||
| //   const DraggableCam({ | ||||
| //     Key? key, | ||||
| //     //@required this.availableScreenSize, | ||||
| //     required this.child, | ||||
| //    // @required this.onButtonBarVisible, | ||||
| //   //  @required this.onButtonBarHeight, | ||||
| // | ||||
| //     /// The portion of the screen the DraggableWidget should use. | ||||
| //     this.scaleFactor = .25, | ||||
| //   })  : assert(scaleFactor != null && scaleFactor > 0 && scaleFactor <= .4), | ||||
| //        // assert(availableScreenSize != null), | ||||
| //        // assert(onButtonBarVisible != null), | ||||
| //        // assert(onButtonBarHeight != null), | ||||
| //         super(key: key); | ||||
| // | ||||
| //   @override | ||||
| //   _DraggablePublisherState createState() => _DraggablePublisherState(); | ||||
| // } | ||||
| // | ||||
| // class _DraggablePublisherState extends State<DraggableCam> { | ||||
| //   bool _isButtonBarVisible = true; | ||||
| //   double _buttonBarHeight = 0; | ||||
| //   late double _width; | ||||
| //   late double _height; | ||||
| //   late double _top; | ||||
| //   late double _left; | ||||
| //   late double _viewPaddingTop; | ||||
| //   late double _viewPaddingBottom; | ||||
| //   final double _padding = 8.0; | ||||
| //   final Duration _duration300ms = const Duration(milliseconds: 300); | ||||
| //   final Duration _duration0ms = const Duration(milliseconds: 0); | ||||
| //   late Duration _duration; | ||||
| //   late StreamSubscription _streamSubscription; | ||||
| //   late StreamSubscription _streamHeightSubscription; | ||||
| // | ||||
| //   @override | ||||
| //   void initState() { | ||||
| //     super.initState(); | ||||
| //     _duration = _duration300ms; | ||||
| //     _width = widget.availableScreenSize.width * widget.scaleFactor; | ||||
| //     _height = _width * (widget.availableScreenSize.height / widget.availableScreenSize.width); | ||||
| //     _top = widget.availableScreenSize.height - (_buttonBarHeight + _padding) - _height; | ||||
| //     _left = widget.availableScreenSize.width - _padding - _width; | ||||
| // | ||||
| //     _streamSubscription = widget.onButtonBarVisible.listen(_buttonBarVisible); | ||||
| //     _streamHeightSubscription = widget.onButtonBarHeight.listen(_getButtonBarHeight); | ||||
| //   } | ||||
| // | ||||
| //   @override | ||||
| //   void didChangeDependencies() { | ||||
| //     var mediaQuery = MediaQuery.of(context); | ||||
| //     _viewPaddingTop = mediaQuery.viewPadding.top; | ||||
| //     _viewPaddingBottom = mediaQuery.viewPadding.bottom; | ||||
| //     super.didChangeDependencies(); | ||||
| //   } | ||||
| // | ||||
| //   @override | ||||
| //   void dispose() { | ||||
| //     _streamSubscription.cancel(); | ||||
| //     _streamHeightSubscription.cancel(); | ||||
| //     super.dispose(); | ||||
| //   } | ||||
| // | ||||
| //   void _getButtonBarHeight(double height) { | ||||
| //     setState(() { | ||||
| //       _buttonBarHeight = height; | ||||
| //       _positionWidget(); | ||||
| //     }); | ||||
| //   } | ||||
| // | ||||
| //   void _buttonBarVisible(bool visible) { | ||||
| //     if (!mounted) { | ||||
| //       return; | ||||
| //     } | ||||
| //     setState(() { | ||||
| //       _isButtonBarVisible = visible; | ||||
| //       if (_duration == _duration300ms) { | ||||
| //         // only position the widget when we are not currently dragging it around | ||||
| //         _positionWidget(); | ||||
| //       } | ||||
| //     }); | ||||
| //   } | ||||
| // | ||||
| //   @override | ||||
| //   Widget build(BuildContext context) { | ||||
| //     return AnimatedPositioned( | ||||
| //       top: _top, | ||||
| //       left: _left, | ||||
| //       width: _width, | ||||
| //       height: _height, | ||||
| //       duration: _duration, | ||||
| //       child: Listener( | ||||
| //         onPointerDown: (_) => _duration = _duration0ms, | ||||
| //         onPointerMove: (PointerMoveEvent event) { | ||||
| //           setState(() { | ||||
| //             _left = (_left + event.delta.dx).roundToDouble(); | ||||
| //             _top = (_top + event.delta.dy).roundToDouble(); | ||||
| //           }); | ||||
| //         }, | ||||
| //         onPointerUp: (_) => _positionWidget(), | ||||
| //         onPointerCancel: (_) => _positionWidget(), | ||||
| //         child: ClippedVideo( | ||||
| //           height: _height, | ||||
| //           width: _width, | ||||
| //           child: widget.child, | ||||
| //         ), | ||||
| //       ), | ||||
| //     ); | ||||
| //   } | ||||
| // | ||||
| //   double _getCurrentStatusBarHeight() { | ||||
| //     if (_isButtonBarVisible) { | ||||
| //       return _viewPaddingTop; | ||||
| //     } | ||||
| //     final _defaultViewPaddingTop = Platform.isIOS ? 20.0 : Platform.isAndroid ? 24.0 : 0.0; | ||||
| //     if (_viewPaddingTop > _defaultViewPaddingTop) { | ||||
| //       // There must be a hardware notch in the display. | ||||
| //       return _viewPaddingTop; | ||||
| //     } | ||||
| //     return 0.0; | ||||
| //   } | ||||
| // | ||||
| //   double _getCurrentButtonBarHeight() { | ||||
| //     if (_isButtonBarVisible) { | ||||
| //       return _buttonBarHeight + _viewPaddingBottom; | ||||
| //     } | ||||
| //     return _viewPaddingBottom; | ||||
| //   } | ||||
| // | ||||
| //   void _positionWidget() { | ||||
| //     // Determine the center of the object being dragged so we can decide | ||||
| //     // in which corner the object should be placed. | ||||
| //     var dx = (_width / 2) + _left; | ||||
| //     dx = dx < 0 ? 0 : dx >= widget.availableScreenSize.width ? widget.availableScreenSize.width - 1 : dx; | ||||
| //     var dy = (_height / 2) + _top; | ||||
| //     dy = dy < 0 ? 0 : dy >= widget.availableScreenSize.height ? widget.availableScreenSize.height - 1 : dy; | ||||
| //     final draggableCenter = Offset(dx, dy); | ||||
| // | ||||
| //     setState(() { | ||||
| //       _duration = _duration300ms; | ||||
| //       if (Rect.fromLTRB(0, 0, widget.availableScreenSize.width / 2, widget.availableScreenSize.height / 2).contains(draggableCenter)) { | ||||
| //         // Top-left | ||||
| //         _top = _getCurrentStatusBarHeight() + _padding; | ||||
| //         _left = _padding; | ||||
| //       } else if (Rect.fromLTRB(widget.availableScreenSize.width / 2, 0, widget.availableScreenSize.width, widget.availableScreenSize.height / 2).contains(draggableCenter)) { | ||||
| //         // Top-right | ||||
| //         _top = _getCurrentStatusBarHeight() + _padding; | ||||
| //         _left = widget.availableScreenSize.width - _padding - _width; | ||||
| //       } else if (Rect.fromLTRB(0, widget.availableScreenSize.height / 2, widget.availableScreenSize.width / 2, widget.availableScreenSize.height).contains(draggableCenter)) { | ||||
| //         // Bottom-left | ||||
| //         _top = widget.availableScreenSize.height - (_getCurrentButtonBarHeight() + _padding) - _height; | ||||
| //         _left = _padding; | ||||
| //       } else if (Rect.fromLTRB(widget.availableScreenSize.width / 2, widget.availableScreenSize.height / 2, widget.availableScreenSize.width, widget.availableScreenSize.height).contains(draggableCenter)) { | ||||
| //         // Bottom-right | ||||
| //         _top = widget.availableScreenSize.height - (_getCurrentButtonBarHeight() + _padding) - _height; | ||||
| //         _left = widget.availableScreenSize.width - _padding - _width; | ||||
| //       } | ||||
| //     }); | ||||
| //   } | ||||
| // } | ||||
					Loading…
					
					
				
		Reference in New Issue