Chat Fix & Calling

merge-requests/188/head
Aamir Muhammad 3 years ago
parent 7191e25ea5
commit d1ccaf7f56

@ -10,6 +10,7 @@ import 'package:huawei_push/huawei_push.dart' as huawei_push;
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/classes/voip_chat_call.dart'; import 'package:mohem_flutter_app/classes/voip_chat_call.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/provider/chat_call_provider.dart'; import 'package:mohem_flutter_app/provider/chat_call_provider.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@ -116,10 +117,18 @@ class AppNotifications {
void _handleMessage(RemoteMessage message) { void _handleMessage(RemoteMessage message) {
Utils.saveStringFromPrefs("isAppOpendByChat", "false"); Utils.saveStringFromPrefs("isAppOpendByChat", "false");
logger.d("Onlyyyyy Msg");
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') {
ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), data: message);
}
} }
void _handleOpenApp(RemoteMessage message) { void _handleOpenApp(RemoteMessage message) {
if (message.data.isNotEmpty && message.data["type"] == 'chat') { if (message.data.isNotEmpty && message.data["messageType"] == 'chat') {
Utils.saveStringFromPrefs("isAppOpendByChat", "true"); Utils.saveStringFromPrefs("isAppOpendByChat", "true");
Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString()); Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString());
} }
@ -134,9 +143,10 @@ AndroidNotificationChannel channel = const AndroidNotificationChannel(
Future<dynamic> backgroundMessageHandler(RemoteMessage message) async { Future<dynamic> backgroundMessageHandler(RemoteMessage message) async {
await Firebase.initializeApp(); await Firebase.initializeApp();
Utils.saveStringFromPrefs("isAppOpendByChat", "false"); if (message.data.isNotEmpty && message.data["messageType"] == 'chat') {
Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString()); Utils.saveStringFromPrefs("isAppOpendByChat", "false");
if (message.data.isNotEmpty && message.data["type"] == 'call') { Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString());
} else if (message.data.isNotEmpty && message.data["messageType"] == 'call') {
ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), data: message); ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), data: message);
} }
} }

