Changes On iOS

merge-requests/188/head
Aamir Muhammad 2 years ago
parent 68f4d21a4a
commit 02073faf9d

@ -4,6 +4,8 @@ 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/navigationService.dart';
import 'package:mohem_flutter_app/classes/notifications.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/main.dart';
@ -15,7 +17,7 @@ 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 extends WidgetsBindingObserver {
class ChatVoipCall {
static final ChatVoipCall _instance = ChatVoipCall._internal();
ChatVoipCall._internal();
@ -34,9 +36,10 @@ class ChatVoipCall extends WidgetsBindingObserver {
ALM.Response autoLoginData;
SingleUserChatModel callerData;
if (data!.data["user_token_response"] == null || data.data["user_token_response"].isEmpty) {
logger.d(AppState().getchatUserDetails!.response!.toJson());
// Online & App Logged In
autoLoginData = ALM.Response.fromJson(AppState().getchatUserDetails!.response!.toJson());
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"],
@ -100,38 +103,10 @@ class ChatVoipCall extends WidgetsBindingObserver {
await FlutterCallkitIncoming.showCallkitIncoming(params);
}
}
Future<void> initProviders() async {
cProv = Provider.of<ChatCallProvider>(AppRoutes.navigatorKey.currentContext!, listen: false);
prov = Provider.of<ChatProviderModel>(AppRoutes.navigatorKey.currentContext!, listen: false);
}
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,
);
cProv.startIncomingCallViaKit(inCallData: data);
try {
await prov.buildHubConnection(context: AppRoutes.navigatorKey.currentContext!, ccProvider: cProv).whenComplete(() {
cProv.init();
});
} catch (e) {
logger.w(e);
}
}
}
Future getCurrentCall() async {
var calls = await FlutterCallkitIncoming.activeCalls();
if (calls is List) {
if (calls.isNotEmpty) {
print('DATA------------: $calls');
return calls[0];
} else {
return null;
@ -144,19 +119,19 @@ class ChatVoipCall extends WidgetsBindingObserver {
if (currentCall != null) {
Future.delayed(const Duration(seconds: 2)).whenComplete(() {
Navigator.pushNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.chatStartCall);
// NavigationService.instance
// .pushNamedIfNotCurrent(AppRoute.callingPage, args: currentCall);
});
}
}
Future<void> isCall() async {
var calls = await FlutterCallkitIncoming.activeCalls();
if (calls is List) {
if (calls.isNotEmpty) {
Navigator.pushNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.chatStartCall);
NavigationService.navigateTo(AppRoutes.chatStartCall);
}
}
}
//Function(CallEvent) callback
Future<void> listenerEvent() async {
try {
@ -167,19 +142,11 @@ class ChatVoipCall extends WidgetsBindingObserver {
case Event.ACTION_CALL_START:
break;
case Event.ACTION_CALL_ACCEPT:
print("------------------------------------------Call Accepted By User ----------------------------------------------");
if (isUserOnline) {
checkAndNavigationCallingPage();
} else {
Utils.showToast("BackgroundState Else Started", longDuration: true);
isCall();
}
// checkAndNavigationCallingPage();
// Navigator.pushNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.chatStartCall);
// checkAndNavigationCallingPage();
checkAndNavigationCallingPage();
} else {
isCall();
}
break;
case Event.ACTION_CALL_DECLINE:
cProv.isIncomingCall = true;
@ -197,56 +164,11 @@ class ChatVoipCall extends WidgetsBindingObserver {
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 {}
}
//
// void didChangeAppLifecycleState(AppLifecycleState state) {
// super.didChangeAppLifecycleState(state);
// switch (state) {
// case AppLifecycleState.paused:
// logger.i('paused');
// break;
// case AppLifecycleState.inactive:
// logger.i('inactive');
// break;
// case AppLifecycleState.resumed:
// logger.i('resumed');
// break;
// case AppLifecycleState.detached:
// logger.i('detached');
// break;
// }
// }
// @override
// void dispose() {
// WidgetsBinding.instance.removeObserver(this);
// }
void nothing() {
// if (!background) {
// await initProviders();
@ -277,10 +199,4 @@ class ChatVoipCall extends WidgetsBindingObserver {
// }
// Navigator.pushNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.chatStartCall);
}
//
// @override
// void dispose() {
// WidgetsBinding.instance.removeObserver(this);
// }
}

@ -0,0 +1,25 @@
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';
final locator = GetIt.instance;
class NavigationService {
final GlobalKey<NavigatorState> navigatorKey = AppRoutes.navigatorKey;
static Future<dynamic> navigateTo(String routeName) {
var key = locator<NavigationService>().navigatorKey;
return key.currentState!.pushNamed(routeName);
}
static Future<dynamic> navigateToPage(Widget page) {
var key = locator<NavigationService>().navigatorKey;
var pageRoute = MaterialPageRoute(builder: (context) => page);
return Navigator.push(key.currentContext!, pageRoute);
}
}
void setupLocator() {
locator.registerLazySingleton( ()=> NavigationService());
}

@ -16,9 +16,8 @@ import 'package:uuid/uuid.dart';
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
class AppNotifications extends WidgetsBindingObserver {
class AppNotifications {
static final AppNotifications _instance = AppNotifications._internal();
AppNotifications._internal();
factory AppNotifications() => _instance;
@ -89,12 +88,8 @@ class AppNotifications extends WidgetsBindingObserver {
// print(err);
// });
}
}
void initHuaweiPush(Function loginCallback) {
AppState().setIsHuawei = true;
initTokenStream(loginCallback);
@ -119,15 +114,12 @@ class AppNotifications extends WidgetsBindingObserver {
}
void _handleMessage(RemoteMessage message) {
logger.d("=============== appOpen ======================");
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') {
if (Platform.isAndroid) {
ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), data: message);
}
}
}
@ -147,15 +139,10 @@ AndroidNotificationChannel channel = const AndroidNotificationChannel(
Future<dynamic> backgroundMessageHandler(RemoteMessage message) async {
await Firebase.initializeApp();
logger.d("=============== appBackground ======================");
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') {
if (Platform.isAndroid) {
ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), data: message, background: true);
}
}
}

