Changes On iOS

merge-requests/188/head
Aamir Muhammad 2 years ago
parent 88ac343203
commit 8db09f20b7

@ -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)
}

@ -2,15 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsForMedia</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
@ -31,6 +22,10 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>sms</string>
@ -41,6 +36,15 @@
<true/>
<key>NFCReaderUsageDescription</key>
<string>This App requires access to NFC to mark your attendance.</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsForMedia</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
<key>NSCameraUsageDescription</key>
<string>This app requires camera access to capture &amp; upload picture as profile image.</string>
<key>NSFaceIDUsageDescription</key>
@ -51,20 +55,19 @@
<string>This App requires access to your location to mark your attendance.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This App requires access to your location to mark your attendance.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to select image as document &amp; upload it.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires microphone access to for call.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to select image as document &amp; upload it.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key>
<array>
<string>processing</string>
<string>processing</string>
<string>fetch</string>
<string>remote-notification</string>
<string>voip</string>
</array>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
@ -88,13 +91,9 @@
<array>
<string>0000</string>
</array>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
</array>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>

@ -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<void> 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<void> 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<void> 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: <int>[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();
}
}
}

@ -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<NavigatorState> navigatorKey = AppRoutes.navigatorKey;
final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
static Future<dynamic> navigateTo(String routeName) {
var key = locator<NavigationService>().navigatorKey;
@ -20,6 +24,4 @@ class NavigationService {
}
}
void setupLocator() {
locator.registerLazySingleton( ()=> NavigationService());
}

@ -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");
}
}

@ -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<void> 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<NavigationService>().navigatorKey,
builder: (BuildContext context, Widget? child) {
AppRoutes.navigatorKey = locator<NavigationService>().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,
);
},
);

@ -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<Object?>? 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<Object?>? 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<void> startIncomingCallViaKit({bool isVCall = true, required var inCallData}) async {

@ -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<StartCallPage> {
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<StartCallPage> {
}
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<StartCallPage> {
@override
Widget build(BuildContext context) {
cProv=context.read<ChatCallProvider>();
provider=context.read<ChatProviderModel>();
cProv = context.read<ChatCallProvider>();
provider = context.read<ChatProviderModel>();
startCall();
return Scaffold(
extendBody: true,

@ -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<OutGoingCall> {
void dispose() {
super.dispose();
}
@override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
chatProvider = Provider.of<ChatProviderModel>(context, listen: true);
callProvider = Provider.of<ChatCallProvider>(context, listen: true);
chatProvider = Provider.of<ChatProviderModel>(context, listen: false);
callProvider = Provider.of<ChatCallProvider>(context, listen: false);
init();
return Scaffold(
body: Consumer<ChatCallProvider>(builder: (BuildContext context, ChatCallProvider chatcp, Widget? child) {

@ -51,15 +51,14 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
late ChatProviderModel cProvider;
late ChatCallProvider chatCallProvider;
final GlobalKey<ScaffoldState> _scaffoldState = GlobalKey();
final RefreshController _refreshController = RefreshController(initialRefresh: false);
int currentIndex = 0;
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
scheduleMicrotask(() {
data = Provider.of<DashboardProviderModel>(context, listen: false);
marathonProvider = Provider.of<MarathonProvider>(context, listen: false);
@ -166,7 +165,7 @@ class _DashboardScreenState extends State<DashboardScreen> 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<DashboardScreen> 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<ChatProviderModel>(
builder: (BuildContext cxt, ChatProviderModel data, Widget? child) {
return !checkIfPrivilegedForChat()
@ -637,7 +635,7 @@ class _DashboardScreenState extends State<DashboardScreen> 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),
),
);

Loading…
Cancel
Save