@ -6,9 +6,15 @@ import 'package:flutter_callkit_incoming/entities/entities.dart';
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.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/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.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/main.dart';
import 'package:mohem_flutter_app/models/chat/call.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart'; import 'package:mohem_flutter_app/models/chat/get_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' as ALM;
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart';
import 'package:mohem_flutter_app/provider/chat_call_provider.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:provider/provider.dart';
class ChatVoipCall { class ChatVoipCall {
static final ChatVoipCall _instance = ChatVoipCall._internal(); static final ChatVoipCall _instance = ChatVoipCall._internal();
@ -17,58 +23,110 @@ class ChatVoipCall {
factory ChatVoipCall() => _instance; factory ChatVoipCall() => _instance;
Future<void> showCallkitIncoming({required String uuid, required RemoteMessage data}) async { late ChatProviderModel chatProvider;
late ChatCallProvider callProvider;
dynamic inCallData;
Future<void> showCallkitIncoming({required String uuid, RemoteMessage? data, bool isOnline = false, CallDataModel? incomingCallData}) async {
await ChatVoipCall().listenerEvent(); await ChatVoipCall().listenerEvent();
SingleUserChatModel callerData = SingleUserChatModel.fromJson(jsonDecode(data.data["user_chat_history_response"])); if (isOnline) {
ALM.Response autoLoginData = ALM.Response.fromJson(jsonDecode(data.data["user_token_response"])); // if (incomingCallData.chatEventId == 3) {
var values = { // await Utils.saveStringFromPrefs("isIncomingCall", "true");
"loginDetails": autoLoginData.toJson(), // await Utils.saveStringFromPrefs(
"callerDetails": callerData.toJson(), // "inComingCallData",
}; // jsonEncode([
CallKitParams params = CallKitParams( // {
id: uuid, // "loginDetails": autoLoginData.toJson(),
nameCaller: callerData.targetUserName, // "callerDetails": callerData.toJson(),
appName: 'Mohemm', // }
handle: '', // ]));
type: 0, // await FlutterCallkitIncoming.showCallkitIncoming(params);
duration: 25000, // }
textAccept: 'Accept', } else {
textDecline: 'Decline', await initProviders();
textMissedCall: 'Missed call', SingleUserChatModel callerData = SingleUserChatModel.fromJson(jsonDecode(data!.data["user_chat_history_response"]));
textCallback: 'Call back', ALM.Response autoLoginData = ALM.Response.fromJson(jsonDecode(data.data["user_token_response"]));
extra: values, CallKitParams params = CallKitParams(
android: const AndroidParams( id: uuid,
isCustomNotification: true, nameCaller: callerData.targetUserName,
isShowLogo: true, appName: 'Mohemm',
isShowCallback: false, handle: '',
isShowMissedCallNotification: true, type: 0,
ringtonePath: 'system_ringtone_default', duration: 25000,
backgroundColor: '#0955fa', textAccept: 'Accept',
backgroundUrl: 'assets/test.png', textDecline: 'Decline',
actionColor: '#4CAF50', textMissedCall: 'Missed call',
), textCallback: 'Call back',
ios: IOSParams( extra: {
iconName: 'Mohemm', "loginDetails": autoLoginData.toJson(),
handleType: '', "callerDetails": callerData.toJson(),
supportsVideo: true, },
maximumCallGroups: 2, android: const AndroidParams(
maximumCallsPerCallGroup: 1, isCustomNotification: true,
audioSessionMode: 'default', isShowLogo: false,
audioSessionActive: true, isShowCallback: false,
audioSessionPreferredSampleRate: 38000.0, isShowMissedCallNotification: true,
audioSessionPreferredIOBufferDuration: 0.005, ringtonePath: 'system_ringtone_default',
supportsDTMF: true, backgroundColor: '#0955fa',
supportsHolding: true, backgroundUrl: 'assets/test.png',
supportsGrouping: false, actionColor: '#4CAF50',
supportsUngrouping: false, ),
ringtonePath: 'system_ringtone_default', ios: IOSParams(
), iconName: 'Mohemm',
); handleType: '',
if (callerData.chatEventId == 3) { supportsVideo: true,
await Utils.saveStringFromPrefs("isIncomingCall", "true"); maximumCallGroups: 2,
await Utils.saveStringFromPrefs("inComingCallData",jsonEncode(values)); maximumCallsPerCallGroup: 1,
await FlutterCallkitIncoming.showCallkitIncoming(params); audioSessionMode: 'default',
} audioSessionActive: true,
audioSessionPreferredSampleRate: 38000.0,
audioSessionPreferredIOBufferDuration: 0.005,
supportsDTMF: true,
supportsHolding: true,
supportsGrouping: false,
supportsUngrouping: false,
ringtonePath: 'system_ringtone_default',
),
);
if (callerData.chatEventId == 3) {
await Utils.saveStringFromPrefs("isIncomingCall", "true");
// await Utils.saveStringFromPrefs(
// "inComingCallData",
// jsonEncode([
// {
// "loginDetails": autoLoginData.toJson(),
// "callerDetails": callerData.toJson(),
// }
// ]));
connection(
data: jsonEncode([
{"loginDetails": autoLoginData.toJson(), "callerDetails": callerData.toJson()}
]));
await FlutterCallkitIncoming.showCallkitIncoming(params);
}
}
}
Future<void> initProviders() async {
callProvider = Provider.of<ChatCallProvider>(AppRoutes.navigatorKey.currentContext!, listen: false);
chatProvider = Provider.of<ChatProviderModel>(AppRoutes.navigatorKey.currentContext!, listen: false);
}
void connection({required data}) async {
// inCallData = await Utils.getStringFromPrefs("inComingCallData");
dynamic callData = await jsonDecode(data);
AppState().setchatUserDetails = UserAutoLoginModel(
response: Response.fromJson(callData[0]["loginDetails"]),
errorResponses: null,
);
callProvider.startIncomingCallViaKit(inCallData: inCallData);
try {
await chatProvider.buildHubConnection(context: AppRoutes.navigatorKey.currentContext!, ccProvider: callProvider).whenComplete(() {
callProvider.init();
});
} catch (e) {
logger.w(e);
}
} }
//Function(CallEvent) callback //Function(CallEvent) callback
@ -84,17 +142,18 @@ class ChatVoipCall {
// TODO: show screen calling in Flutter // TODO: show screen calling in Flutter
break; break;
case Event.ACTION_CALL_ACCEPT: case Event.ACTION_CALL_ACCEPT:
Navigator.pushNamedAndRemoveUntil(AppRoutes.navigatorKey.currentContext!, AppRoutes.chatStartCall, (_) => false);
// Navigator.pushNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.chatStartCall);
break; break;
case Event.ACTION_CALL_DECLINE: case Event.ACTION_CALL_DECLINE:
callProvider.isIncomingCall = true;
Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("isIncomingCall", "false");
Utils.saveStringFromPrefs("inComingCallData", "null"); Utils.saveStringFromPrefs("inComingCallData", "null");
callProvider.endCall();
break; break;
case Event.ACTION_CALL_ENDED: case Event.ACTION_CALL_ENDED:
Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("isIncomingCall", "false");
Utils.saveStringFromPrefs("inComingCallData", "null"); Utils.saveStringFromPrefs("inComingCallData", "null");
// TODO: ended an incoming/outgoing call
break; break;
case Event.ACTION_CALL_TIMEOUT: case Event.ACTION_CALL_TIMEOUT:
Utils.saveStringFromPrefs("isIncomingCall", "false"); Utils.saveStringFromPrefs("isIncomingCall", "false");

@ -7,12 +7,12 @@ import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:just_audio/just_audio.dart'; import 'package:just_audio/just_audio.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/classes/voip_chat_call.dart';
import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/call.dart'; import 'package:mohem_flutter_app/models/chat/call.dart';
import 'package:mohem_flutter_app/models/chat/incomingCall.dart'; import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/models/chat/webrtc_payloads.dart'; import 'package:mohem_flutter_app/models/chat/webrtc_payloads.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.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/chat/call/start_call_screen.dart'; import 'package:mohem_flutter_app/ui/chat/call/start_call_screen.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@ -27,7 +27,6 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
final AudioPlayer player = AudioPlayer(); final AudioPlayer player = AudioPlayer();
late MediaStream localStream; late MediaStream localStream;
late CallDataModel outGoingCallData; late CallDataModel outGoingCallData;
late IncomingCallDataPayload inComingCallData;
bool isMicOff = false; bool isMicOff = false;
bool isLoudSpeaker = false; bool isLoudSpeaker = false;
bool isCamOff = false; bool isCamOff = false;
@ -36,10 +35,12 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
bool isCallStarted = false; bool isCallStarted = false;
bool isFrontCamera = true; bool isFrontCamera = true;
bool isOnIncomingCallPage = false; bool isOnIncomingCallPage = false;
late SingleUserChatModel incomingCallData;
/// WebRTC Connection Variables /// WebRTC Connection Variables
bool _offer = false; //bool _offer = false;
bool isIncomingCallLoader = true; bool isIncomingCallLoader = true;
bool isIncomingCall = false;
late BuildContext providerContext; late BuildContext providerContext;
/// Temp Variable Remove After Development /// Temp Variable Remove After Development
@ -90,7 +91,10 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
}; };
Future<void> init() async { Future<void> init() async {
creatOfferWithCon(); _pc = await creatOfferWithCon();
Future.delayed(const Duration(seconds: 2), () {
connectIncomingCall();
});
} }
Future<void> initLocalCamera({required ChatProviderModel chatProvmodel, required callData, required BuildContext context, bool isIncomingCall = false}) async { Future<void> initLocalCamera({required ChatProviderModel chatProvmodel, required callData, required BuildContext context, bool isIncomingCall = false}) async {
@ -131,19 +135,34 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
} }
Future<bool> endCall() async { Future<bool> endCall() async {
await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: outGoingCallData.callerId!, targetUserID: outGoingCallData.receiverId!, userStatus: 1); if (isIncomingCall) {
await invoke(invokeMethod: "HangUpAsync", currentUserID: outGoingCallData.callerId!, targetUserID: outGoingCallData.receiverId!, userStatus: 1); await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!, userStatus: 1);
_pc.dispose(); await invoke(invokeMethod: "HangUpAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!, userStatus: 1);
isCallStarted = false; _pc.dispose();
isVideoCall = false; isCallStarted = false;
isCamOff = false; isVideoCall = false;
isMicOff = false; isCamOff = false;
isLoudSpeaker = false; isMicOff = false;
localVideoRenderer.srcObject = null; isLoudSpeaker = false;
remoteRenderer.srcObject = null; localVideoRenderer.srcObject = null;
//player.stop(); remoteRenderer.srcObject = null;
_offer = false; isIncomingCall = false;
return true; return true;
} else {
await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: outGoingCallData.callerId!, targetUserID: outGoingCallData.receiverId!, userStatus: 1);
await invoke(invokeMethod: "HangUpAsync", currentUserID: outGoingCallData.callerId!, targetUserID: outGoingCallData.receiverId!, userStatus: 1);
_pc.dispose();
isCallStarted = false;
isVideoCall = false;
isCamOff = false;
isMicOff = false;
isLoudSpeaker = false;
localVideoRenderer.srcObject = null;
remoteRenderer.srcObject = null;
//player.stop();
// _offer = false;
return true;
}
} }
// OutGoing Listeners // OutGoing Listeners
@ -157,52 +176,71 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
} }
Future<void> onIceCandidateAsync(List<Object?>? params) async { Future<void> onIceCandidateAsync(List<Object?>? params) async {
print("--------------------- onIceCandidateAsync ---------------------------------------");
var items = params!.toList(); var items = params!.toList();
if (kDebugMode) { if (isIncomingCall) {
logger.i("res: " + items.toString()); RemoteIceCandidatePayLoad data = RemoteIceCandidatePayLoad.fromJson(jsonDecode(items.first.toString()));
} if (_pc != null) {
RemoteIceCandidatePayLoad data = RemoteIceCandidatePayLoad.fromJson(jsonDecode(items.first.toString())); await _pc.addCandidate(RTCIceCandidate(data.candidate!.candidate, data.candidate!.sdpMid, data.candidate!.sdpMLineIndex));
if (_pc != null) { }
await _pc.addCandidate(RTCIceCandidate(data.candidate!.candidate, data.candidate!.sdpMid, data.candidate!.sdpMLineIndex)); } else {
if (!isCallStarted) { if (kDebugMode) {
isCallStarted = true; logger.i("res: " + items.toString());
if (isCallStarted) { }
Navigator.push( RemoteIceCandidatePayLoad data = RemoteIceCandidatePayLoad.fromJson(jsonDecode(items.first.toString()));
providerContext, if (_pc != null) {
MaterialPageRoute( await _pc.addCandidate(RTCIceCandidate(data.candidate!.candidate, data.candidate!.sdpMid, data.candidate!.sdpMLineIndex));
builder: (BuildContext context) => StartCallPage(localRenderer: localVideoRenderer, remoteRenderer: remoteRenderer), if (!isCallStarted) {
allowSnapshotting: false, isCallStarted = true;
)).then((value) { if (isCallStarted) {
Navigator.of(providerContext).pop(); Navigator.push(
}); providerContext,
MaterialPageRoute(
builder: (BuildContext context) => StartCallPage(),
allowSnapshotting: false,
)).then((value) {
Navigator.of(providerContext).pop();
});
}
} }
} }
notifyListeners();
} }
notifyListeners();
} }
Future<void> onOfferAsync(List<Object?>? params) async { Future<void> onOfferAsync(List<Object?>? params) async {
// tempPayLoad = {"values": params!.toList()};
dynamic items = params!.toList(); dynamic items = params!.toList();
RTCSessionDescription description = await _createAnswer(); var data = jsonDecode(items.toString());
await _pc.setLocalDescription(description); if (isIncomingCall) {
var payload = {"target": items[0]["id"], "caller": outGoingCallData.callerId, "sdp": description.toMap()}; _pc.setRemoteDescription(RTCSessionDescription(data[0]["sdp"]["sdp"], data[0]["sdp"]["type"]));
invoke(invokeMethod: "AnswerOffer", currentUserID: outGoingCallData.callerId!, targetUserID: items[0]["id"], data: jsonEncode(payload)); RTCSessionDescription description = await _createAnswer();
await _pc.setLocalDescription(description);
var payload = {"target": data[0]["caller"], "caller": AppState().chatDetails!.response!.id, "sdp": description.toMap()};
invoke(invokeMethod: "AnswerOfferAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!, data: jsonEncode(payload));
}
// else {
// RTCSessionDescription description = await _createAnswer();
// await _pc.setLocalDescription(description);
// var payload = {"target": items[0]["id"], "caller": outGoingCallData.callerId, "sdp": description.toMap()};
// invoke(invokeMethod: "AnswerOffer", currentUserID: outGoingCallData.callerId!, targetUserID: items[0]["id"], data: jsonEncode(payload));
// }
notifyListeners(); notifyListeners();
} }
// Incoming Listeners // Incoming Listeners
void onAnswerOffer(List<Object?>? payload) async { void onAnswerOffer(List<Object?>? payload) async {
print("--------------------- On Answer Offer Async ---------------------------------------"); if (isIncomingCall) {
var items = payload!.toList(); // print("--------------------- On Answer Offer Async ---------------------------------------");
if (kDebugMode) { //await invoke(invokeMethod: "InvokeMobile", currentUserID: AppState().getchatUserDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!, debugData: {"On Answer Offer Async"});
logger.i("res: " + items.toString()); } else {
var items = payload!.toList();
if (kDebugMode) {
logger.i("res: " + items.toString());
}
CallSessionPayLoad data = CallSessionPayLoad.fromJson(jsonDecode(items.first.toString()));
RTCSessionDescription description = RTCSessionDescription(data.sdp!.sdp, 'answer');
_pc.setRemoteDescription(description);
} }
CallSessionPayLoad data = CallSessionPayLoad.fromJson(jsonDecode(items.first.toString()));
RTCSessionDescription description = RTCSessionDescription(data.sdp!.sdp, 'answer');
_pc.setRemoteDescription(description);
} }
void onHangUpAsync(List<Object?>? params) { void onHangUpAsync(List<Object?>? params) {
@ -217,37 +255,53 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
print("--------------------- On Incoming Call ---------------------------------------"); print("--------------------- On Incoming Call ---------------------------------------");
dynamic items = params!.toList(); dynamic items = params!.toList();
logger.d(items); logger.d(items);
if (!isOnIncomingCallPage) { // Map<String, dynamic> json = {
Map<String, dynamic> json = { // "callerID": items[0]["id"],
"callerID": items[0]["id"], // "callerName": items[0]["userName"],
"callerName": items[0]["userName"], // "callerEmail": items[0]["email"],
"callerEmail": items[0]["email"], // "callerTitle": items[0]["title"],
"callerTitle": items[0]["title"], // "callerPhone": null,
"callerPhone": null, // "receiverID": AppState().chatDetails!.response!.id,
"receiverID": AppState().chatDetails!.response!.id, // "receiverName": AppState().chatDetails!.response!.userName,
"receiverName": AppState().chatDetails!.response!.userName, // "receiverEmail": AppState().chatDetails!.response!.email,
"receiverEmail": AppState().chatDetails!.response!.email, // "receiverTitle": AppState().chatDetails!.response!.title,
"receiverTitle": AppState().chatDetails!.response!.title, // "receiverPhone": AppState().chatDetails!.response!.phone,
"receiverPhone": AppState().chatDetails!.response!.phone, // "title": AppState().chatDetails!.response!.userName!.replaceAll(".", " "),
"title": AppState().chatDetails!.response!.userName!.replaceAll(".", " "), // "callType": items[1] ? "Video" : "Audio",
"callType": items[1] ? "Video" : "Audio", // };
}; // CallDataModel callData = CallDataModel.fromJson(json);
CallDataModel callData = CallDataModel.fromJson(json); // ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), isOnline: true, incomingCallData: callData);
await Navigator.push( //
providerContext, // if (!isOnIncomingCallPage) {
MaterialPageRoute( // Map<String, dynamic> json = {
builder: (BuildContext context) => IncomingCall( // "callerID": items[0]["id"],
isVideoCall: items[1] ? true : false, // "callerName": items[0]["userName"],
outGoingCallData: callData, // "callerEmail": items[0]["email"],
), // "callerTitle": items[0]["title"],
), // "callerPhone": null,
); // "receiverID": AppState().chatDetails!.response!.id,
isOnIncomingCallPage = true; // "receiverName": AppState().chatDetails!.response!.userName,
} // "receiverEmail": AppState().chatDetails!.response!.email,
// "receiverTitle": AppState().chatDetails!.response!.title,
// "receiverPhone": AppState().chatDetails!.response!.phone,
// "title": AppState().chatDetails!.response!.userName!.replaceAll(".", " "),
// "callType": items[1] ? "Video" : "Audio",
// };
// CallDataModel callData = CallDataModel.fromJson(json);
// await Navigator.push(
// providerContext,
// MaterialPageRoute(
// builder: (BuildContext context) => IncomingCall(
// isVideoCall: items[1] ? true : false,
// outGoingCallData: callData,
// ),
// ),
// );
// isOnIncomingCallPage = true;
// }
} }
void onCallDeclinedAsync(List<Object?>? params) { void onCallDeclinedAsync(List<Object?>? params) {
print("--------------------- on Call Declined ---------------------------------------");
endCall().then((bool value) { endCall().then((bool value) {
if (value) { if (value) {
isCallEnded = true; isCallEnded = true;
@ -258,7 +312,7 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
//// Invoke Methods //// Invoke Methods
Future<void> invoke({required String invokeMethod, required int currentUserID, required int targetUserID, var data, int userStatus = 1}) async { Future<void> invoke({required String invokeMethod, required int currentUserID, required int targetUserID, var data, int userStatus = 1, var debugData}) async {
List<Object> args = []; List<Object> args = [];
// Utils.showToast(currentUserID.toString() + " -- " + targetUserID.toString() + " -- " + isVideoCall.toString()); // Utils.showToast(currentUserID.toString() + " -- " + targetUserID.toString() + " -- " + isVideoCall.toString());
if (invokeMethod == "CallUserAsync") { if (invokeMethod == "CallUserAsync") {
@ -276,8 +330,9 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
args = [currentUserID, userStatus]; args = [currentUserID, userStatus];
} else if (invokeMethod == "HangUpAsync") { } else if (invokeMethod == "HangUpAsync") {
args = [currentUserID, targetUserID]; args = [currentUserID, targetUserID];
} else if (invokeMethod == "InvokeMobile") {
args = [debugData];
} }
logger.d(args);
try { try {
await chatHubConnection.invoke("$invokeMethod", args: args); await chatHubConnection.invoke("$invokeMethod", args: args);
} catch (e) { } catch (e) {
@ -319,7 +374,9 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
}, },
'optional': [] 'optional': []
}; };
RTCPeerConnection pc = await createPeerConnection(configuration, offerSdpConstraints); RTCPeerConnection pc = await createPeerConnection(configuration, offerSdpConstraints);
logger.w(pc.connectionState);
await pc!.addStream(localStream!); await pc!.addStream(localStream!);
pc?.onConnectionState = (RTCPeerConnectionState state) {}; pc?.onConnectionState = (RTCPeerConnectionState state) {};
pc?.onAddStream = (MediaStream stream) { pc?.onAddStream = (MediaStream stream) {
@ -327,10 +384,19 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners(); notifyListeners();
}; };
pc!.onIceCandidate = (RTCIceCandidate e) async { pc!.onIceCandidate = (RTCIceCandidate e) async {
if (e.candidate != null) { if (isIncomingCall) {
var payload = {"target": outGoingCallData.callerId, "candidate": e.toMap()}; if (e.candidate != null) {
logger.i("Candidate:" + e.toMap().toString()); var payload = {"target": incomingCallData.targetUserId, "candidate": e.toMap()};
await invoke(invokeMethod: "IceCandidateAsync", currentUserID: outGoingCallData.callerId!, targetUserID: outGoingCallData.receiverId!, data: jsonEncode(payload)); logger.i("Candidate:" + e.toMap().toString());
invoke(invokeMethod: "IceCandidateAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!, data: jsonEncode(payload));
notifyListeners();
}
} else {
if (e.candidate != null) {
var payload = {"target": outGoingCallData.callerId, "candidate": e.toMap()};
logger.i("Candidate:" + e.toMap().toString());
invoke(invokeMethod: "IceCandidateAsync", currentUserID: outGoingCallData.callerId!, targetUserID: outGoingCallData.receiverId!, data: jsonEncode(payload));
}
} }
}; };
// pc!.onTrack = (RTCTrackEvent event) async { // pc!.onTrack = (RTCTrackEvent event) async {
@ -345,12 +411,21 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
// }; // };
pc!.onSignalingState = (RTCSignalingState state) { pc!.onSignalingState = (RTCSignalingState state) {
logger.i("signaling state: " + state.name); logger.i("signaling state: " + state.name);
invoke(
invokeMethod: "InvokeMobile",
currentUserID: AppState().getchatUserDetails!.response!.id!,
targetUserID: incomingCallData.targetUserId!,
debugData: {"location": "Signaling", "parms": state.name});
}; };
pc!.onIceGatheringState = (RTCIceGatheringState state) { pc!.onIceGatheringState = (RTCIceGatheringState state) {
logger.i("rtc ice gathering state: " + state.name); logger.i("rtc ice gathering state: " + state.name);
}; };
pc!.onIceConnectionState = (RTCIceConnectionState state) { pc!.onIceConnectionState = (RTCIceConnectionState state) {
logger.i("rtc ice connection state: " + state.name); // invoke(
// invokeMethod: "InvokeMobile",
// currentUserID: AppState().getchatUserDetails!.response!.id!,
// targetUserID: incomingCallData.targetUserId!,
// debugData: {"location": "onIceConnection", "parms": state.name});
}; };
pc!.onRenegotiationNeeded = () {}; pc!.onRenegotiationNeeded = () {};
return pc; return pc;
@ -376,13 +451,13 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
Future<RTCSessionDescription> _createOffer() async { Future<RTCSessionDescription> _createOffer() async {
RTCSessionDescription description = await _pc!.createOffer(); RTCSessionDescription description = await _pc!.createOffer();
_offer = true; // _offer = true;
return description; return description;
} }
Future<RTCSessionDescription> _createAnswer() async { Future<RTCSessionDescription> _createAnswer() async {
RTCSessionDescription description = await _pc!.createAnswer(); RTCSessionDescription description = await _pc!.createAnswer();
_offer = false; // _offer = false;
return description; return description;
} }
@ -421,7 +496,6 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
void switchCamera() { void switchCamera() {
isFrontCamera = !isFrontCamera; isFrontCamera = !isFrontCamera;
print("================= Camera Switch Triggered ===================");
Helper.switchCamera(localStream.getVideoTracks()[0]); Helper.switchCamera(localStream.getVideoTracks()[0]);
notifyListeners(); notifyListeners();
} }
@ -431,11 +505,22 @@ class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
localStream = await navigator.mediaDevices.getUserMedia(isVideoCall ? videoConstraints : audioConstraints); localStream = await navigator.mediaDevices.getUserMedia(isVideoCall ? videoConstraints : audioConstraints);
localVideoRenderer.srcObject = localStream; localVideoRenderer.srcObject = localStream;
await remoteRenderer.initialize(); await remoteRenderer.initialize();
_pc = await creatOfferWithCon();
} }
Future<void> startIncomingCallViaKit() async { Future<void> startIncomingCallViaKit({bool isVCall = true, required var inCallData}) async {
Utils.saveStringFromPrefs("isIncomingCall", "false");
isVideoCall = isVCall;
await startIncomingCall(); await startIncomingCall();
await invoke(invokeMethod: "answerCallAsync", currentUserID: inComingCallData.extra!.loginDetails!.id!, targetUserID: inComingCallData.extra!.callerDetails!.targetUserId!); isIncomingCall = true;
dynamic callData = await jsonDecode(inCallData);
incomingCallData = SingleUserChatModel.fromJson(callData[0]["callerDetails"]);
notifyListeners();
}
void connectIncomingCall() {
invoke(invokeMethod: "answerCallAsync", currentUserID: AppState().getchatUserDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!);
isIncomingCallLoader = false;
isVideoCall = true;
notifyListeners();
} }
} }

@ -139,15 +139,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
chatHubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); chatHubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
chatHubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); chatHubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
// Calling
// chatHubConnection.on("OnCallAcceptedAsync", callP.onCallAcceptedAsync);
// chatHubConnection.on("OnIceCandidateAsync", callP.onIceCandidateAsync);
// chatHubConnection.on("OnOfferAsync", callP.onOfferAsync);
// chatHubConnection.on("OnAnswerOffer", callP.onAnswerOffer);
// chatHubConnection.on("OnHangUpAsync", callP.onHangUpAsync);
// chatHubConnection.on("OnCallDeclinedAsync", callP.onCallDeclinedAsync);
if (kDebugMode) { if (kDebugMode) {
logger.i("All listeners registered"); logger.i("All listeners registered");
} }
@ -1478,21 +1469,4 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
return Material.TextDirection.ltr; return Material.TextDirection.ltr;
} }
void openChatByNoti(BuildContext context) async {
SingleUserChatModel nUser = SingleUserChatModel();
Utils.saveStringFromPrefs("isAppOpendByChat", "false");
if (await Utils.getStringFromPrefs("notificationData") != "null") {
nUser = SingleUserChatModel.fromJson(jsonDecode(await Utils.getStringFromPrefs("notificationData")));
Utils.saveStringFromPrefs("notificationData", "null");
Future.delayed(const Duration(seconds: 2));
for (ChatUser user in searchedChats!) {
if (user.id == nUser.targetUserId) {
Navigator.pushNamed(context, AppRoutes.chatDetailed, arguments: ChatDetailedScreenParams(user, false));
return;
}
}
}
Utils.saveStringFromPrefs("notificationData", "null");
}
} }