@ -6,6 +6,7 @@ import 'package:flutter/services.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';
@ -28,7 +29,7 @@ Logger logger = Logger(
// output: null, // U
);
enum AppRunningStates { resume, background, closed }
late BuildContext callGlobalContext;
class MyHttpOverrides extends HttpOverrides {
@override
@ -47,6 +48,7 @@ Future<void> main() async {
]);
await EasyLocalization.ensureInitialized();
AppState().setPostParamsInitConfig();
setupLocator();
HttpOverrides.global = MyHttpOverrides();
isTablet = MediaQueryData.fromWindow(WidgetsBinding.instance.window).size.shortestSide >= ApiConsts.tabletMinLength;
@ -93,6 +95,7 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
callGlobalContext = context;
return Sizer(
builder: (
BuildContext context,
@ -124,6 +127,7 @@ class MyApp extends StatelessWidget {
locale: context.locale,
initialRoute: AppRoutes.initialRoute,
routes: AppRoutes.routes,
);
},
);

@ -66,62 +66,62 @@ class IncomingCallModel {
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"].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"].toInt(),
uuid: json["uuid"],
);
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,
};
"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 {
@ -131,11 +131,9 @@ class Args {
String toRawJson() => json.encode(toJson());
factory Args.fromJson(Map<String, dynamic> json) => Args(
);
factory Args.fromJson(Map<String, dynamic> json) => Args();
Map<String, dynamic> toJson() => {
};
Map<String, dynamic> toJson() => {};
}
class Extra {
@ -154,16 +152,16 @@ class Extra {
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"],
callerDetails: json["callerDetails"] == null ? null : CallerDetails.fromJson(json["callerDetails"]),
);
loginDetails: json["loginDetails"] == null ? null : LoginDetails.fromJson(json["loginDetails"]),
isIncomingCall: json["isIncomingCall"],
callerDetails: json["callerDetails"] == null ? null : CallerDetails.fromJson(json["callerDetails"]),
);
Map<String, dynamic> toJson() => {
"loginDetails": loginDetails?.toJson(),
"isIncomingCall": isIncomingCall,
"callerDetails": callerDetails?.toJson(),
};
"loginDetails": loginDetails?.toJson(),
"isIncomingCall": isIncomingCall,
"callerDetails": callerDetails?.toJson(),
};
}
class CallerDetails {
@ -214,48 +212,48 @@ class CallerDetails {
String toRawJson() => json.encode(toJson());
factory CallerDetails.fromJson(Map<String, dynamic> json) => CallerDetails(
userChatHistoryId: 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"].toInt(),
isSeen: json["isSeen"],
userChatHistoryLineId: json["userChatHistoryLineId"].toInt(),
isDelivered: json["isDelivered"],
targetUserName: json["targetUserName"],
currentUserId: json["currentUserId"].toInt(),
createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]),
currentUserEmail: json["currentUserEmail"],
contantNo: json["contantNo"],
chatEventId: json["chatEventId"].toInt(),
encryptedTargetUserName: json["encryptedTargetUserName"],
chatSource: json["chatSource"].toInt(),
);
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,
};
"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 {
@ -270,12 +268,12 @@ class FileTypeResponse {
String toRawJson() => json.encode(toJson());
factory FileTypeResponse.fromJson(Map<String, dynamic> json) => FileTypeResponse(
fileTypeId:json["fileTypeId"].toInt(),
);
fileTypeId: json["fileTypeId"].toInt(),
);
Map<String, dynamic> toJson() => {
"fileTypeId": fileTypeId,
};
"fileTypeId": fileTypeId,
};
}
class LoginDetails {
@ -306,26 +304,26 @@ class LoginDetails {
String toRawJson() => json.encode(toJson());
factory LoginDetails.fromJson(Map<String, dynamic> json) => LoginDetails(
isActiveCode: json["isActiveCode"],
id: json["id"].toInt(),
encryptedUserName: json["encryptedUserName"],
userName: json["userName"],
title: json["title"],
encryptedUserId: json["encryptedUserId"],
email: json["email"],
isDomainUser: json["isDomainUser"],
token: json["token"],
);
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,
};
"isActiveCode": isActiveCode,
"id": id,
"encryptedUserName": encryptedUserName,
"userName": userName,
"title": title,
"encryptedUserId": encryptedUserId,
"email": email,
"isDomainUser": isDomainUser,
"token": token,
};
}

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:just_audio/just_audio.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
@ -40,7 +41,6 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
bool isIncomingCallLoader = true;
bool isIncomingCall = false;
bool isOutGoingCall = false;
bool isUserOnline = false;
late BuildContext providerContext;
@ -204,7 +204,7 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
if (_pc.connectionState == RTCPeerConnectionState.RTCPeerConnectionStateConnected) {
print("------------------ PC Stopped ----------------------------");
_pc.close();
_pc.dispose();
// _pc.dispose();
}
isCallStarted = false;
isVideoCall = false;
@ -214,26 +214,27 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
localVideoRenderer.srcObject = null;
remoteRenderer.srcObject = null;
isIncomingCall = false;
isOutGoingCall = false;
if (chatHubConnection != null) {
chatHubConnection.stop();
await localVideoRenderer.dispose();
localStream.dispose();
remoteRenderer.dispose();
// await localVideoRenderer.dispose();
// localStream.dispose();
// remoteRenderer.dispose();
}
await FlutterCallkitIncoming.endAllCalls();
return true;
} else {
if (isOutGoingCall) {
await invoke(invokeMethod: "HangUpAsync", currentUserID: outGoingCallData.callerId!, targetUserID: outGoingCallData.receiverId!, userStatus: 1);
await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: outGoingCallData.callerId!, targetUserID: outGoingCallData.receiverId!, userStatus: 0);
} else {
} else if (isIncomingCall) {
await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!, userStatus: 1);
}
if (_pc.connectionState == RTCPeerConnectionState.RTCPeerConnectionStateConnected) {
_pc.close();
_pc.dispose();
localStream.dispose();
remoteRenderer.dispose();
// _pc.dispose();
// localStream.dispose();
// remoteRenderer.dispose();
}
isCallStarted = false;
isVideoCall = false;
@ -241,9 +242,10 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
isMicOff = false;
isLoudSpeaker = false;
localVideoRenderer.srcObject = null;
await localVideoRenderer.dispose();
// await localVideoRenderer.dispose();
remoteRenderer.srcObject = null;
isOutGoingCall = false;
isIncomingCall = false;
return true;
}
}
@ -275,10 +277,10 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
void onHangUpAsync(List<Object?>? params) {
print("--------------------- onHangUp ---------------------------------------");
isOutGoingCall = false;
// isEndedByCaller = true;
// isEndedByCaller = true;
endCall().then((bool value) {
Navigator.of(AppRoutes.navigatorKey.currentContext!).pop();
// notifyListeners();
// notifyListeners();
isCallEnded = true;
});
}
@ -423,7 +425,7 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
};
RTCPeerConnection pc = await createPeerConnection(configuration, offerSdpConstraints);
await pc!.addStream(localStream!);
await pc!.addStream(localStream);
pc?.onConnectionState = (RTCPeerConnectionState state) {};
pc?.onAddStream = (MediaStream stream) {
remoteRenderer.srcObject = stream;
@ -569,25 +571,15 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
isVideoCall = isVCall;
await initStreams();
isIncomingCall = true;
dynamic callData = await jsonDecode(inCallData);
incomingCallData = SingleUserChatModel.fromJson(callData[0]["callerDetails"]);
incomingCallData = SingleUserChatModel.fromJson(inCallData);
loudOn();
notifyListeners();
}
void connectIncomingCall() {
invoke(invokeMethod: "answerCallAsync", currentUserID: AppState().getchatUserDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!);
isIncomingCallLoader = false;
isIncomingCall = true;
isVideoCall = true;
notifyListeners();
}
////////////////// End Incoming Call ////////////////////////
//Extra
// void disposeRenders() async {
// await localVideoRenderer.dispose();
// localStream.dispose();
// notifyListeners();
// }
}

