From 8db09f20b78d62308e3bb2a4426d1670e3554ab1 Mon Sep 17 00:00:00 2001 From: Aamir-iMac Date: Sun, 28 May 2023 16:32:49 +0300 Subject: [PATCH] Changes On iOS --- ios/Runner/AppDelegate.swift | 6 -- ios/Runner/Info.plist | 37 ++++---- lib/classes/chat_call_kit.dart | 94 ++++++++++--------- lib/classes/navigationService.dart | 14 +-- lib/classes/notifications.dart | 2 + lib/main.dart | 10 +- lib/provider/chat_call_provider.dart | 9 +- .../chat/call/chat_incoming_call_screen.dart | 12 +-- .../chat/call/chat_outgoing_call_screen.dart | 11 +-- lib/ui/landing/dashboard_screen.dart | 26 +++-- 10 files changed, 112 insertions(+), 109 deletions(-) diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 5b1bfee..96c55d9 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -34,8 +34,6 @@ import flutter_local_notifications func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) { print(credentials.token) let deviceToken = credentials.token.map { String(format: "%02x", $0) }.joined() - print(deviceToken) - print("deviceToken From Swift") //Save deviceToken to your server SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken) } @@ -57,11 +55,7 @@ import flutter_local_notifications // // let data = flutter_callkit_incoming.Data(id: "1", nameCaller: "Mohemm", handle: "handle", type: isVideo ? 1 : 0) -// //set more data // data.extra = ["user": "abc@123", "platform": "ios"] -// //data.iconName = ... -// //data..... -// data.appName = "Mohemm" // data.iconName = "Mohemm" SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming(data, fromPushKit: true) } diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 50ff832..df3e12c 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,15 +2,6 @@ - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - NSAllowsArbitraryLoadsForMedia - - NSAllowsArbitraryLoadsInWebContent - - CADisableMinimumFrameDurationOnPhone CFBundleDevelopmentRegion @@ -31,6 +22,10 @@ ???? CFBundleVersion $(FLUTTER_BUILD_NUMBER) + FirebaseAppDelegateProxyEnabled + + ITSAppUsesNonExemptEncryption + LSApplicationQueriesSchemes sms @@ -41,6 +36,15 @@ NFCReaderUsageDescription This App requires access to NFC to mark your attendance. + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + NSAllowsArbitraryLoadsForMedia + + NSAllowsArbitraryLoadsInWebContent + + NSCameraUsageDescription This app requires camera access to capture & upload picture as profile image. NSFaceIDUsageDescription @@ -51,20 +55,19 @@ This App requires access to your location to mark your attendance. NSLocationWhenInUseUsageDescription This App requires access to your location to mark your attendance. - NSPhotoLibraryUsageDescription - This app requires photo library access to select image as document & upload it. NSMicrophoneUsageDescription This app requires microphone access to for call. + NSPhotoLibraryUsageDescription + This app requires photo library access to select image as document & upload it. + UIApplicationSupportsIndirectInputEvents + UIBackgroundModes - processing + processing fetch remote-notification voip - - FirebaseAppDelegateProxyEnabled - UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -88,13 +91,9 @@ 0000 - ITSAppUsesNonExemptEncryption - com.apple.developer.nfc.readersession.formats TAG - UIApplicationSupportsIndirectInputEvents - diff --git a/lib/classes/chat_call_kit.dart b/lib/classes/chat_call_kit.dart index 2059eec..b1846ba 100644 --- a/lib/classes/chat_call_kit.dart +++ b/lib/classes/chat_call_kit.dart @@ -4,6 +4,7 @@ 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/consts.dart'; import 'package:mohem_flutter_app/classes/navigationService.dart'; import 'package:mohem_flutter_app/classes/notifications.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; @@ -13,9 +14,14 @@ 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/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/chat/call/chat_incoming_call_screen.dart'; +import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; import 'package:provider/provider.dart'; +import 'package:signalr_netcore/hub_connection.dart'; +import 'package:signalr_netcore/signalr_client.dart'; class ChatVoipCall { static final ChatVoipCall _instance = ChatVoipCall._internal(); @@ -29,6 +35,7 @@ class ChatVoipCall { dynamic inCallData; bool isUserOnline = false; dynamic callData; + late IncomingCallModel sessionData; Future showCallkitIncoming({required String uuid, RemoteMessage? data, CallDataModel? incomingCallData, bool background = false}) async { await ChatVoipCall().listenerEvent(); @@ -38,7 +45,6 @@ class ChatVoipCall { 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( @@ -61,7 +67,7 @@ class ChatVoipCall { appName: 'Mohemm', handle: '', type: 0, - duration: 25000, + duration: 20000, textAccept: 'Accept', textDecline: 'Decline', textMissedCall: 'Missed call', @@ -70,6 +76,7 @@ class ChatVoipCall { "loginDetails": autoLoginData.toJson(), "callerDetails": callerData.toJson(), 'isIncomingCall': true, + 'isUserOnline': isUserOnline, }, android: const AndroidParams( isCustomNotification: true, @@ -98,11 +105,13 @@ class ChatVoipCall { ringtonePath: 'system_ringtone_default', ), ); + sessionData = IncomingCallModel.fromJson(params.toJson()); if (callerData.chatEventId == 3) { await Utils.saveStringFromPrefs("isIncomingCall", "true"); await FlutterCallkitIncoming.showCallkitIncoming(params); } } + Future getCurrentCall() async { var calls = await FlutterCallkitIncoming.activeCalls(); if (calls is List) { @@ -115,19 +124,19 @@ class ChatVoipCall { } void checkAndNavigationCallingPage() async { - var currentCall = await getCurrentCall(); + dynamic currentCall = await getCurrentCall(); if (currentCall != null) { - Future.delayed(const Duration(seconds: 2)).whenComplete(() { + Future.delayed(const Duration(seconds: 1)).whenComplete(() { Navigator.pushNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.chatStartCall); }); } } Future isCall() async { - var calls = await FlutterCallkitIncoming.activeCalls(); + dynamic calls = await FlutterCallkitIncoming.activeCalls(); if (calls is List) { if (calls.isNotEmpty) { - NavigationService.navigateTo(AppRoutes.chatStartCall); + NavigationService.navigateToPage(StartCallPage()); } } } @@ -143,18 +152,15 @@ class ChatVoipCall { break; case Event.ACTION_CALL_ACCEPT: if (isUserOnline) { - checkAndNavigationCallingPage(); - } else { - isCall(); - } + checkAndNavigationCallingPage(); + } else { + isCall(); + } break; case Event.ACTION_CALL_DECLINE: - // cProv.isIncomingCall = true; Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("inComingCallData", "null"); - - // cProv.endCall(isUserOnline: true); - FlutterCallkitIncoming.endAllCalls(); + declineCall(); break; case Event.ACTION_CALL_ENDED: Utils.saveStringFromPrefs("isIncomingCall", "false"); @@ -164,40 +170,44 @@ class ChatVoipCall { case Event.ACTION_CALL_TIMEOUT: Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("inComingCallData", "null"); + FlutterCallkitIncoming.endAllCalls(); break; } }); } on Exception {} } - void nothing() { - // if (!background) { - // await initProviders(); - // if (data!.data["callType"] == "video") { - // cProv.isVideoCall = true; - // } else { - // cProv.isAudioCall = true; - // cProv.isVideoCall = false; - // } - // } - // - // // if(!background){} - // await initProviders(); + Future declineCall() async { + if (isUserOnline) { + if (chatHubConnection.state == HubConnectionState.Connected) { + if (sessionData?.extra != null) { + chatHubConnection.invoke("HangUpAsync", args: [ + int.parse(sessionData.extra!.callerDetails!.currentUserId.toString()), + int.parse(sessionData.extra!.callerDetails!.targetUserId.toString()), + ]); + chatHubConnection.invoke("UpdateUserStatusAsync", args: [ + int.parse(sessionData.extra!.callerDetails!.currentUserId.toString()), + 1, + ]); - // callData = jsonEncode([ - // { - // "loginDetails": autoLoginData.toJson(), - // "callerDetails": callerData.toJson(), - // } - // ]); - - // connection(data: callData, isUserOnline: isUserOnline).whenComplete(() => {}); - // if (isUserOnline) { - // cProv.init(); - // } - // if (!isUserOnline) { - // initProviders(); - // } - // Navigator.pushNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.chatStartCall); + FlutterCallkitIncoming.endCall(sessionData.id!); + } + } + } else { + HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); + HubConnection hc = HubConnectionBuilder() + .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${sessionData.extra!.loginDetails!.id}&source=Desktop&access_token=${sessionData.extra?.loginDetails!.token}", options: httpOp) + .withAutomaticReconnect(retryDelays: [2000, 5000, 10000, 20000]).build(); + await hc.start(); + await hc.invoke( + "HangUpAsync", + args: [ + int.parse(sessionData.extra!.callerDetails!.currentUserId.toString()), + int.parse(sessionData.extra!.callerDetails!.targetUserId.toString()), + ], + ); + FlutterCallkitIncoming.endCall(sessionData.id!); + hc.stop(); + } } } diff --git a/lib/classes/navigationService.dart b/lib/classes/navigationService.dart index d18a945..e79e546 100644 --- a/lib/classes/navigationService.dart +++ b/lib/classes/navigationService.dart @@ -1,12 +1,16 @@ import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; -import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/main.dart'; -final locator = GetIt.instance; + +void setupLocator() { + print("GetIt Registered :::::"); + locator.registerLazySingleton(() => NavigationService()); +} class NavigationService { - final GlobalKey navigatorKey = AppRoutes.navigatorKey; + final GlobalKey navigatorKey = new GlobalKey(); static Future navigateTo(String routeName) { var key = locator().navigatorKey; @@ -20,6 +24,4 @@ class NavigationService { } } -void setupLocator() { - locator.registerLazySingleton( ()=> NavigationService()); -} + diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index c573e4b..2ae84be 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -114,6 +114,7 @@ class AppNotifications { } void _handleMessage(RemoteMessage message) { + print("res: --------------"); Utils.saveStringFromPrefs("isAppOpendByChat", "false"); if (message.data.isNotEmpty && message.data["messageType"] == 'chat') { Utils.saveStringFromPrefs("isAppOpendByChat", "true"); @@ -128,6 +129,7 @@ class AppNotifications { Utils.saveStringFromPrefs("isAppOpendByChat", "true"); Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString()); } + print("hereeee"); } } diff --git a/lib/main.dart b/lib/main.dart index a4cdf94..b8b2682 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:get_it/get_it.dart'; import 'package:logger/logger.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; @@ -21,6 +22,7 @@ import 'package:provider/provider.dart'; import 'package:provider/single_child_widget.dart'; import 'package:sizer/sizer.dart'; +final GetIt locator = GetIt.instance; Logger logger = Logger( // filter: null, // Use the default LogFilter (-> only log in debug mode) printer: PrettyPrinter( @@ -46,9 +48,11 @@ Future main() async { DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); + locator.registerSingleton(NavigationService(), + signalsReady: true); await EasyLocalization.ensureInitialized(); AppState().setPostParamsInitConfig(); - setupLocator(); + HttpOverrides.global = MyHttpOverrides(); isTablet = MediaQueryData.fromWindow(WidgetsBinding.instance.window).size.shortestSide >= ApiConsts.tabletMinLength; @@ -111,8 +115,9 @@ class MyApp extends StatelessWidget { MonthYearPickerLocalizations.delegate, ); return MaterialApp( - navigatorKey: AppRoutes.navigatorKey, + navigatorKey: locator().navigatorKey, builder: (BuildContext context, Widget? child) { + AppRoutes.navigatorKey = locator().navigatorKey; return MediaQuery( data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), child: child!, @@ -127,7 +132,6 @@ class MyApp extends StatelessWidget { locale: context.locale, initialRoute: AppRoutes.initialRoute, routes: AppRoutes.routes, - ); }, ); diff --git a/lib/provider/chat_call_provider.dart b/lib/provider/chat_call_provider.dart index 3660668..13aa3e1 100644 --- a/lib/provider/chat_call_provider.dart +++ b/lib/provider/chat_call_provider.dart @@ -42,6 +42,7 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { bool isIncomingCallLoader = true; bool isIncomingCall = false; bool isOutGoingCall = false; + bool isUserOnline = false; late BuildContext providerContext; @@ -229,13 +230,11 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { return true; } else { if (isOutGoingCall) { - print("Endded Outgoing"); await invoke(invokeMethod: "HangUpAsync", currentUserID: outGoingCallData.callerId!, targetUserID: outGoingCallData.receiverId!, userStatus: 1); await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: outGoingCallData.callerId!, targetUserID: outGoingCallData.receiverId!, userStatus: 1); } else if (isIncomingCall) { await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!, userStatus: 1); } - isCallStarted = false; isVideoCall = false; isCamOff = false; @@ -280,8 +279,8 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { void onHangUpAsync(List? params) { print("--------------------- onHangUp ---------------------------------------"); - isOutGoingCall = false; - endCall(isUserOnline: false).then((bool value) { + + endCall(isUserOnline: isUserOnline).then((bool value) { Navigator.of(AppRoutes.navigatorKey.currentContext!).pop(); isCallEnded = true; }); @@ -339,6 +338,7 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { void onCallDeclinedAsync(List? params) { print("================= On Declained ========================"); + logger.d(params); // endCall().then((bool value) { // if (value) { // isCallEnded = true; @@ -564,6 +564,7 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { _localStream ??= await navigator.mediaDevices.getUserMedia(isVideoCall ? videoConstraints : audioConstraints); localVideoRenderer!.srcObject = _localStream; await remoteRenderer!.initialize(); + notifyListeners(); } Future startIncomingCallViaKit({bool isVCall = true, required var inCallData}) async { diff --git a/lib/ui/chat/call/chat_incoming_call_screen.dart b/lib/ui/chat/call/chat_incoming_call_screen.dart index f890696..f7e188b 100644 --- a/lib/ui/chat/call/chat_incoming_call_screen.dart +++ b/lib/ui/chat/call/chat_incoming_call_screen.dart @@ -11,7 +11,6 @@ import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/main.dart'; -import 'package:mohem_flutter_app/models/chat/call.dart'; import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart'; import 'package:mohem_flutter_app/models/chat/incoming_call_model.dart'; import 'package:mohem_flutter_app/provider/chat_call_provider.dart'; @@ -39,15 +38,13 @@ class _StartCallPageState extends State { void dispose() { super.dispose(); } - - + @override void didChangeDependencies() { // TODO: implement didChangeDependencies super.didChangeDependencies(); } - void startCall() async { IncomingCallModel? sessionData; dynamic calls = await FlutterCallkitIncoming.activeCalls(); @@ -57,15 +54,18 @@ class _StartCallPageState extends State { } if (isIncomingCall) { if (provider.isUserOnline) { + cProv.isUserOnline = provider.isUserOnline; if (kDebugMode) { print("====== Processing Incoming Call in Online State ========="); } + await cProv.startIncomingCallViaKit(inCallData: sessionData!.extra!.callerDetails!.toJson()); cProv.init(); } else { if (kDebugMode) { print("====== Processing Incoming Call ========="); } + cProv.isUserOnline = provider.isUserOnline; await cProv.startIncomingCallViaKit(inCallData: sessionData!.extra!.callerDetails!.toJson()); try { AppState().setchatUserDetails = UserAutoLoginModel(response: Response.fromJson(sessionData.extra!.loginDetails!.toJson()), errorResponses: null); @@ -122,8 +122,8 @@ class _StartCallPageState extends State { @override Widget build(BuildContext context) { - cProv=context.read(); - provider=context.read(); + cProv = context.read(); + provider = context.read(); startCall(); return Scaffold( extendBody: true, diff --git a/lib/ui/chat/call/chat_outgoing_call_screen.dart b/lib/ui/chat/call/chat_outgoing_call_screen.dart index 6a1a3c7..1db6ecc 100644 --- a/lib/ui/chat/call/chat_outgoing_call_screen.dart +++ b/lib/ui/chat/call/chat_outgoing_call_screen.dart @@ -10,7 +10,6 @@ import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/models/chat/call.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/chat/call/chat_incoming_call_screen.dart'; import 'package:provider/provider.dart'; class OutGoingCall extends StatefulWidget { @@ -42,17 +41,11 @@ class _OutGoingCallState extends State { void dispose() { super.dispose(); } - - @override - void didChangeDependencies() { - // TODO: implement didChangeDependencies - super.didChangeDependencies(); - } @override Widget build(BuildContext context) { - chatProvider = Provider.of(context, listen: true); - callProvider = Provider.of(context, listen: true); + chatProvider = Provider.of(context, listen: false); + callProvider = Provider.of(context, listen: false); init(); return Scaffold( body: Consumer(builder: (BuildContext context, ChatCallProvider chatcp, Widget? child) { diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 87eadd2..3a65791 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -51,15 +51,14 @@ class _DashboardScreenState extends State with WidgetsBindingOb late ChatProviderModel cProvider; late ChatCallProvider chatCallProvider; final GlobalKey _scaffoldState = GlobalKey(); - final RefreshController _refreshController = RefreshController(initialRefresh: false); - int currentIndex = 0; @override void initState() { WidgetsBinding.instance.addObserver(this); super.initState(); + scheduleMicrotask(() { data = Provider.of(context, listen: false); marathonProvider = Provider.of(context, listen: false); @@ -166,7 +165,7 @@ class _DashboardScreenState extends State with WidgetsBindingOb print("-------------------- Survey ----------------------------"); if (val.result!.data!.notificationType == "Survey") { DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then( - (value) { + (value) { if (value!.mohemmItgResponseItem!.statusCode == 200) { if (value.mohemmItgResponseItem!.result!.data != null) { // Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data); @@ -617,16 +616,15 @@ class _DashboardScreenState extends State with WidgetsBindingOb icon: Stack( alignment: Alignment.centerLeft, children: [ - SvgPicture.asset( - "assets/icons/chat/chat.svg", - color: !checkIfPrivilegedForChat() - ? MyColors.lightGreyE3Color - : currentIndex == 4 - ? MyColors.grey3AColor - : cProvider.disableChatForThisUser - ? MyColors.lightGreyE3Color - : MyColors.grey98Color, - ).paddingAll(4), + SvgPicture.asset("assets/icons/chat/chat.svg", color: !checkIfPrivilegedForChat() ? MyColors.lightGreyE3Color : MyColors.grey98Color + + // currentIndex == 4 + // ? MyColors.grey3AColor + // : cProvider.disableChatForThisUser + // ? MyColors.lightGreyE3Color + // : MyColors.grey98Color, + ) + .paddingAll(4), Consumer( builder: (BuildContext cxt, ChatProviderModel data, Widget? child) { return !checkIfPrivilegedForChat() @@ -637,7 +635,7 @@ class _DashboardScreenState extends State with WidgetsBindingOb child: Container( padding: const EdgeInsets.only(left: 4, right: 4), alignment: Alignment.center, - decoration: BoxDecoration(color: cProvider.disableChatForThisUser ? MyColors.pinkDarkColor : MyColors.redColor, borderRadius: BorderRadius.circular(17)), + decoration: BoxDecoration(color: data.disableChatForThisUser ? MyColors.pinkDarkColor : MyColors.redColor, borderRadius: BorderRadius.circular(17)), child: data.chatUConvCounter.toString().toText10(color: Colors.white), ), );