@ -9,6 +9,8 @@ import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.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_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart'; import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart';
import 'package:mohem_flutter_app/models/chat/incomingCall.dart'; import 'package:mohem_flutter_app/models/chat/incomingCall.dart';
import 'package:mohem_flutter_app/provider/chat_call_provider.dart'; import 'package:mohem_flutter_app/provider/chat_call_provider.dart';
@ -17,27 +19,22 @@ import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class StartCallPage extends StatefulWidget { class StartCallPage extends StatefulWidget {
RTCVideoRenderer? localRenderer;
RTCVideoRenderer? remoteRenderer;
StartCallPage({this.localRenderer, this.remoteRenderer});
@override @override
_StartCallPageState createState() => _StartCallPageState(); _StartCallPageState createState() => _StartCallPageState();
} }
class _StartCallPageState extends State<StartCallPage> { class _StartCallPageState extends State<StartCallPage> {
final dragController = DragController(); final dragController = DragController();
late ChatProviderModel cPro; late ChatProviderModel chatProvider;
late ChatCallProvider callPro; late ChatCallProvider callProvider;
var inCallData; var inCallData;
bool isIncomingCall = false;
//userChatDetails //userChatDetails
@override @override
void initState() { void initState() {
callPro = Provider.of<ChatCallProvider>(context, listen: false); // callProvider = Provider.of<ChatCallProvider>(context, listen: false);
cPro = Provider.of<ChatProviderModel>(context, listen: false); // chatProvider = Provider.of<ChatProviderModel>(context, listen: false);
// connection();
super.initState(); super.initState();
} }
@ -49,278 +46,260 @@ class _StartCallPageState extends State<StartCallPage> {
super.dispose(); super.dispose();
} }
void connection() async { // void connection() async {
isIncomingCall = (Utils.getStringFromPrefs("isIncomingCall") == "true" ? true : false); // inCallData = await Utils.getStringFromPrefs("inComingCallData");
Utils.saveStringFromPrefs("isIncomingCall", "false"); // dynamic callData = await jsonDecode(inCallData);
callPro.tempPayLoad = inCallData; // AppState().setchatUserDetails = UserAutoLoginModel(
// callPro.isIncomingCallLoader = false; // response: Response.fromJson(callData[0]["loginDetails"]),
// callPro.notifyListeners(); // errorResponses: null,
cPro.userLoginData = UserAutoLoginModel( // );
response: Response.fromJson(jsonDecode(inCallData["loginDetails"])), // callProvider.startIncomingCallViaKit(inCallData: inCallData);
errorResponses: null, // try {
); // await chatProvider.buildHubConnection(context: context, ccProvider: callProvider).whenComplete(() {
AppState().setchatUserDetails = cPro.userLoginData; // callProvider.init();
await cPro.buildHubConnection(context: context, ccProvider: callPro); // });
//callPro.inComingCallData = inCallData; // } catch (e) {
callPro.isIncomingCallLoader = false; // logger.w(e);
Future.delayed(const Duration(seconds: 2)).then((value) { // }
callPro.startIncomingCallViaKit(); //
//Utils.showToast(inCallData.extra!.loginDetails!.toRawJson(), longDuration: false); // // callProvider.afterHub();
callPro.notifyListeners(); // }
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
inCallData = ModalRoute.of(context)!.settings.arguments; return Scaffold(
if (inCallData != null) { extendBody: true,
connection(); body: Consumer2<ChatCallProvider, ChatProviderModel>(builder: (BuildContext context, ChatCallProvider provider, ChatProviderModel cpm, Widget? child) {
} return SizedBox(
return Consumer2<ChatCallProvider, ChatProviderModel>(builder: (BuildContext context, ChatCallProvider provider, ChatProviderModel cpm, Widget? child) { width: double.infinity,
return SizedBox( height: double.infinity,
width: double.infinity, child: provider.isVideoCall
height: double.infinity, ? Stack(
child: provider.isVideoCall alignment: FractionalOffset.center,
? Stack( children: <Widget>[
alignment: FractionalOffset.center, if (provider.isVideoCall)
children: <Widget>[ Positioned.fill(
if (provider.isVideoCall) child: RTCVideoView(
Positioned.fill( provider.remoteRenderer!,
child: RTCVideoView( objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
widget.remoteRenderer!, key: const Key('remote'),
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(
widget.localRenderer!,
mirror: true,
objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
), ),
), if (provider.isVideoCall)
), DraggableWidget(
if (!provider.isVideoCall) bottomMargin: 20,
Positioned.fill( topMargin: 40,
child: ClipRect( intialVisibility: true,
child: BackdropFilter( horizontalSpace: 20,
filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0), shadowBorderRadius: 50,
child: Container( initialPosition: AnchoringPosition.topLeft,
decoration: BoxDecoration( dragController: dragController,
color: MyColors.grey57Color.withOpacity( normalShadow: const BoxShadow(spreadRadius: 0.0, blurRadius: 0.0),
0.3, draggingShadow: const BoxShadow(spreadRadius: 0.0, blurRadius: 0.0),
), child: SizedBox(
height: 200,
width: 140,
child: RTCVideoView(
provider.localVideoRenderer,
mirror: true,
objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
), ),
child: Column( ),
crossAxisAlignment: CrossAxisAlignment.start, ),
mainAxisSize: MainAxisSize.max, if (!provider.isVideoCall)
children: <Widget>[ Positioned.fill(
40.height, child: ClipRect(
Row( child: BackdropFilter(
crossAxisAlignment: CrossAxisAlignment.center, filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0),
mainAxisAlignment: MainAxisAlignment.center, child: Container(
decoration: BoxDecoration(
color: MyColors.grey57Color.withOpacity(
0.3,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[ children: <Widget>[
Container( 40.height,
margin: const EdgeInsets.all(21.0), Row(
child: Container( crossAxisAlignment: CrossAxisAlignment.center,
margin: const EdgeInsets.only( mainAxisAlignment: MainAxisAlignment.center,
left: 10.0, children: <Widget>[
right: 10.0, Container(
), margin: const EdgeInsets.all(21.0),
child: Column( child: Container(
crossAxisAlignment: CrossAxisAlignment.center, margin: const EdgeInsets.only(
mainAxisSize: MainAxisSize.min, left: 10.0,
mainAxisAlignment: MainAxisAlignment.spaceAround, right: 10.0,
children: <Widget>[
SvgPicture.asset(
"assets/images/user.svg",
height: 70,
width: 70,
fit: BoxFit.cover,
),
10.height,
Text(
callPro.outGoingCallData.receiverName!,
style: const TextStyle(
fontSize: 21,
decoration: TextDecoration.none,
fontWeight: FontWeight.bold,
color: MyColors.white,
letterSpacing: -1.26,
height: 23 / 12,
),
), ),
const Text( child: Column(
"On Call", crossAxisAlignment: CrossAxisAlignment.center,
style: TextStyle( mainAxisSize: MainAxisSize.min,
fontSize: 16, mainAxisAlignment: MainAxisAlignment.spaceAround,
decoration: TextDecoration.none, children: <Widget>[
fontWeight: FontWeight.w600, SvgPicture.asset(
color: Color( "assets/images/user.svg",
0xffC6C6C6, height: 70,
width: 70,
fit: BoxFit.cover,
), ),
letterSpacing: -0.48, 10.height,
height: 23 / 24, Text(
), provider.outGoingCallData.receiverName!,
), style: const TextStyle(
const SizedBox( fontSize: 21,
height: 2, 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,
Align( child: Container(
alignment: Alignment.bottomCenter, padding: const EdgeInsets.only(
child: Container( bottom: 20,
padding: const EdgeInsets.only( left: 40,
bottom: 20, right: 40,
left: 40,
right: 40,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
// if (provider.isVideoCall)
RawMaterialButton(
constraints: const BoxConstraints(),
onPressed: () {
callPro.loudOn();
},
elevation: 2.0,
fillColor: callPro.isLoudSpeaker ? MyColors.green2DColor : Colors.grey,
padding: const EdgeInsets.all(
10.0,
),
shape: const CircleBorder(),
child: const Icon(
Icons.volume_up,
color: MyColors.white,
size: 30.0,
),
), ),
RawMaterialButton( child: Row(
constraints: const BoxConstraints(), mainAxisSize: MainAxisSize.max,
onPressed: () { mainAxisAlignment: MainAxisAlignment.spaceBetween,
provider.camOff(); children: <Widget>[
}, // if (provider.isVideoCall)
elevation: 2.0, RawMaterialButton(
fillColor: provider.isCamOff ? MyColors.green2DColor : Colors.grey, constraints: const BoxConstraints(),
padding: const EdgeInsets.all( onPressed: () {
10.0, provider.loudOn();
), },
shape: const CircleBorder(), elevation: 2.0,
child: Icon( fillColor: provider.isLoudSpeaker ? MyColors.green2DColor : Colors.grey,
provider.isCamOff ? Icons.videocam_off : Icons.videocam, padding: const EdgeInsets.all(
color: MyColors.white, 10.0,
size: 30.0, ),
), shape: const CircleBorder(),
), child: const Icon(
RawMaterialButton( Icons.volume_up,
constraints: const BoxConstraints(), color: MyColors.white,
onPressed: () { size: 30.0,
provider.switchCamera(); ),
}, ),
elevation: 2.0, RawMaterialButton(
fillColor: provider.isFrontCamera ? Colors.grey : MyColors.green2DColor, constraints: const BoxConstraints(),
padding: const EdgeInsets.all( onPressed: () {
10.0, provider.camOff();
), },
shape: const CircleBorder(), elevation: 2.0,
child: Icon( fillColor: provider.isCamOff ? MyColors.green2DColor : Colors.grey,
provider.isFrontCamera ? Icons.switch_camera_outlined : Icons.switch_camera, padding: const EdgeInsets.all(
color: MyColors.white, 10.0,
size: 30.0, ),
), shape: const CircleBorder(),
), child: Icon(
RawMaterialButton( provider.isCamOff ? Icons.videocam_off : Icons.videocam,
constraints: const BoxConstraints(), color: MyColors.white,
onPressed: () { size: 30.0,
provider.micOff(); ),
}, ),
elevation: 2.0, RawMaterialButton(
fillColor: provider.isMicOff ? MyColors.green2DColor : Colors.grey, constraints: const BoxConstraints(),
padding: const EdgeInsets.all( onPressed: () {
10.0, provider.switchCamera();
), },
shape: const CircleBorder(), elevation: 2.0,
child: Icon( fillColor: provider.isFrontCamera ? Colors.grey : MyColors.green2DColor,
provider.isMicOff ? Icons.mic_off : Icons.mic, padding: const EdgeInsets.all(
color: MyColors.white, 10.0,
size: 30.0, ),
), shape: const CircleBorder(),
), child: Icon(
RawMaterialButton( provider.isFrontCamera ? Icons.switch_camera_outlined : Icons.switch_camera,
constraints: const BoxConstraints(), color: MyColors.white,
onPressed: () { size: 30.0,
provider.endCall().then((value) { ),
if (value) { ),
Navigator.of(context).pop(); RawMaterialButton(
} constraints: const BoxConstraints(),
}); onPressed: () {
}, provider.micOff();
elevation: 2.0, },
fillColor: MyColors.redA3Color, elevation: 2.0,
padding: const EdgeInsets.all( fillColor: provider.isMicOff ? MyColors.green2DColor : Colors.grey,
10.0, padding: const EdgeInsets.all(
), 10.0,
shape: const CircleBorder(), ),
child: const Icon( shape: const CircleBorder(),
Icons.call_end, child: Icon(
color: MyColors.white, provider.isMicOff ? Icons.mic_off : Icons.mic,
size: 30.0, 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,
),
),
],
), ),
], ),
), ),
), ],
), )
], : const SizedBox(
)
: provider.isIncomingCallLoader
? SizedBox(
width: double.infinity, width: double.infinity,
height: 500, height: 500,
child: Center( child: Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
), ),
) ));
: ListView( }),
padding: EdgeInsets.fromLTRB(20,40,20,20), );
children: [
Consumer<ChatCallProvider>(
builder: (BuildContext cxt, ChatCallProvider data, Widget? child) {
return Text(
data.tempPayLoad.toString(),style: TextStyle(fontSize: 12, color: Colors.white, decoration: TextDecoration.none,),
);
},
),
],
),
);
});
} }
} }

@ -101,7 +101,7 @@ class _LoginScreenState extends State<LoginScreen> {
Future<void> checkFirebaseToken() async { Future<void> checkFirebaseToken() async {
if (await Utils.getStringFromPrefs("isIncomingCall") == "true") { if (await Utils.getStringFromPrefs("isIncomingCall") == "true") {
Utils.hideLoading(context); Utils.hideLoading(context);
Navigator.pushNamed(context, AppRoutes.chatStartCall, arguments: await Utils.getStringFromPrefs("inComingCallData")); Navigator.pushNamed(context, AppRoutes.chatStartCall);
} else { } else {
try { try {
Utils.showLoading(context); Utils.showLoading(context);

Loading…
Cancel
Save