@ -81,7 +81,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
List<ChatUser>? chatUsersList = [];
int pageNo = 1;
bool disbaleChatForThisUser = false;
bool disableChatForThisUser = false;
bool isUserOnline = false;
bool isCall = false;
userLoginToken.UserAutoLoginModel userLoginData = userLoginToken.UserAutoLoginModel();
@ -91,16 +92,22 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
userLoginToken.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
Utils.saveStringFromPrefs("userLoginChatDetails", jsonEncode(userLoginResponse.response));
isUserOnline = true;
} else {
AppState().setchatUserDetails = userLoginResponse;
Utils.saveStringFromPrefs("userLoginChatDetails", "null");
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
disbaleChatForThisUser = true;
disableChatForThisUser = true;
isUserOnline = false;
notifyListeners();
}
} catch (e) {
disbaleChatForThisUser = true;
disableChatForThisUser = true;
isUserOnline = false;
notifyListeners();
}
}
@ -1023,7 +1030,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
void disposeData() {
if (!disbaleChatForThisUser) {
if (!disableChatForThisUser) {
search.clear();
isChatScreenActive = false;
receiverID = 0;

@ -1,22 +1,40 @@
import 'dart:convert';
import 'dart:core';
import 'dart:ui';
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/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';
class StartCallPage extends StatefulWidget {
@override
_StartCallPageState createState() => _StartCallPageState();
}
class _StartCallPageState extends State<StartCallPage> {
final dragController = DragController();
DragController dragController = DragController();
bool isOutGoingCall = false;
bool isIncomingCall = false;
late ChatCallProvider cProv;
late ChatProviderModel provider;
@override
void initState() {
super.initState();
cProv = Provider.of<ChatCallProvider>(context, listen: false);
provider = Provider.of<ChatProviderModel>(context, listen: false);
startCall();
}
@ -27,253 +45,544 @@ class _StartCallPageState extends State<StartCallPage> {
void startCall() async {
IncomingCallModel? sessionData;
var calls = await FlutterCallkitIncoming.activeCalls();
dynamic calls = await FlutterCallkitIncoming.activeCalls();
if (calls.isNotEmpty) {
sessionData = IncomingCallModel.fromRawJson(jsonEncode(calls[0]));
isIncomingCall = sessionData.extra!.isIncomingCall!;
}
if (isIncomingCall) {
if (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 =========");
}
await cProv.startIncomingCallViaKit(inCallData: sessionData!.extra!.callerDetails!.toJson());
try {
AppState().setchatUserDetails = UserAutoLoginModel(response: Response.fromJson(sessionData.extra!.loginDetails!.toJson()), errorResponses: null);
await provider.buildHubConnection(context: context, ccProvider: cProv).whenComplete(() {
cProv.init();
});
} 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 =========");
}
}
logger.d(sessionData!.extra!.isIncomingCall);
}
// 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) {
return Scaffold(
body: Center(
child: Container(
color: Colors.red,
width: 200,
height: 200,
),
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 (!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,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
40.height,
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
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.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,
),
],
),
),
),
],
),
],
),
),
),
),
),
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().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,
),
),
],
),
),
),
],
),
)
: 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,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
40.height,
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
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.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,
),
],
),
),
),
],
),
],
),
),
),
),
),
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().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,
),
),
],
),
),
),
],
),
)
: SizedBox(
child: Container(
color: Colors.red,
width: 200,
height: 200,
),
);
},
),
);
// return Scaffold(
// extendBody: true,
// body: Consumer2<ChatCallProvider, ChatProviderModel>(builder: (BuildContext context, ChatCallProvider provider, ChatProviderModel cpm, Widget? child) {
// // if (provider.isEndedByCaller && Platform.isAndroid) SystemNavigator.pop();
// return 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,
// ),
// ),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisSize: MainAxisSize.max,
// children: <Widget>[
// 40.height,
// Row(
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
// children: <Widget>[
// Container(
// 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.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,
// ),
// ],
// ),
// ),
// ),
// ],
// ),
// ],
// ),
// ),
// ),
// ),
// ),
// 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().then((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,
// ),
// ),
// ],
// ),
// ),
// ),
// ],
// )
// );
// }),
// );
}
}

