import ' dart:async ' ;
import ' dart:convert ' ;
import ' dart:io ' ;
import ' package:diplomaticquarterapp/locator.dart ' ;
import ' package:diplomaticquarterapp/main.dart ' ;
import ' package:diplomaticquarterapp/uitl/navigation_service.dart ' ;
import ' package:diplomaticquarterapp/uitl/utils.dart ' ;
import ' package:diplomaticquarterapp/voipcall/call/chat_incoming_call_screen.dart ' ;
import ' package:diplomaticquarterapp/voipcall/model/call.dart ' ;
import ' package:diplomaticquarterapp/voipcall/model/get_single_user_chat_call.dart ' ;
import ' package:diplomaticquarterapp/voipcall/model/webrtc_payloads.dart ' ;
import ' package:flutter/foundation.dart ' ;
import ' package:flutter/material.dart ' ;
import ' package:flutter_webrtc/flutter_webrtc.dart ' ;
import ' package:http/http.dart ' ;
import ' package:just_audio/just_audio.dart ' ;
import ' package:logging/logging.dart ' ;
import ' package:signalr_netcore/signalr_client.dart ' ;
class ChatCallProvider with ChangeNotifier , DiagnosticableTreeMixin {
///////////////////// Web RTC Video Calling //////////////////////
// Video Call
HubConnection ? chatHubConnection ;
RTCPeerConnection ? _pc ;
//late ChatProviderModel chatProvModel;
RTCVideoRenderer ? localVideoRenderer ;
RTCVideoRenderer ? remoteRenderer ;
final AudioPlayer player = AudioPlayer ( ) ;
MediaStream ? _localStream ;
CallDataModel ? outGoingCallData ;
bool isMicOff = false ;
bool isLoudSpeaker = false ;
bool isCamOff = false ;
bool isCallEnded = false ;
// This need to Be Changed to dynamic
bool isVideoCall = true ;
bool isAudioCall = false ;
bool isCallStarted = false ;
bool isFrontCamera = true ;
SingleUserChatModel ? incomingCallData ;
/// WebRTC Connection Variables
bool isIncomingCallLoader = true ;
bool isIncomingCall = false ;
bool isOutGoingCall = false ;
bool isUserOnline = false ;
List < MediaDeviceInfo > devices = [ ] ;
//
// // If you want only to log out the message for the higer level hub protocol:
// final hubProtLogger = Logger("SignalR - hub");
// final transportProtLogger = Logger("SignalR - transport");
// late Logger _logger;
// late StreamSubscription<LogRecord> _logMessagesSub;
//
// void _handleLogMessage(LogRecord msg) {
// print(msg.message);
// }
//
// Future<void> buildHubConnection() async {
// try {
// Logger.root.level = Level.ALL;
// _logMessagesSub = Logger.root.onRecord.listen(_handleLogMessage);
// _logger = Logger("ChatPageViewModel");
//
// // chatHubConnection = await getHubConnection();
// String to = "ytvF4zQfUrJHOUfpE7UE1Q";
// HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true, logger: transportProtLogger);
// // hub = HubConnectionBuilder()
// // .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Desktop&access_token=${AppState().chatDetails!.response!.token}", options: httpOp)
// // .withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
// var urlWithParams = "https://ms.hmg.com/livecare/liveCareHub?UserID=4767770&ProjectId=12&IsAdmin=false&To=$to";
// print("ChatHubURL:::: " + urlWithParams);
// chatHubConnection = await HubConnectionBuilder().withUrl(urlWithParams, options: httpOp).build();
// await chatHubConnection!.start();
// print(chatHubConnection!.state);
// chatHubConnection!.onclose(({error}) {
// print("Connection Closed");
// });
// // if (chatHubConnection!.state == HubConnectionState.Connected) {
// // print("Success Chat Con ID::: " + chatHubConnection!.connectionId.toString());
// // if (kDebugMode) {
// // print("Hub Conn: Startedddddddd");
// // }
// // //registerCallListners();
// // }
// } catch (e) {
// print(e.toString());
// Utils.showErrorToast(e.toString());
// }
// }
//{"id":341682,"userName":"Aamir.Muhammad","email":"Aamir.Muhammad@cloudsolutions.com.sa","phone":null,"title":"Aamir Saleem Ahmad Dost Muhammad","token":"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIzNDE2ODIiLCJlbWFpbCI6IkFhbWlyLk11aGFtbWFkQGNsb3Vkc29sdXRpb25zLmNvbS5zYSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvdXNlcmRhdGEiOiJBYW1pci5NdWhhbW1hZCIsIm5iZiI6MTcwNzIwNTAyMywiZXhwIjoxNzA3MjkxNDIzLCJpYXQiOjE3MDcyMDUwMjN9.Zz2bcsMwiLAAWGZh2E_p5Qs6ItMt0JHhDFI_0DLdggCQtt6HHcT4n8nvqMZx-uYr3jLwqhA_IAjTuaCeSE15sw","isDomainUser":true,"isActiveCode":false,"encryptedUserId":"nn7RkYzbnQc=","encryptedUserName":"/QruOyp4QMcmNXKZlljUgg=="}
// Future<HubConnection> getHubConnection() async {
// AppState().chatDetails = getUserToken.UserAutoLoginModel(
// response: getUserToken.Response.fromJson({
// "id": 341682,
// "userName": "Aamir.Muhammad",
// "email": "Aamir.Muhammad@cloudsolutions.com.sa",
// "phone": null,
// "title": "Aamir Saleem Ahmad Dost Muhammad",
// "token":
// "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIzNDE2ODIiLCJlbWFpbCI6IkFhbWlyLk11aGFtbWFkQGNsb3Vkc29sdXRpb25zLmNvbS5zYSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvdXNlcmRhdGEiOiJBYW1pci5NdWhhbW1hZCIsIm5iZiI6MTcwODI1NjI5NywiZXhwIjoxNzA4MzQyNjk3LCJpYXQiOjE3MDgyNTYyOTd9.Y-QDVbSbPzcMVkHyIT06WgM0EsKH183hASZrIsXGkFOR_XZcqCJS-CrgdN0nOtxCWV6wd01dgfhMTNTZhybwiQ",
// "isDomainUser": true,
// "isActiveCode": false,
// "encryptedUserId": "nn7RkYzbnQc=",
// "encryptedUserName": "/QruOyp4QMcmNXKZlljUgg=="
// }),
// );
// String to = "dfK3ZqFD-BTlJLnuf1F5Cw";
// HubConnection hub;
// HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true);
// // hub = HubConnectionBuilder()
// // .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Desktop&access_token=${AppState().chatDetails!.response!.token}", options: httpOp)
// // .withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
// var urlWithParams = "https://ms.hmg.com/livecare/liveCareHub?UserID=4767770&ProjectId=15&IsAdmin=false&To=$to";
// print("ChatHubURL:::: " + urlWithParams);
// hub = await HubConnectionBuilder().withUrl(urlWithParams, options: httpOp).withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
// return hub;
// }
// Future<CallDataModel> makeCall({required String callType}) async {
// Map<String, dynamic> json = {
// "callerID": AppState().chatDetails!.response!.id,
// "callerName": AppState().chatDetails!.response!.userName,
// "callerEmail": AppState().chatDetails!.response!.email,
// "callerTitle": AppState().chatDetails!.response!.title,
// "callerPhone": AppState().chatDetails!.response!.phone,
// "receiverID": 266642,
// "receiverName": "Muhammad Alam",
// "receiverEmail": "Muhamad.Alam@cloudsolutions.com.sa",
// "receiverTitle": "Muhammad Alam",
// "receiverPhone": "123456789",
// "title": "Muhammad Alam",
// "callType": callType == "VIDEO" ? "Video" : "Audio",
// };
// CallDataModel res = CallDataModel.fromJson(json);
// return res;
// }
// void registerCallListners() {
// if (kDebugMode) {
// print("=================== Call Listeners Registered =======================");
// }
// chatHubConnection!.on("OnCallAcceptedAsync", onCallAcceptedAsync);
// chatHubConnection!.on("OnIceCandidateAsync", onIceCandidateAsync);
// chatHubConnection!.on("OnOfferAsync", onOfferAsync);
// chatHubConnection!.on("OnAnswerOffer", onAnswerOffer);
// chatHubConnection!.on("OnHangUpAsync", onHangUpAsync);
// // chatHubConnection!.on("OnCallDeclinedAsync", onCallDeclinedAsync);
// // chatHubConnection!.on("OnIncomingCallAsync", OnIncomingCallAsync);
// }
// Audio Constraints
Map < String , Object > audioConstraints = {
" sampleRate " : 8000 ,
" sampleSize " : 16 ,
" channelCount " : 2 ,
" echoCancellation " : true ,
" audio " : true ,
} ;
// Future<void> init() async {
// _pc = await creatOfferWithCon();
// Future.delayed(const Duration(seconds: 2), () {
// connectIncomingCall();
// });
// }
///////////////////////////////////////////////OutGoing Call////////////////////////////////////////////////////
//
// Future<void> initLocalCamera({callData, bool isIncomingCall = false}) async {
// isCallEnded = false;
// outGoingCallData = callData;
// await initStreams();
// await startCall();
// _pc = await creatOfferWithCon();
// connectOutgoing();
// notifyListeners();
// }
//
// void connectOutgoing() {
// isOutGoingCall = true;
// // notifyListeners();
// }
//
// Future<void> startCall() async {
// // chatProvModel.isTextMsg = true;
// // chatProvModel.isAttachmentMsg = false;
// // chatProvModel.isVoiceMsg = false;
// // chatProvModel.isReplyMsg = false;
// // chatProvModel.isCall = true;
// // chatProvModel.message.text = "Start $callType call ${outGoingCallData.receiverName.toString().replaceAll(".", " ")}";
// // chatProvModel.sendChatMessage(
// // context,
// // targetUserId: outGoingCallData.receiverId,
// // userStatus: 1,
// // userEmail: outGoingCallData.receiverEmail,
// // targetUserName: outGoingCallData.receiverName,
// // );
// await invoke(
// invokeMethod: "CallUserAsync",
// currentUserID: outGoingCallData!.callerId!,
// targetUserID: outGoingCallData!.receiverId!,
// );
// await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: outGoingCallData!.callerId!, targetUserID: outGoingCallData!.receiverId!, userStatus: 4);
// }
// // OutGoing Listeners
// void onCallAcceptedAsync(List<Object?>? params) async {
// dynamic items = params!.toList();
// RTCSessionDescription description = await _createOffer();
// await _pc!.setLocalDescription(description);
// dynamic payload = {"target": items[0]["id"], "caller": outGoingCallData!.callerId, "sdp": description.toMap()};
// invoke(invokeMethod: "OfferAsync", currentUserID: outGoingCallData!.callerId!, targetUserID: items[0]["id"], data: jsonEncode(payload));
// }
//
// Future<void> onIceCandidateAsync(List<Object?>? params) async {
// dynamic items = params!.toList();
// if (isIncomingCall) {
// RemoteIceCandidatePayLoad data = RemoteIceCandidatePayLoad.fromJson(jsonDecode(items.first.toString()));
// if (_pc != null) {
// await _pc!.addCandidate(RTCIceCandidate(data.candidate!.candidate, data.candidate!.sdpMid, data.candidate!.sdpMLineIndex));
// }
// } else {
// if (kDebugMode) {
// print("res: " + items.toString());
// }
// RemoteIceCandidatePayLoad data = RemoteIceCandidatePayLoad.fromJson(jsonDecode(items.first.toString()));
// if (_pc != null) {
// await _pc!.addCandidate(RTCIceCandidate(data.candidate!.candidate, data.candidate!.sdpMid, data.candidate!.sdpMLineIndex));
// if (!isCallStarted) {
// isCallStarted = true;
// notifyListeners();
// if (isCallStarted) {
// isIncomingCallLoader = false;
// isOutGoingCall = true;
// if (Platform.isIOS) {
// Future.delayed(Duration(seconds: 2), () {
// Navigator.pushReplacement(
// locator<NavigationService>().navigatorKey.currentContext!,
// MaterialPageRoute(
// builder: (BuildContext context) => StartCallPage(),
// ));
// });
// } else {
// Navigator.pushReplacement(
// locator<NavigationService>().navigatorKey.currentContext!,
// MaterialPageRoute(
// builder: (BuildContext context) => StartCallPage(),
// ));
// }
// }
// }
// }
// notifyListeners();
// }
// }
//
// Future<void> onOfferAsync(List<Object?>? params) async {
// dynamic items = params!.toList();
// var data = jsonDecode(items.toString());
// if (isIncomingCall) {
// _pc!.setRemoteDescription(RTCSessionDescription(data[0]["sdp"]["sdp"], data[0]["sdp"]["type"]));
// RTCSessionDescription description = await _createAnswer();
// await _pc!.setLocalDescription(description);
// dynamic 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();
// }
//////////////////////////// OutGoing Call End ///////////////////////////////////////
// Future<bool> endCall({bool? isUserOnline}) async {
// if (isIncomingCall) {
// print("-----------------------Endeddddd By Me---------------------------");
// if (chatHubConnection!.state == HubConnectionState.Connected) {
// await invoke(invokeMethod: "HangUpAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData!.targetUserId!, userStatus: 0);
// await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData!.targetUserId!, userStatus: 1);
// }
// isCallStarted = false;
// isVideoCall = false;
// isCamOff = false;
// isMicOff = false;
// isLoudSpeaker = false;
// isIncomingCall = false;
// isOutGoingCall = false;
// isAudioCall = false;
//
// if (isCallConnected) {
// if (_pc!.connectionState == RTCPeerConnectionState.RTCPeerConnectionStateConnected) {
// if (kDebugMode) {
// print("------------------ PC Stopped ----------------------------");
// }
// _pc!.close();
// _pc!.dispose();
// }
// }
// if (remoteRenderer != null) {
// remoteRenderer!.dispose();
// remoteRenderer = null;
// }
// if (localVideoRenderer != null) {
// localVideoRenderer!.dispose();
// localVideoRenderer = null;
// }
//
// if (_localStream != null) {
// _localStream!.dispose();
// _localStream = null;
// }
// if (chatHubConnection != null && !isUserOnline!) {
// chatHubConnection!.stop();
// }
// 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: 1);
// } else if (isIncomingCall) {
// await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData!.targetUserId!, userStatus: 1);
// }
// isCallStarted = false;
// isVideoCall = false;
// isCamOff = false;
// isMicOff = false;
// isLoudSpeaker = false;
// if (isCallConnected) {
// if (_pc!.connectionState == RTCPeerConnectionState.RTCPeerConnectionStateConnected) {
// _pc!.close();
// _pc!.dispose();
// }
// }
// if (remoteRenderer != null) {
// remoteRenderer!.dispose();
// remoteRenderer = null;
// }
// if (localVideoRenderer != null) {
// localVideoRenderer!.dispose();
// localVideoRenderer = null;
// }
//
// if (_localStream != null) {
// _localStream!.dispose();
// _localStream = null;
// }
// isOutGoingCall = false;
// isIncomingCall = false;
// isAudioCall = false;
// return true;
// }
// }
// Incoming Listeners
// void onAnswerOffer(List<Object?>? payload) async {
// // if (isIncomingCall) {
// // // print("--------------------- On Answer Offer Async ---------------------------------------");
// // //await invoke(invokeMethod: "InvokeMobile", currentUserID: AppState().getchatUserDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!, debugData: {"On Answer Offer Async"});
// // } else {
// var items = payload!.toList();
// if (kDebugMode) {
// print("res: " + items.toString());
// }
// CallSessionPayLoad data = CallSessionPayLoad.fromJson(jsonDecode(items.first.toString()));
// RTCSessionDescription description = RTCSessionDescription(data.sdp!.sdp, 'answer');
// _pc!.setRemoteDescription(description);
// // }
// }
// void onHangUpAsync(List<Object?>? params) {
// print("--------------------- onHangUp ASYNC ---------------------------------");
//
// dynamic items = params!.toList();
// // if (kDebugMode) {
// // logger.i("res: " + items.toString());
// // }
// if (items[0]["id"] != AppState().chatDetails!.response!.id!) {
// if (kDebugMode) {
// print("Call Ended By Other User");
// }
// if (isIncomingCall) {
// endCall(isUserOnline: isUserOnline).then((bool value) {
// if (isCallConnected && isUserOnline) {
// isCallConnected = false;
// if (!AppState().isLogged) {
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).pop();
// } else {
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).popUntil(ModalRoute.withName(HOME));
// }
// } else {
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).pop();
// }
// });
// } else {
// if (isOutGoingCall) {
// endCall(isUserOnline: isUserOnline).then((bool value) {
// if (isCallConnected && isUserOnline) {
// isCallConnected = false;
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).popUntil(ModalRoute.withName(HOME));
// } else {
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).pop();
// }
// });
// }
// }
// } else {
// if (kDebugMode) {
// print("Call Ended By Me");
// }
// if (isOutGoingCall) {
// if (isCallConnected && isUserOnline) {
// isCallConnected = false;
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).popUntil(ModalRoute.withName(HOME));
// } else {
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).pop();
// }
// }
// }
// // endCall(isUserOnline: isUserOnline).then((bool value) {
// // if (isCallConnected && isUserOnline) {
// // Navigator.of(AppRoutes.navigatorKey.currentContext!).popUntil(ModalRoute.withName(AppRoutes.chatDetailed));
// // isCallConnected = false;
// // }
// // if (items[0]["id"] != AppState().chatDetails!!.response!.id && !AppState().isBackgroundCall) {
// // if (kDebugMode) {
// // print("Popped Due to Another User");
// // }
// // if (AppState().isBackgroundCall) {
// // Navigator.of(AppRoutes.navigatorKey.currentContext!).pop();
// // // Navigator.of(AppRoutes.navigatorKey.currentContext!).popUntil(ModalRoute.withName(AppRoutes.login));
// // } else {
// // Navigator.of(AppRoutes.navigatorKey.currentContext!).popUntil(ModalRoute.withName(AppRoutes.chat));
// // }
// // }
// // if (AppState().isBackgroundCall) {
// // Navigator.of(AppRoutes.navigatorKey.currentContext!).pop();
// // }
// //
// notifyListeners();
// isCallEnded = true;
// // });
// }
// Future<void> OnIncomingCallAsync(List<Object?>? params) async {
// print("--------------------- On Incoming Call ---------------------------------------");
// dynamic items = params!.toList();
// logger.d(items);
// // Map<String, dynamic> json = {
// // "callerID": items[0]["id"],
// // "callerName": items[0]["userName"],
// // "callerEmail": items[0]["email"],
// // "callerTitle": items[0]["title"],
// // "callerPhone": null,
// // "receiverID": AppState().chatDetails!!.response!.id,
// // "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);
// // ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), isOnline: true, incomingCallData: callData);
// //
// // if (!isOnIncomingCallPage) {
// // Map<String, dynamic> json = {
// // "callerID": items[0]["id"],
// // "callerName": items[0]["userName"],
// // "callerEmail": items[0]["email"],
// // "callerTitle": items[0]["title"],
// // "callerPhone": null,
// // "receiverID": AppState().chatDetails!!.response!.id,
// // "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 ) {
print ( " ================= On Declained ======================== " ) ;
print ( params ) ;
// endCall().then((bool value) {
// if (value) {
// isCallEnded = true;
// notifyListeners();
// }
// });
// if (params != null) {
// endCall(isUserOnline: isUserOnline).then((bool value) {
// if (isCallConnected) {
// // Navigator.of(AppRoutes.navigatorKey.currentContext!).pop();
// isCallConnected = false;
// }
// isCallEnded = true;
// });
// }
}
//// Invoke Methods
// Future<void> invoke({required String invokeMethod, required int currentUserID, required int targetUserID, var data, int userStatus = 1, var debugData}) async {
// List<Object> args = [];
// if (invokeMethod == "CallUserAsync") {
// args = [currentUserID, targetUserID, isVideoCall];
// } else if (invokeMethod == "answerCallAsync") {
// args = [currentUserID, targetUserID];
// } else if (invokeMethod == "IceCandidateAsync") {
// args = [targetUserID, data];
// } else if (invokeMethod == "OfferAsync") {
// args = [targetUserID, data];
// } else if (invokeMethod == "AnswerOfferAsync") {
// args = [targetUserID, data];
// // json In Data
// } else if (invokeMethod == "UpdateUserStatusAsync") {
// args = [currentUserID, userStatus];
// } else if (invokeMethod == "HangUpAsync") {
// args = [currentUserID, targetUserID];
// } else if (invokeMethod == "InvokeMobile") {
// args = [debugData];
// }
// try {
// await chatHubConnection!.invoke("$invokeMethod", args: args);
// } catch (e) {
// print(e);
// }
// }
void stopListeners ( ) async {
chatHubConnection ! . off ( ' OnCallDeclinedAsync ' ) ;
chatHubConnection ! . off ( ' OnCallAcceptedAsync ' ) ;
chatHubConnection ! . off ( ' OnIceCandidateAsync ' ) ;
chatHubConnection ! . off ( ' OnAnswerOffer ' ) ;
}
void playRingtone ( ) async {
player . stop ( ) ;
await player . setVolume ( 1.0 ) ;
String audioAsset = " " ;
if ( Platform . isAndroid ) {
audioAsset = " assets/audio/ring_60Sec.mp3 " ;
} else {
audioAsset = " assets/audio/ring_30Sec.caf " ;
}
try {
await player . setAsset ( audioAsset ) ;
await player . load ( ) ;
player . play ( ) ;
} catch ( e ) {
print ( " Error: $ e " ) ;
}
}
//////////////////// Web RTC Offers & Connections ////////////////////////
// Future<RTCPeerConnection> creatOfferWithCon() async {
// Map<String, dynamic> configuration = {
// "sdpSemantics": "plan-b",
// 'iceServers': [
// {
// 'urls': 'stun:15.185.116.59:3478',
// },
// {
// 'urls': 'turn:15.185.116.59:3479',
// 'username': 'admin',
// 'credential': 'admin',
// },
// ]
// };
// Map<String, dynamic> offerSdpConstraints = {
// 'mandatory': {
// 'OfferToReceiveAudio': true,
// 'OfferToReceiveVideo': true,
// },
// 'optional': []
// };
// RTCPeerConnection pc = await createPeerConnection(configuration, offerSdpConstraints);
// // await pc.addStream(_localStream!);
// //Changed By Aamir
// _localStream?.getTracks().forEach((track) {
// pc.addTrack(track, _localStream!);
// });
// pc.onConnectionState = (RTCPeerConnectionState state) {};
// pc.onAddStream = (MediaStream stream) {
// remoteRenderer!.srcObject = stream;
// notifyListeners();
// };
// pc.onIceCandidate = (RTCIceCandidate e) async {
// if (isIncomingCall) {
// if (e.candidate != null) {
// var payload = {"target": incomingCallData!.targetUserId, "candidate": e.toMap()};
// 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()};
// invoke(invokeMethod: "IceCandidateAsync", currentUserID: outGoingCallData!.callerId!, targetUserID: outGoingCallData!.receiverId!, data: jsonEncode(payload));
// }
// }
// };
// // pc!.onTrack = (RTCTrackEvent event) async {
// //
// // String streamId = const Uuid().toString();
// // MediaStream remoteStream = await createLocalMediaStream(streamId);
// // event.streams[0].getTracks().forEach((MediaStreamTrack element) {
// // logger.i("Stream Track: " + element.id.toString());
// // // remoteRenderer.srcObject = element;
// // remoteStream.addTrack(element);
// // });
// // };
// pc.onSignalingState = (RTCSignalingState state) {
// print("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) {
// print("rtc ice gathering state: " + state.name);
// };
// pc.onIceConnectionState = (RTCIceConnectionState state) {
// if (RTCIceConnectionState.RTCIceConnectionStateFailed == state ||
// RTCIceConnectionState.RTCIceConnectionStateDisconnected == state ||
// RTCIceConnectionState.RTCIceConnectionStateClosed == state) {
// print("Ice Connection State:" + state.name);
//
// // endCall().then((value) {
// // notifyListeners();
// // });
// }
// };
// // pc!.onRenegotiationNeeded = _onRenegotiate;
// return pc;
// }
// void _onRenegotiate() async {
// try {
// print('onRenegotiationNeeded start');
// // makingOffer = true;
// await _pc.setLocalDescription(await _pc.createOffer(videoConstraints));
// print('onRenegotiationNeeded state after setLocalDescription: ' + _pc.signalingState.toString());
// // send offer via callManager
// var localDesc = await _pc.getLocalDescription();
// // callManager.sendCallMessage(MsgType.rtc_offer, RtcOfferAnswer(localDesc.sdp, localDesc.type));
// print('onRenegotiationNeeded; offer sent');
// } catch (e) {
// print("onRenegotiationNeeded error: " + e.toString());
// } finally {
// // makingOffer = false;
// print('onRenegotiationNeeded done');
// }
// }
// Future<RTCSessionDescription> _createOffer() async {
// RTCSessionDescription description = await _pc!.createOffer();
// // _offer = true;
// return description;
// }
//
// Future<RTCSessionDescription> _createAnswer() async {
// RTCSessionDescription description = await _pc!.createAnswer();
// // _offer = false;
// return description;
// }
//////////////////// Web RTC End Offers ////////////////////
//////////////////// CallPage Buttons //////////////////////
void micOff ( ) {
isMicOff = ! isMicOff ;
_localStream ! . getAudioTracks ( ) . forEach ( ( track ) {
track . enabled = ! track . enabled ;
} ) ;
notifyListeners ( ) ;
}
void camOff ( ) {
isCamOff = ! isCamOff ;
_localStream ! . getVideoTracks ( ) . forEach ( ( track ) {
track . enabled = ! track . enabled ;
} ) ;
// if (isCamOff) {
// isVideoCall = false;
// } else {
// isVideoCall = true;
// }
notifyListeners ( ) ;
}
void loudOn ( ) {
isLoudSpeaker = ! isLoudSpeaker ;
remoteRenderer ! . srcObject ? . getAudioTracks ( ) . forEach ( ( track ) {
if ( isLoudSpeaker ) {
track . enableSpeakerphone ( true ) ;
} else {
track . enableSpeakerphone ( false ) ;
}
} ) ;
notifyListeners ( ) ;
}
void switchCamera ( ) {
isFrontCamera = ! isFrontCamera ;
Helper . switchCamera ( _localStream ! . getVideoTracks ( ) [ 0 ] ) ;
notifyListeners ( ) ;
}
///////////////// Incoming Call ///////////////////////////////
Future < void > initStreams ( ) async {
List < MediaDeviceInfo > devices = await navigator . mediaDevices . enumerateDevices ( ) ;
remoteRenderer = RTCVideoRenderer ( ) ;
localVideoRenderer ? ? = RTCVideoRenderer ( ) ;
await localVideoRenderer ! . initialize ( ) ;
try {
_localStream = await navigator . mediaDevices . getUserMedia ( {
' audio ' : true ,
' video ' : {
' mandatory ' : {
' minWidth ' : ' 640 ' , // Provide your own width, height and frame rate here
' minHeight ' : ' 480 ' ,
' minFrameRate ' : ' 25 ' ,
} ,
' facingMode ' : ' user ' ,
' optional ' : [ ] ,
" audio " : true ,
}
} ) ;
_localStream ! . getAudioTracks ( ) . first . enableSpeakerphone ( true ) ;
localVideoRenderer ! . srcObject = _localStream ;
localVideoRenderer ! . value = ( const RTCVideoValue (
width: 200 ,
height: 200 ,
renderVideo: true ,
) ) ;
print ( " Working localStream " ) ;
} catch ( e ) {
print ( " Failed to get user media: $ e " ) ;
}
await remoteRenderer ! . initialize ( ) ;
notifyListeners ( ) ;
}
// Future<void> startIncomingCallViaKit({bool isVCall = true, var inCallData}) async {
// AppSharedPrefs().setStringFromPrefs("isIncomingCall", "false");
// if (isVCall) {
// isVideoCall = isVCall;
// } else {
// isAudioCall = true;
// }
// await initStreams();
// isIncomingCall = true;
// 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();
// }
// void startRecording() async {
// print("=-=-=-=-=-=-= Call Recoding Started -=-=-=-=-=-=-=-=-==-=");
// if (_localStream == null) throw Exception('Stream is not initialized');
// if (Platform.isIOS) {
// print('Recording is not available on iOS');
// return;
// }
// Directory appDirectory = await getApplicationDocumentsDirectory();
// String dirPath = '${appDirectory.path}/webrtc_sample';
// if (!await Directory(dirPath).exists()) {
// await Directory(dirPath).create();
// await File('$dirPath/.nomedia').create();
// }
// if (appDirectory == null) throw Exception('Can\'t find storagePath');
// String filePath = dirPath + '/mobile.mp4';
// mobileRecoder = MediaRecorder();
// notifyListeners();
// MediaStreamTrack videoTrack = _localStream!.getVideoTracks().firstWhere((track) => track.kind == 'video');
// await mobileRecoder!.start(filePath, videoTrack: videoTrack);
//
// Future.delayed(Duration(minutes: 1), () {
// stopRecording();
// });
// }
//
// void stopRecording() async {
// print("=-=-=-=-=-=-= Call Recoding Stopped -=-=-=-=-=-=-=-=-==-=");
// await mobileRecoder!.stop();
// mobileRecoder = null;
// notifyListeners();
// }
// WebRtc
final transportProtLogger = Logger ( " SignalR - transport " ) ;
late Logger _logger ;
RTCPeerConnection ? pCon ;
String ? _doctorID ;
String ? _patientID ;
String ? get doctorID = > _doctorID ;
set doctorID ( String ? value ) {
_doctorID = value ;
}
String ? get patientID = > _patientID ;
set patientID ( String ? value ) {
_patientID = value ;
}
void _httpClientCreateCallback ( Client httpClient ) {
HttpOverrides . global = HttpOverrideCertificateVerificationInDev ( ) ;
}
Future < void > buildHubConnection ( ) async {
_logger = Logger ( " ChatPageViewModel " ) ;
final logger = _logger ;
if ( chatHubConnection ! = null ) {
chatHubConnection ! . stop ( ) ;
chatHubConnection = null ;
}
if ( doctorID ! = null ) {
try {
final httpConnectionOptions =
new HttpConnectionOptions ( httpClient: WebSupportingHttpClient ( logger , httpClientCreateCallback: _httpClientCreateCallback ) , logger: logger , logMessageContent: true ) ;
var urlWithParams = " https://ms.hmg.com/livecare/liveCareHub?UserID=4767770&ProjectId=15&IsAdmin=false&To= $ doctorID " ;
chatHubConnection =
await HubConnectionBuilder ( ) . withUrl ( urlWithParams , options: httpConnectionOptions ) . withAutomaticReconnect ( retryDelays: [ 2000 , 5000 , 10000 , 20000 ] ) . configureLogging ( logger ) . build ( ) ;
chatHubConnection ! . onclose ( ( { error } ) {
print ( " Connection Closed " ) ;
Utils . showErrorToast ( error . toString ( ) ) ;
} ) ;
register ( ) ;
if ( chatHubConnection ! . state = = HubConnectionState . Disconnected ) {
await chatHubConnection ! . start ( ) ;
print ( chatHubConnection ! . state ) ;
print ( " Success Chat Con ID::: " + chatHubConnection ! . connectionId . toString ( ) ) ;
}
if ( chatHubConnection ! . state = = HubConnectionState . Connected ) {
if ( chatHubConnection ! = null ) {
print ( chatHubConnection ! . connectionId ) ;
try {
chatHubConnection ! . invoke ( " Call_Accept " , args: [
{ " UserID " : 4767770 }
] ) ;
// .onError((error, stackTrace) {
// Utils.showErrorToast(error.toString());
// });
} catch ( e ) {
print ( e ) ;
}
}
}
} catch ( e ) {
print ( e . toString ( ) ) ;
Utils . showErrorToast ( e . toString ( ) ) ;
await buildHubConnection ( ) ;
}
} else {
Utils . showErrorToast ( " Doctor ID is not correct " ) ;
}
}
void register ( ) async {
chatHubConnection ! . on ( " pre-offer " , handlePreOffer ) ;
chatHubConnection ! . on ( " OnOffer " , handleOnOffer ) ;
chatHubConnection ! . on ( " IceCandidate " , handleIceCandidate ) ;
// New Events
chatHubConnection ! . on ( " Call_Decline " , handleCallDecline ) ;
chatHubConnection ! . on ( " Call_NoAnswer " , handleNoAnswerCall ) ;
chatHubConnection ! . on ( " CallCompleted " , handleCallComplete ) ;
}
handlePreOffer ( List < Object ? > ? params ) async {
print ( " ----------Event Pre Offer Received ---------- " ) ;
dynamic items = params ! . toList ( ) ;
print ( " Doctor ID : " + items [ 0 ] [ ' from ' ] . toString ( ) ) ;
print ( " Patient ID: " + items [ 0 ] [ ' to ' ] . toString ( ) ) ;
doctorID = items [ 0 ] [ ' from ' ] ;
patientID = items [ 0 ] [ ' to ' ] ;
initStreams ( ) ;
createPConnection ( ) ;
sendPreAnswerOffer ( ) ;
}
handleOnOffer ( List < Object ? > ? params ) async {
print ( " ----------Event On Offer Received ---------- " ) ;
dynamic items = params ! . toList ( ) ;
var data = jsonDecode ( items [ 0 ] [ " offer " ] ) ;
_localStream ? . getTracks ( ) . forEach ( ( track ) {
pCon ! . addTrack ( track , _localStream ! ) ;
} ) ;
await pCon ! . setRemoteDescription ( RTCSessionDescription ( data [ " sdp " ] , data [ " type " ] ) ) ;
RTCSessionDescription description = await pCon ! . createAnswer ( ) ;
await pCon ! . setLocalDescription ( description ) ;
var payload = {
" to " : doctorID ,
" callerSocketId " : patientID ,
" answer " : " ${ json . encode ( description . toMap ( ) ) } " ,
} ;
if ( chatHubConnection ! . state = = HubConnectionState . Connected ) {
print ( " ---------Answer Offer Invoke -------- " ) ;
await chatHubConnection ! . invoke ( " OnAnswerOffer " , args: [ payload ] ) . onError ( ( error , stackTrace ) {
print ( " error sending offer answer " ) ;
Utils . showErrorToast ( error . toString ( ) ) ;
} ) ;
}
startCallByRTC ( ) ;
Future . delayed ( Duration ( seconds: 5 ) , ( ) {
Navigator . push (
locator < NavigationService > ( ) . navigatorKey . currentContext ! ,
MaterialPageRoute (
builder: ( BuildContext context ) = > StartCallPage ( ) ,
) ) ;
} ) ;
}
handleIceCandidate ( List < Object ? > ? params ) async {
print ( " ----------Event Ice Candidate Received ---------- " ) ;
dynamic items = params ! . toList ( ) ;
var val = jsonDecode ( items [ 0 ] [ " candidate " ] ) ;
RemoteIceCandidatePayLoad data = await RemoteIceCandidatePayLoad (
target: 00000 , candidate: Candidate ( candidate: val [ " candidate " ] , sdpMid: val [ " sdpMid " ] , sdpMLineIndex: val [ " sdpMLineIndex " ] , usernameFragment: val [ " usernameFragment " ] ) ) ;
if ( pCon ! = null ) {
pCon ! . addCandidate ( RTCIceCandidate ( data . candidate ! . candidate , data . candidate ! . sdpMid , data . candidate ! . sdpMLineIndex ) ) ;
}
}
handleCallDecline ( List < Object ? > ? params ) {
print ( " ----------handle Call Decline Received ---------- " ) ;
dynamic items = params ! . toList ( ) ;
logger . d ( items ) ;
}
handleNoAnswerCall ( List < Object ? > ? params ) {
print ( " ----------handle No Answer Received ---------- " ) ;
dynamic items = params ! . toList ( ) ;
logger . d ( items ) ;
}
handleCallComplete ( List < Object ? > ? params ) {
print ( " ----------handle Call Complete Received ---------- " ) ;
dynamic items = params ! . toList ( ) ;
logger . d ( items ) ;
isCallStarted = false ;
isVideoCall = false ;
isCamOff = false ;
isMicOff = false ;
isLoudSpeaker = false ;
isIncomingCall = false ;
isOutGoingCall = false ;
isAudioCall = false ;
if ( pCon ! . connectionState = = RTCPeerConnectionState . RTCPeerConnectionStateConnected ) {
pCon ! . close ( ) ;
pCon ! . dispose ( ) ;
}
if ( remoteRenderer ! = null ) {
remoteRenderer ! . dispose ( ) ;
remoteRenderer = null ;
}
if ( localVideoRenderer ! = null ) {
localVideoRenderer ! . dispose ( ) ;
localVideoRenderer = null ;
}
if ( _localStream ! = null ) {
_localStream ! . dispose ( ) ;
_localStream = null ;
}
if ( chatHubConnection ! = null & & ! isUserOnline ) {
chatHubConnection ! . stop ( ) ;
}
}
void createPConnection ( ) async {
Map < String , dynamic > configuration = {
" sdpSemantics " : " plan-b " ,
' iceServers ' : [
{
' urls ' : ' stun:15.185.116.59:3478 ' ,
} ,
{
' urls ' : ' turn:15.185.116.59:3479 ' ,
' username ' : ' admin ' ,
' credential ' : ' admin ' ,
}
] ,
" iceCandidatePoolSize " : 10
} ;
Map < String , dynamic > offerSdpConstraints = {
' mandatory ' : {
' OfferToReceiveAudio ' : true ,
' OfferToReceiveVideo ' : true ,
} ,
' optional ' : [ ]
} ;
pCon = await createPeerConnection ( configuration , offerSdpConstraints ) ;
pCon ! . onConnectionState = ( RTCPeerConnectionState state ) { } ;
pCon ! . onAddStream = ( MediaStream stream ) {
remoteRenderer ! . srcObject = stream ;
notifyListeners ( ) ;
} ;
pCon ! . onIceCandidate = ( RTCIceCandidate e ) async {
if ( e . candidate ! = null ) {
await pCon ! . addCandidate ( e ) ;
var data = { " target " : doctorID , " callerSocketId " : doctorID , " from " : patientID , " calleePersonalCode " : patientID , " to " : doctorID , " candidate " : " ${ json . encode ( e . toMap ( ) ) } " } ;
if ( chatHubConnection ! . state = = HubConnectionState . Connected ) {
await chatHubConnection ! . invoke ( ' IceCandidate ' , args: [ data ] ) . onError ( ( error , stackTrace ) {
Utils . showErrorToast ( error . toString ( ) ) ;
} ) ;
}
}
} ;
pCon ! . onSignalingState = ( RTCSignalingState state ) {
print ( " signaling state: " + state . name ) ;
} ;
pCon ! . onIceGatheringState = ( RTCIceGatheringState state ) {
print ( " rtc ice gathering state: " + state . name ) ;
} ;
pCon ! . onIceConnectionState = ( RTCIceConnectionState state ) {
if ( RTCIceConnectionState . RTCIceConnectionStateFailed = = state | |
RTCIceConnectionState . RTCIceConnectionStateDisconnected = = state | |
RTCIceConnectionState . RTCIceConnectionStateClosed = = state ) {
print ( " Ice Connection State: " + state . name ) ;
}
} ;
}
sendPreAnswerOffer ( ) async {
var data = {
" to " : doctorID ,
" calleePersonalCode " : patientID ,
" preOfferAnswer " : " " ,
} ;
print ( data ) ;
if ( chatHubConnection ! . state = = HubConnectionState . Connected ) {
await chatHubConnection ! . invoke ( " SendPreOfferAnswer " , args: [ data ] ) . onError ( ( error , stackTrace ) {
print ( " error sending pre offer answer " ) ;
Utils . showErrorToast ( error . toString ( ) ) ;
} ) ;
}
}
startCallByRTC ( ) {
isVideoCall = true ;
isIncomingCallLoader = false ;
isIncomingCall = true ;
isCallConnected = true ;
}
}
class HttpOverrideCertificateVerificationInDev extends HttpOverrides {
@ override
HttpClient createHttpClient ( SecurityContext ? context ) {
return super . createHttpClient ( context ) . . badCertificateCallback = ( X509Certificate cert , String host , int port ) = > true ;
}
}
// class ChatService extends BaseService {
// Future<getUserToken.UserAutoLoginModel> getUserCallToken({required String userid}) async {
// getUserToken.UserAutoLoginModel userLoginResponse = getUserToken.UserAutoLoginModel();
// http.post(Uri.parse("${ApiConsts.chatLoginTokenUrl}externaluserlogin"), body: {
// "employeeNumber": userid,
// "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
// }).then((response) {
// userLoginResponse = getUserToken.userAutoLoginModelFromJson(response.body);
// }).onError((error, stackTrace) {
// hasError = true;
// print(error);
// super.error = error.toString();
// });
//
// return userLoginResponse;
// }
// }