From a992c8dae9253a6667cf4282fff5618721314c3f Mon Sep 17 00:00:00 2001 From: Aamir-iMac Date: Thu, 1 Jun 2023 16:00:17 +0300 Subject: [PATCH] Changes On iOS --- lib/classes/chat_call_kit.dart | 135 ++++++------------ lib/classes/navigationService.dart | 27 ---- lib/classes/notifications.dart | 20 ++- lib/main.dart | 10 +- lib/provider/chat_call_provider.dart | 51 +++++-- .../chat/call/chat_incoming_call_screen.dart | 44 +----- lib/ui/landing/dashboard_screen.dart | 61 +++++++- lib/ui/login/login_screen.dart | 74 +++++++++- lib/ui/login/verify_last_login_screen.dart | 7 +- 9 files changed, 219 insertions(+), 210 deletions(-) delete mode 100644 lib/classes/navigationService.dart diff --git a/lib/classes/chat_call_kit.dart b/lib/classes/chat_call_kit.dart index b785fa2..7440cfb 100644 --- a/lib/classes/chat_call_kit.dart +++ b/lib/classes/chat_call_kit.dart @@ -1,13 +1,12 @@ import 'dart:convert'; +import 'dart:math'; +import 'package:easy_localization/easy_localization.dart'; 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/consts.dart'; -import 'package:mohem_flutter_app/classes/navigationService.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'; @@ -15,7 +14,6 @@ import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' a import 'package:mohem_flutter_app/models/chat/incoming_call_model.dart'; import 'package:mohem_flutter_app/provider/chat_call_provider.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; -import 'package:mohem_flutter_app/ui/chat/call/chat_incoming_call_screen.dart'; import 'package:signalr_netcore/hub_connection.dart'; import 'package:signalr_netcore/signalr_client.dart'; @@ -25,15 +23,14 @@ class ChatVoipCall { ChatVoipCall._internal(); factory ChatVoipCall() => _instance; + late ChatProviderModel prov; late ChatCallProvider cProv; 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(); await FlutterCallkitIncoming.endAllCalls(); ALM.Response autoLoginData; SingleUserChatModel callerData; @@ -67,7 +64,13 @@ class ChatVoipCall { textDecline: 'Decline', textMissedCall: 'Missed call', textCallback: 'Call back', - extra: {"loginDetails": autoLoginData.toJson(), "callerDetails": callerData.toJson(), 'isIncomingCall': true, 'isUserOnline': isUserOnline, 'callType': data.data["callType"]}, + extra: { + "loginDetails": autoLoginData.toJson(), + "callerDetails": callerData.toJson(), + 'isIncomingCall': true, + 'isUserOnline': isUserOnline, + 'callType': data.data["callType"], + }, android: const AndroidParams( isCustomNotification: true, isShowLogo: false, @@ -95,117 +98,59 @@ 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) { - if (calls.isNotEmpty) { - return calls[0]; - } else { - return null; - } - } - } - - void checkAndNavigationCallingPage() async { - dynamic currentCall = await getCurrentCall(); - if (currentCall != null) { - Future.delayed(const Duration(seconds: 1)).whenComplete(() { - Navigator.pushNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.chatStartCall); - }); - } - } - - Future isCall() async { - dynamic calls = await FlutterCallkitIncoming.activeCalls(); - if (calls is List) { - if (calls.isNotEmpty) { - NavigationService.navigateToPage(StartCallPage()); - } - } - } - -//Function(CallEvent) callback - Future listenerEvent() async { - try { - FlutterCallkitIncoming.onEvent.listen((CallEvent? event) async { - switch (event!.event) { - case Event.ACTION_CALL_INCOMING: - break; - case Event.ACTION_CALL_START: - break; - case Event.ACTION_CALL_ACCEPT: - if (isUserOnline) { - checkAndNavigationCallingPage(); - } else { - isCall(); - } - break; - case Event.ACTION_CALL_DECLINE: - Utils.saveStringFromPrefs("isIncomingCall", "false"); - Utils.saveStringFromPrefs("inComingCallData", "null"); - declineCall(); - break; - case Event.ACTION_CALL_ENDED: - Utils.saveStringFromPrefs("isIncomingCall", "false"); - Utils.saveStringFromPrefs("inComingCallData", "null"); - FlutterCallkitIncoming.endAllCalls(); - break; - case Event.ACTION_CALL_TIMEOUT: - Utils.saveStringFromPrefs("isIncomingCall", "false"); - Utils.saveStringFromPrefs("inComingCallData", "null"); - FlutterCallkitIncoming.endAllCalls(); - break; - } - }); - } on Exception {} - } - - Future declineCall() async { + Future declineCall({var payload}) async { + IncomingCallModel data = IncomingCallModel.fromJson(jsonDecode(payload)); if (isUserOnline) { - HubConnection hc = await makeHub(); - await hc.start(); - print("Connection State ===" + chatHubConnection.state.toString()); - if (hc.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()), + HubConnection _hc = await makeHub(sessionData: data); + await _hc.start(); + if (_hc.state == HubConnectionState.Connected) { + if (data.extra != null) { + _hc.invoke("HangUpAsync", args: [ + data.extra!.callerDetails!.currentUserId!, + data.extra!.callerDetails!.targetUserId!, ]); - chatHubConnection.invoke("UpdateUserStatusAsync", args: [ - int.parse(sessionData.extra!.callerDetails!.currentUserId.toString()), + _hc.invoke("UpdateUserStatusAsync", args: [ + int.parse(data.extra!.callerDetails!.currentUserId.toString()), 1, ]); - FlutterCallkitIncoming.endCall(sessionData.id!); - chatHubConnection = hc; + FlutterCallkitIncoming.endAllCalls(); + chatHubConnection = _hc; } } } else { - HubConnection hc = await makeHub(); - await hc.start(); - await hc.invoke( + Utils.showToast("Offline END Call", longDuration: true); + HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); + HubConnection _bghc = HubConnectionBuilder() + .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${data.extra!.loginDetails!.id}&source=Desktop&access_token=${data.extra?.loginDetails!.token}", options: httpOp) + .withAutomaticReconnect(retryDelays: [2000, 5000, 10000, 20000]).build(); + await _bghc.start(); + await _bghc.invoke( "HangUpAsync", args: [ - int.parse(sessionData.extra!.callerDetails!.currentUserId.toString()), - int.parse(sessionData.extra!.callerDetails!.targetUserId.toString()), + data.extra!.callerDetails!.currentUserId!, + data.extra!.callerDetails!.targetUserId!, ], ); - FlutterCallkitIncoming.endCall(sessionData.id!); + _bghc.invoke("UpdateUserStatusAsync", args: [ + int.parse(data.extra!.callerDetails!.currentUserId.toString()), + 2, + ]); + FlutterCallkitIncoming.endAllCalls(); if (!isUserOnline) { - hc.stop(); + _bghc.stop(); } else { - chatHubConnection = hc; + chatHubConnection = _bghc; } } } - Future makeHub() async { + Future makeHub({required IncomingCallModel sessionData}) async { late HubConnection hc; try { HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); diff --git a/lib/classes/navigationService.dart b/lib/classes/navigationService.dart deleted file mode 100644 index f193c9b..0000000 --- a/lib/classes/navigationService.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:get_it/get_it.dart'; -import 'package:mohem_flutter_app/config/routes.dart'; -import 'package:mohem_flutter_app/main.dart'; - - -void setupLocator() { - print("GetIt Registered :::::"); - locator.registerLazySingleton(() => NavigationService()); -} - -class NavigationService { - final GlobalKey navigatorKey = GlobalKey(); - - static Future navigateTo(String routeName) { - var key = locator().navigatorKey; - return key.currentState!.pushNamed(routeName); - } - - static Future navigateToPage(Widget page) { - var key = locator().navigatorKey; - var pageRoute = MaterialPageRoute(builder: (context) => page); - return Navigator.push(key.currentContext!, pageRoute); - } -} - - diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index 7fd0e14..d718874 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -55,6 +55,10 @@ class AppNotifications { Permission.notification.request(); } }); + + await FirebaseMessaging.instance.setAutoInitEnabled(true); + await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(alert: true, badge: true, sound: true); + RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage(); if (initialMessage != null) _handleMessage(initialMessage); @@ -115,14 +119,11 @@ class AppNotifications { } void _handleMessage(RemoteMessage message) { - print("res: ------handle message--------"); - logger.w(message); Utils.saveStringFromPrefs("isAppOpendByChat", "false"); if (message.data.isNotEmpty && message.data["messageType"] == 'chat') { Utils.saveStringFromPrefs("isAppOpendByChat", "true"); Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString()); } else if (message.data.isNotEmpty && message.data["messageType"] == 'call') { - logger.d(message.data); ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), data: message); } } @@ -132,18 +133,23 @@ class AppNotifications { Utils.saveStringFromPrefs("isAppOpendByChat", "true"); Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString()); } - print("hereeee"); } } -Future backgroundMessageHandler(RemoteMessage message) async { +const AndroidNotificationChannel channel = AndroidNotificationChannel( + 'high_importance_channel', // id + 'High Importance Notifications', // title + description: 'This channel is used for important notifications.', // description + importance: Importance.high, +); + +@pragma('vm:entry-point') +Future backgroundMessageHandler(RemoteMessage message) async { await Firebase.initializeApp(); - print("res: ------background message--------"); if (message.data.isNotEmpty && message.data["messageType"] == 'chat') { Utils.saveStringFromPrefs("isAppOpendByChat", "false"); Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString()); } else if (message.data.isNotEmpty && message.data["messageType"] == 'call') { - logger.d(message.data); ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), data: message, background: true); } } diff --git a/lib/main.dart b/lib/main.dart index 900a6d3..08203d5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,11 +3,9 @@ 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'; -import 'package:mohem_flutter_app/classes/navigationService.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/generated/codegen_loader.g.dart'; import 'package:mohem_flutter_app/models/post_params_model.dart'; @@ -23,7 +21,6 @@ import 'package:provider/single_child_widget.dart'; import 'package:signalr_netcore/hub_connection.dart'; import 'package:sizer/sizer.dart'; -final GetIt locator = GetIt.instance; late HubConnection chatHubConnection; Logger logger = Logger( // filter: null, // Use the default LogFilter (-> only log in debug mode) @@ -50,11 +47,8 @@ Future main() async { DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); - locator.registerSingleton(NavigationService(), - signalsReady: true); await EasyLocalization.ensureInitialized(); AppState().setPostParamsInitConfig(); - HttpOverrides.global = MyHttpOverrides(); isTablet = MediaQueryData.fromWindow(WidgetsBinding.instance.window).size.shortestSide >= ApiConsts.tabletMinLength; @@ -101,7 +95,6 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - callGlobalContext = context; return Sizer( builder: ( BuildContext context, @@ -117,9 +110,8 @@ class MyApp extends StatelessWidget { MonthYearPickerLocalizations.delegate, ); return MaterialApp( - navigatorKey: locator().navigatorKey, + navigatorKey: AppRoutes.navigatorKey, builder: (BuildContext context, Widget? child) { - AppRoutes.navigatorKey = locator().navigatorKey; return MediaQuery( data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), child: child!, diff --git a/lib/provider/chat_call_provider.dart b/lib/provider/chat_call_provider.dart index 957c2e6..9bdf0f9 100644 --- a/lib/provider/chat_call_provider.dart +++ b/lib/provider/chat_call_provider.dart @@ -210,6 +210,7 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { isIncomingCall = false; isOutGoingCall = false; isAudioCall = false; + if (isCallConnected) { if (_pc.connectionState == RTCPeerConnectionState.RTCPeerConnectionStateConnected) { print("------------------ PC Stopped ----------------------------"); @@ -217,10 +218,15 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { _pc.dispose(); } } - remoteRenderer!.dispose(); - localVideoRenderer!.dispose(); - localVideoRenderer = null; - remoteRenderer = null; + if (remoteRenderer != null) { + remoteRenderer!.dispose(); + remoteRenderer = null; + } + if (localVideoRenderer != null) { + localVideoRenderer!.dispose(); + localVideoRenderer = null; + } + if (_localStream != null) { _localStream!.dispose(); _localStream = null; @@ -248,10 +254,15 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { _pc.dispose(); } } - remoteRenderer!.dispose(); - localVideoRenderer!.dispose(); - localVideoRenderer = null; - remoteRenderer = null; + if (remoteRenderer != null) { + remoteRenderer!.dispose(); + remoteRenderer = null; + } + if (localVideoRenderer != null) { + localVideoRenderer!.dispose(); + localVideoRenderer = null; + } + if (_localStream != null) { _localStream!.dispose(); _localStream = null; @@ -259,7 +270,6 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { isOutGoingCall = false; isIncomingCall = false; isAudioCall = false; - // await initStreams().whenComplete(() => notifyListeners()); return true; } } @@ -285,7 +295,10 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { print("--------------------- onHangUp ---------------------------------------"); endCall(isUserOnline: isUserOnline).then((bool value) { - Navigator.of(AppRoutes.navigatorKey.currentContext!).pop(); + if (isCallConnected) { + Navigator.of(AppRoutes.navigatorKey.currentContext!).pop(); + isCallConnected = false; + } isCallEnded = true; }); } @@ -349,13 +362,21 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { // notifyListeners(); // } // }); + if (params != null) { + endCall(isUserOnline: isUserOnline).then((bool value) { + // if (isCallConnected) { + Navigator.of(AppRoutes.navigatorKey.currentContext!).pop(); + // isCallConnected = false; + // } + isCallEnded = true; + }); + } } //// Invoke Methods Future invoke({required String invokeMethod, required int currentUserID, required int targetUserID, var data, int userStatus = 1, var debugData}) async { List args = []; - // Utils.showToast(currentUserID.toString() + " -- " + targetUserID.toString() + " -- " + isVideoCall.toString()); if (invokeMethod == "CallUserAsync") { args = [currentUserID, targetUserID, isVideoCall]; } else if (invokeMethod == "answerCallAsync") { @@ -573,23 +594,23 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin { Future startIncomingCallViaKit({bool isVCall = true, required var inCallData}) async { Utils.saveStringFromPrefs("isIncomingCall", "false"); - if(isVCall) { + if (isVCall) { isVideoCall = isVCall; - }else{ + } else { isAudioCall = true; } await initStreams(); isIncomingCall = true; incomingCallData = SingleUserChatModel.fromJson(inCallData); loudOn(); - // notifyListeners(); + // notifyListeners(); } void connectIncomingCall() { invoke(invokeMethod: "answerCallAsync", currentUserID: AppState().getchatUserDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!); isIncomingCallLoader = false; isIncomingCall = true; - // isVideoCall = true; + // isVideoCall = true; notifyListeners(); } diff --git a/lib/ui/chat/call/chat_incoming_call_screen.dart b/lib/ui/chat/call/chat_incoming_call_screen.dart index 0dbec81..32ac3df 100644 --- a/lib/ui/chat/call/chat_incoming_call_screen.dart +++ b/lib/ui/chat/call/chat_incoming_call_screen.dart @@ -46,9 +46,7 @@ class _StartCallPageState extends State { dynamic calls = await FlutterCallkitIncoming.activeCalls(); if (calls.isNotEmpty) { sessionData = IncomingCallModel.fromRawJson(jsonEncode(calls[0])); - isIncomingCall = sessionData.extra!.isIncomingCall!; } - if (isIncomingCall) { if (provider.isUserOnline) { cProv.isUserOnline = provider.isUserOnline; if (kDebugMode) { @@ -73,50 +71,10 @@ class _StartCallPageState extends State { } catch (e) { logger.w(e); } - if (kDebugMode) { - print('========== END =============='); - } } - } - // else if (isOutGoingCall) { - // if (kDebugMode) { - // print("====== Processing Outgoing Call ========="); - // } - // - // } - else { - if (kDebugMode) { - print("====== Something Wrong With Call ========="); - } - } } - // void connection({required data, required bool isUserOnline}) async { - // if (isUserOnline) { - // cProv.isUserOnline = isUserOnline; - // cProv.startIncomingCallViaKit(inCallData: data); - // } else { - // dynamic callData = await jsonDecode(data); - // AppState().setchatUserDetails = UserAutoLoginModel( - // response: Response.fromJson(callData[0]["loginDetails"]), - // errorResponses: null, - // ); - // Utils.saveStringFromPrefs( - // "userLoginChatDetails", - // UserAutoLoginModel( - // response: Response.fromJson(callData[0]["loginDetails"]), - // errorResponses: null, - // ).toJson().toString()); - // cProv.startIncomingCallViaKit(inCallData: data); - // try { - // await prov.buildHubConnection(context: AppRoutes.navigatorKey.currentContext!, ccProvider: cProv).whenComplete(() { - // cProv.init(); - // }); - // } catch (e) { - // logger.w(e); - // } - // } - // } + @override Widget build(BuildContext context) { diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index e7fc4a3..290501a 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -1,14 +1,18 @@ import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'dart:ui' as ui; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_callkit_incoming/entities/call_event.dart'; +import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/chat_call_kit.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; @@ -17,11 +21,14 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/main.dart'; +import 'package:mohem_flutter_app/models/itg/itg_main_response.dart'; +import 'package:mohem_flutter_app/models/itg/itg_response_model.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; import 'package:mohem_flutter_app/models/privilege_list_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/provider/dashboard_provider_model.dart'; +import 'package:mohem_flutter_app/ui/chat/call/chat_incoming_call_screen.dart'; import 'package:mohem_flutter_app/ui/landing/widget/app_drawer.dart'; import 'package:mohem_flutter_app/ui/landing/widget/menus_widget.dart'; import 'package:mohem_flutter_app/ui/landing/widget/services_widget.dart'; @@ -35,8 +42,6 @@ import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:signalr_netcore/signalr_client.dart'; - - class DashboardScreen extends StatefulWidget { DashboardScreen({Key? key}) : super(key: key); @@ -60,6 +65,7 @@ class _DashboardScreenState extends State with WidgetsBindingOb WidgetsBinding.instance.addObserver(this); super.initState(); + // callListeners(); scheduleMicrotask(() { data = Provider.of(context, listen: false); marathonProvider = Provider.of(context, listen: false); @@ -72,6 +78,51 @@ class _DashboardScreenState extends State with WidgetsBindingOb }); } + Future callListeners() async { + try { + FlutterCallkitIncoming.onEvent.listen((CallEvent? event) async { + switch (event!.event) { + case Event.ACTION_CALL_INCOMING: + break; + case Event.ACTION_CALL_START: + break; + case Event.ACTION_CALL_ACCEPT: + if (mounted) { + moveToCallScreen(); + } + break; + case Event.ACTION_CALL_DECLINE: + Utils.saveStringFromPrefs("isIncomingCall", "false"); + Utils.saveStringFromPrefs("inComingCallData", "null"); + await ChatVoipCall().declineCall(payload: jsonEncode(event.body)); + break; + case Event.ACTION_CALL_ENDED: + Utils.saveStringFromPrefs("isIncomingCall", "false"); + Utils.saveStringFromPrefs("inComingCallData", "null"); + FlutterCallkitIncoming.endAllCalls(); + break; + case Event.ACTION_CALL_TIMEOUT: + Utils.saveStringFromPrefs("isIncomingCall", "false"); + Utils.saveStringFromPrefs("inComingCallData", "null"); + FlutterCallkitIncoming.endAllCalls(); + break; + } + }); + } on Exception {} + } + + Future moveToCallScreen() async { + dynamic calls = await FlutterCallkitIncoming.activeCalls(); + if (calls is List) { + if (calls.isNotEmpty) { + Future.delayed(const Duration(seconds: 3)).whenComplete(() { + MaterialPageRoute pageRoute = MaterialPageRoute(builder: (BuildContext context) => StartCallPage()); + Navigator.push(context, pageRoute); + }); + } + } + } + @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { @@ -161,12 +212,12 @@ class _DashboardScreenState extends State with WidgetsBindingOb } void checkERMChannel() { - data.getITGNotification().then((val) { + data.getITGNotification().then((MohemmItgResponseItem? val) { if (val!.result!.data != null) { print("-------------------- Survey ----------------------------"); if (val.result!.data!.notificationType == "Survey") { DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then( - (value) { + (ItgMainRes? value) { if (value!.mohemmItgResponseItem!.statusCode == 200) { if (value.mohemmItgResponseItem!.result!.data != null) { // Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data); @@ -182,7 +233,7 @@ class _DashboardScreenState extends State with WidgetsBindingOb } else { print("------------------------------------------- Ads --------------------"); DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then( - (value) { + (ItgMainRes? value) { if (value!.mohemmItgResponseItem!.statusCode == 200) { if (value.mohemmItgResponseItem!.result!.data != null) { Navigator.pushNamed(context, AppRoutes.advertisement, arguments: { diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 8a78dfd..f669158 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; @@ -8,10 +9,13 @@ import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_callkit_incoming/entities/call_event.dart'; +import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; // import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/chat_call_kit.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/notifications.dart'; @@ -28,8 +32,8 @@ import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'package:mohem_flutter_app/models/privilege_list_model.dart'; +import 'package:mohem_flutter_app/ui/chat/call/chat_incoming_call_screen.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; -import 'package:mohem_flutter_app/widgets/button/hmg_connectivity_button.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart'; // import 'package:safe_device/safe_device.dart'; @@ -61,6 +65,7 @@ class _LoginScreenState extends State { bool isRealDevice = false; bool isOnExternalStorage = false; bool isDevelopmentModeEnable = false; + bool isIncomingCall = false; // late HmsApiAvailability hmsApiAvailability; @@ -72,6 +77,7 @@ class _LoginScreenState extends State { // if (kReleaseMode) { // checkDeviceSafety(); // } + callListeners(); } // void checkDeviceSafety() async { @@ -90,6 +96,58 @@ class _LoginScreenState extends State { // } // } + Future callListeners() async { + try { + FlutterCallkitIncoming.onEvent.listen((CallEvent? event) async { + switch (event!.event) { + case Event.ACTION_CALL_INCOMING: + break; + case Event.ACTION_CALL_START: + break; + case Event.ACTION_CALL_ACCEPT: + if (mounted) { + isIncomingCall = true; + moveToCallScreen(); + } + break; + case Event.ACTION_CALL_DECLINE: + Utils.saveStringFromPrefs("isIncomingCall", "false"); + Utils.saveStringFromPrefs("inComingCallData", "null"); + await ChatVoipCall().declineCall(payload: jsonEncode(event.body)); + + break; + case Event.ACTION_CALL_ENDED: + Utils.saveStringFromPrefs("isIncomingCall", "false"); + Utils.saveStringFromPrefs("inComingCallData", "null"); + FlutterCallkitIncoming.endAllCalls(); + break; + case Event.ACTION_CALL_TIMEOUT: + Utils.saveStringFromPrefs("isIncomingCall", "false"); + Utils.saveStringFromPrefs("inComingCallData", "null"); + FlutterCallkitIncoming.endAllCalls(); + break; + } + }); + } on Exception {} + } + + Future moveToCallScreen() async { + dynamic calls = await FlutterCallkitIncoming.activeCalls(); + if (calls is List) { + if (calls.isNotEmpty) { + Utils.hideLoading(context); + var pageRoute = MaterialPageRoute(builder: (context) => StartCallPage()); + Navigator.push(context, pageRoute).whenComplete((){ + checkFirebaseToken(); + }); + }else{ + FlutterCallkitIncoming.endAllCalls(); + Utils.showToast("Something wen't wrong"); + } + } + } + + @override void dispose() { super.dispose(); @@ -100,7 +158,7 @@ class _LoginScreenState extends State { Future checkFirebaseToken() async { try { - Utils.showLoading(context); + //Utils.showLoading(context); if (Platform.isAndroid) { try { if (!(await Utils.isGoogleServicesAvailable())) { @@ -194,7 +252,10 @@ class _LoginScreenState extends State { @override Widget build(BuildContext context) { if (isAppOpenBySystem == null) { - isAppOpenBySystem = (ModalRoute.of(context)!.settings.arguments ?? true) as bool; + isAppOpenBySystem = (ModalRoute + .of(context)! + .settings + .arguments ?? true) as bool; if (!kReleaseMode) { // username.text = "15444"; // Maha User // username.text = "15153"; // Tamer User @@ -206,7 +267,12 @@ class _LoginScreenState extends State { // 13777 // Ab12345cd } - if (isAppOpenBySystem!) checkFirebaseToken(); + Utils.showLoading(context); + Future.delayed(const Duration(seconds: 2)).whenComplete(() { + if (!isIncomingCall) { + if (isAppOpenBySystem!) checkFirebaseToken(); + } + }); } // username.text = "15444"; diff --git a/lib/ui/login/verify_last_login_screen.dart b/lib/ui/login/verify_last_login_screen.dart index f94e59a..b6b5953 100644 --- a/lib/ui/login/verify_last_login_screen.dart +++ b/lib/ui/login/verify_last_login_screen.dart @@ -3,7 +3,6 @@ import 'dart:io'; import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; import 'package:flutter_svg/svg.dart'; import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; @@ -21,6 +20,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart'; +import 'package:mohem_flutter_app/ui/chat/call/chat_incoming_call_screen.dart'; import 'package:mohem_flutter_app/ui/dialogs/id/business_card_dialog.dart'; import 'package:mohem_flutter_app/ui/dialogs/id/employee_digital_id_dialog.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; @@ -51,19 +51,16 @@ class _VerifyLastLoginScreenState extends State { @override void initState() { - _getAvailableBiometrics(); + _getAvailableBiometrics(); // setDefault(); super.initState(); } - - @override Widget build(BuildContext context) { mobileLoginInfoListModel ??= ModalRoute.of(context)!.settings.arguments as GetMobileLoginInfoListModel; // String empName = AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr! : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!; String empName = mobileLoginInfoListModel!.employeeName!; - return Scaffold( appBar: AppBar( backgroundColor: Colors.transparent,