import 'dart:convert'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_callkit_incoming/entities/entities.dart'; import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.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/get_user_login_token_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'; class ChatVoipCall { static final ChatVoipCall _instance = ChatVoipCall._internal(); ChatVoipCall._internal(); factory ChatVoipCall() => _instance; late ChatProviderModel prov; late ChatCallProvider cProv; dynamic inCallData; Future showCallkitIncoming({required String uuid, RemoteMessage? data, bool isOnline = false, CallDataModel? incomingCallData}) async { await ChatVoipCall().listenerEvent(); if (isOnline) { // if (incomingCallData.chatEventId == 3) { // await Utils.saveStringFromPrefs("isIncomingCall", "true"); // await Utils.saveStringFromPrefs( // "inComingCallData", // jsonEncode([ // { // "loginDetails": autoLoginData.toJson(), // "callerDetails": callerData.toJson(), // } // ])); // await FlutterCallkitIncoming.showCallkitIncoming(params); // } } else { await initProviders(); SingleUserChatModel callerData = SingleUserChatModel.fromJson(jsonDecode(data!.data["user_chat_history_response"])); ALM.Response autoLoginData = ALM.Response.fromJson(jsonDecode(data.data["user_token_response"])); data!.data["callType"] == "video" ? cProv.isVideoCall = true : cProv.isVideoCall = false; CallKitParams params = CallKitParams( id: uuid, nameCaller: callerData.targetUserName, appName: 'Mohemm', handle: '', type: 0, duration: 25000, textAccept: 'Accept', textDecline: 'Decline', textMissedCall: 'Missed call', textCallback: 'Call back', extra: { "loginDetails": autoLoginData.toJson(), "callerDetails": callerData.toJson(), }, android: const AndroidParams( isCustomNotification: true, isShowLogo: false, isShowCallback: false, isShowMissedCallNotification: true, ringtonePath: 'system_ringtone_default', backgroundColor: '#0955fa', backgroundUrl: 'assets/test.png', actionColor: '#4CAF50', ), ios: IOSParams( iconName: '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 Utils.saveStringFromPrefs( // "inComingCallData", // jsonEncode([ // { // "loginDetails": autoLoginData.toJson(), // "callerDetails": callerData.toJson(), // } // ])); connection( data: jsonEncode([ {"loginDetails": autoLoginData.toJson(), "callerDetails": callerData.toJson()} ])); await FlutterCallkitIncoming.showCallkitIncoming(params); } } } Future initProviders() async { cProv = Provider.of(AppRoutes.navigatorKey.currentContext!, listen: false); prov = Provider.of(AppRoutes.navigatorKey.currentContext!, listen: false); } void connection({required data}) async { // inCallData = await Utils.getStringFromPrefs("inComingCallData"); dynamic callData = await jsonDecode(data); AppState().setchatUserDetails = UserAutoLoginModel( response: Response.fromJson(callData[0]["loginDetails"]), errorResponses: null, ); cProv.startIncomingCallViaKit(inCallData: data); try { await prov.buildHubConnection(context: AppRoutes.navigatorKey.currentContext!, ccProvider: cProv).whenComplete(() { cProv.init(); }); } catch (e) { logger.w(e); } } //Function(CallEvent) callback Future listenerEvent() async { try { FlutterCallkitIncoming.onEvent.listen((event) async { switch (event!.event) { case Event.ACTION_CALL_INCOMING: // TODO: received an incoming call break; case Event.ACTION_CALL_START: // TODO: started an outgoing call // TODO: show screen calling in Flutter break; case Event.ACTION_CALL_ACCEPT: Navigator.pushNamedAndRemoveUntil(AppRoutes.navigatorKey.currentContext!, AppRoutes.chatStartCall, (_) => false); // Navigator.pushNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.chatStartCall); break; case Event.ACTION_CALL_DECLINE: cProv.isIncomingCall = true; Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("inComingCallData", "null"); cProv.endCall(); break; case Event.ACTION_CALL_ENDED: Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("inComingCallData", "null"); break; case Event.ACTION_CALL_TIMEOUT: Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("inComingCallData", "null"); break; case Event.ACTION_CALL_CALLBACK: // TODO: only Android - click action `Call back` from missed call notification break; case Event.ACTION_CALL_TOGGLE_HOLD: // TODO: only iOS break; case Event.ACTION_CALL_TOGGLE_MUTE: // TODO: only iOS break; case Event.ACTION_CALL_TOGGLE_DMTF: // TODO: only iOS break; case Event.ACTION_CALL_TOGGLE_GROUP: // TODO: only iOS break; case Event.ACTION_CALL_TOGGLE_AUDIO_SESSION: // TODO: only iOS break; case Event.ACTION_DID_UPDATE_DEVICE_PUSH_TOKEN_VOIP: // TODO: only iOS break; } }); } on Exception {} } }