@ -96,7 +96,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
showTyping: true,
chatUser: params!.chatUser,
actions: [
if (Platform.isAndroid)
// if (Platform.isAndroid)
SvgPicture.asset("assets/icons/chat/call.svg", width: 21, height: 23).onPress(() async {
Future<PermissionStatus> micPer = Permission.microphone.request();
if (await micPer.isGranted) {
@ -107,8 +107,9 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
});
}
}),
if (Platform.isAndroid) 24.width,
if (Platform.isAndroid)
// if (Platform.isAndroid)
24.width,
// if (Platform.isAndroid)
SvgPicture.asset("assets/icons/chat/video_call.svg", width: 21, height: 18).onPress(() async {
Future<PermissionStatus> camPer = Permission.camera.request();
if (await camPer.isGranted) {
@ -119,7 +120,8 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
});
}
}),
if (Platform.isAndroid) 21.width,
// if (Platform.isAndroid)
21.width,
],
),
body: SafeArea(

@ -91,14 +91,14 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
if (!cProvider.disbaleChatForThisUser) {
if (!cProvider.disableChatForThisUser) {
chatHubConnection.stop();
}
}
void _bHubCon() {
cProvider.getUserAutoLoginToken().whenComplete(() async {
if (!cProvider.disbaleChatForThisUser) {
if (!cProvider.disableChatForThisUser) {
String isAppOpendByChat = await Utils.getStringFromPrefs("isAppOpendByChat");
if (isAppOpendByChat != "null" && isAppOpendByChat == "true") {
Utils.showLoading(context);
@ -156,7 +156,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
if (isFromInit) {
checkERMChannel();
}
if (!cProvider.disbaleChatForThisUser && !isFromInit) checkHubCon();
if (!cProvider.disableChatForThisUser && !isFromInit) checkHubCon();
_refreshController.refreshCompleted();
}
@ -623,7 +623,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
? MyColors.lightGreyE3Color
: currentIndex == 4
? MyColors.grey3AColor
: cProvider.disbaleChatForThisUser
: cProvider.disableChatForThisUser
? MyColors.lightGreyE3Color
: MyColors.grey98Color,
).paddingAll(4),
@ -637,7 +637,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.disbaleChatForThisUser ? MyColors.pinkDarkColor : MyColors.redColor, borderRadius: BorderRadius.circular(17)),
decoration: BoxDecoration(color: cProvider.disableChatForThisUser ? MyColors.pinkDarkColor : MyColors.redColor, borderRadius: BorderRadius.circular(17)),
child: data.chatUConvCounter.toString().toText10(color: Colors.white),
),
);
@ -664,7 +664,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
} else if (index == 3) {
Navigator.pushNamed(context, AppRoutes.itemsForSale);
} else if (index == 4) {
if (!cProvider.disbaleChatForThisUser) {
if (!cProvider.disableChatForThisUser) {
Navigator.pushNamed(context, AppRoutes.chat);
}
}

@ -21,6 +21,7 @@ import 'package:mohem_flutter_app/extensions/int_extensions.dart';
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/chat/incoming_call_model.dart';
import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart';
import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart';
@ -94,9 +95,6 @@ class _LoginScreenState extends State<LoginScreen> {
super.dispose();
}
String? firebaseToken;
GetMobileLoginInfoListModel? loginInfo;

@ -51,8 +51,7 @@ class _VerifyLastLoginScreenState extends State<VerifyLastLoginScreen> {
@override
void initState() {
_getAvailableBiometrics();
print("------------------- Verfiy Screeeeeen -----------------------");
_getAvailableBiometrics();
// setDefault();
super.initState();
}

@ -91,6 +91,7 @@ dependencies:
draggable_widget: ^2.0.0
flutter_local_notifications: any
flutter_callkit_incoming: ^1.0.3+3
get_it: ^7.6.0
#firebase_analytics: any
#Chat Voice Message Recoding & Play

Loading…
Cancel
Save