diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index f187ebd..5b3b2ba 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -7,7 +7,15 @@
-
+
+
+
+
+
+
+
+
+
main() async {
),
ChangeNotifierProvider(
create: (_) => MarathonProvider(),
- )
+ ),
+ // ChangeNotifierProvider(
+ // create: (_) => ChatCallProvider(),
+ // ),
],
child: const MyApp(),
),
@@ -261,4 +264,3 @@ class MyApp extends StatelessWidget {
// });
// }
// }
-
diff --git a/lib/models/chat/call.dart b/lib/models/chat/call.dart
index 7f8f6eb..ce58ae3 100644
--- a/lib/models/chat/call.dart
+++ b/lib/models/chat/call.dart
@@ -7,127 +7,191 @@ import 'dart:convert';
class CallDataModel {
CallDataModel({
this.callerId,
- this.callReceiverID,
- this.notificationForeground,
- this.message,
+ this.callerDetails,
+ this.receiverId,
+ this.receiverDetails,
this.title,
- this.type,
- this.identity,
- this.name,
- this.isCall,
- this.isWebrtc,
- this.contant,
- this.contantNo,
- this.chatEventId,
- this.fileTypeId,
- this.currentUserId,
- this.chatSource,
- this.userChatHistoryLineRequestList,
- this.server,
+ this.calltype,
});
String? callerId;
- String? callReceiverID;
- String? notificationForeground;
- String? message;
- String? title;
- String? type;
- String? identity;
- String? name;
- String? isCall;
- String? isWebrtc;
- String? contant;
- String? contantNo;
- String? chatEventId;
- dynamic? fileTypeId;
- String? currentUserId;
- String? chatSource;
- List? userChatHistoryLineRequestList;
- String? server;
+ CallerDetails? callerDetails;
+ String? receiverId;
+ ReceiverDetails? receiverDetails;
+ dynamic title;
+ String? calltype;
factory CallDataModel.fromRawJson(String str) => CallDataModel.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory CallDataModel.fromJson(Map json) => CallDataModel(
- callerId: json["callerID"] == null ? null : json["callerID"],
- callReceiverID: json["callReceiverID"] == null ? null : json["callReceiverID"],
- notificationForeground: json["notification_foreground"] == null ? null : json["notification_foreground"],
- message: json["message"] == null ? null : json["message"],
- title: json["title"] == null ? null : json["title"],
- type: json["type"] == null ? null : json["type"],
- identity: json["identity"] == null ? null : json["identity"],
- name: json["name"] == null ? null : json["name"],
- isCall: json["is_call"] == null ? null : json["is_call"],
- isWebrtc: json["is_webrtc"] == null ? null : json["is_webrtc"],
- contant: json["contant"] == null ? null : json["contant"],
- contantNo: json["contantNo"] == null ? null : json["contantNo"],
- chatEventId: json["chatEventId"] == null ? null : json["chatEventId"],
- fileTypeId: json["fileTypeId"],
- currentUserId: json["currentUserId"] == null ? null : json["currentUserId"],
- chatSource: json["chatSource"] == null ? null : json["chatSource"],
- userChatHistoryLineRequestList: json["userChatHistoryLineRequestList"] == null
- ? null
- : List.from(
- json["userChatHistoryLineRequestList"].map(
- (x) => UserChatHistoryLineRequestList.fromJson(x),
- ),
- ),
- server: json["server"] == null ? null : json["server"],
- );
+ callerId: json["callerID"],
+ callerDetails: json["callerDetails"] == null ? null : CallerDetails.fromJson(json["callerDetails"]),
+ receiverId: json["receiverID"],
+ receiverDetails: json["receiverDetails"] == null ? null : ReceiverDetails.fromJson(json["receiverDetails"]),
+ title: json["title"],
+ calltype: json["calltype"],
+ );
+
+ Map toJson() => {
+ "callerID": callerId,
+ "callerDetails": callerDetails?.toJson(),
+ "receiverID": receiverId,
+ "receiverDetails": receiverDetails?.toJson(),
+ "title": title,
+ "calltype": calltype,
+ };
+}
+
+class CallerDetails {
+ CallerDetails({
+ this.response,
+ this.errorResponses,
+ });
+
+ Response? response;
+ dynamic errorResponses;
+
+ factory CallerDetails.fromRawJson(String str) => CallerDetails.fromJson(json.decode(str));
+
+ String toRawJson() => json.encode(toJson());
+
+ factory CallerDetails.fromJson(Map json) => CallerDetails(
+ response: json["response"] == null ? null : Response.fromJson(json["response"]),
+ errorResponses: json["errorResponses"],
+ );
Map toJson() => {
- "callerID": callerId == null ? null : callerId,
- "callReceiverID": callReceiverID == null ? null : callReceiverID,
- "notification_foreground": notificationForeground == null ? null : notificationForeground,
- "message": message == null ? null : message,
- "title": title == null ? null : title,
- "type": type == null ? null : type,
- "identity": identity == null ? null : identity,
- "name": name == null ? null : name,
- "is_call": isCall == null ? null : isCall,
- "is_webrtc": isWebrtc == null ? null : isWebrtc,
- "contant": contant == null ? null : contant,
- "contantNo": contantNo == null ? null : contantNo,
- "chatEventId": chatEventId == null ? null : chatEventId,
- "fileTypeId": fileTypeId,
- "currentUserId": currentUserId == null ? null : currentUserId,
- "chatSource": chatSource == null ? null : chatSource,
- "userChatHistoryLineRequestList": userChatHistoryLineRequestList == null
- ? null
- : List.from(
- userChatHistoryLineRequestList!.map(
- (x) => x.toJson(),
- ),
- ),
- "server": server == null ? null : server,
- };
+ "response": response?.toJson(),
+ "errorResponses": errorResponses,
+ };
}
-class UserChatHistoryLineRequestList {
- UserChatHistoryLineRequestList({
- this.isSeen,
- this.isDelivered,
- this.targetUserId,
- this.targetUserStatus,
+class Response {
+ Response({
+ this.id,
+ this.userName,
+ this.email,
+ this.phone,
+ this.title,
+ this.token,
+ this.isDomainUser,
+ this.isActiveCode,
+ this.encryptedUserId,
+ this.encryptedUserName,
});
- bool? isSeen;
- bool? isDelivered;
- int? targetUserId;
- int? targetUserStatus;
+ int? id;
+ String? userName;
+ String? email;
+ dynamic phone;
+ String? title;
+ String? token;
+ bool? isDomainUser;
+ bool? isActiveCode;
+ String? encryptedUserId;
+ String? encryptedUserName;
+
+ factory Response.fromRawJson(String str) => Response.fromJson(json.decode(str));
+
+ String toRawJson() => json.encode(toJson());
+
+ factory Response.fromJson(Map json) => Response(
+ id: json["id"],
+ userName: json["userName"],
+ email: json["email"],
+ phone: json["phone"],
+ title: json["title"],
+ token: json["token"],
+ isDomainUser: json["isDomainUser"],
+ isActiveCode: json["isActiveCode"],
+ encryptedUserId: json["encryptedUserId"],
+ encryptedUserName: json["encryptedUserName"],
+ );
+
+ Map toJson() => {
+ "id": id,
+ "userName": userName,
+ "email": email,
+ "phone": phone,
+ "title": title,
+ "token": token,
+ "isDomainUser": isDomainUser,
+ "isActiveCode": isActiveCode,
+ "encryptedUserId": encryptedUserId,
+ "encryptedUserName": encryptedUserName,
+ };
+}
+
+class ReceiverDetails {
+ ReceiverDetails({
+ this.id,
+ this.userName,
+ this.email,
+ this.phone,
+ this.title,
+ this.userStatus,
+ this.image,
+ this.unreadMessageCount,
+ this.userAction,
+ this.isPin,
+ this.isFav,
+ this.isAdmin,
+ this.rKey,
+ this.totalCount,
+ });
+
+ int? id;
+ String? userName;
+ String? email;
+ dynamic phone;
+ dynamic title;
+ int? userStatus;
+ String? image;
+ int? unreadMessageCount;
+ dynamic userAction;
+ bool? isPin;
+ bool? isFav;
+ bool? isAdmin;
+ String? rKey;
+ int? totalCount;
+
+ factory ReceiverDetails.fromRawJson(String str) => ReceiverDetails.fromJson(json.decode(str));
+
+ String toRawJson() => json.encode(toJson());
- factory UserChatHistoryLineRequestList.fromJson(Map json) => UserChatHistoryLineRequestList(
- isSeen: json["isSeen"] == null ? null : json["isSeen"],
- isDelivered: json["isDelivered"] == null ? null : json["isDelivered"],
- targetUserId: json["targetUserId"] == null ? null : json["targetUserId"],
- targetUserStatus: json["targetUserStatus"] == null ? null : json["targetUserStatus"],
- );
+ factory ReceiverDetails.fromJson(Map json) => ReceiverDetails(
+ id: json["id"],
+ userName: json["userName"],
+ email: json["email"],
+ phone: json["phone"],
+ title: json["title"],
+ userStatus: json["userStatus"],
+ image: json["image"],
+ unreadMessageCount: json["unreadMessageCount"],
+ userAction: json["userAction"],
+ isPin: json["isPin"],
+ isFav: json["isFav"],
+ isAdmin: json["isAdmin"],
+ rKey: json["rKey"],
+ totalCount: json["totalCount"],
+ );
Map toJson() => {
- "isSeen": isSeen == null ? null : isSeen,
- "isDelivered": isDelivered == null ? null : isDelivered,
- "targetUserId": targetUserId == null ? null : targetUserId,
- "targetUserStatus": targetUserStatus == null ? null : targetUserStatus,
- };
+ "id": id,
+ "userName": userName,
+ "email": email,
+ "phone": phone,
+ "title": title,
+ "userStatus": userStatus,
+ "image": image,
+ "unreadMessageCount": unreadMessageCount,
+ "userAction": userAction,
+ "isPin": isPin,
+ "isFav": isFav,
+ "isAdmin": isAdmin,
+ "rKey": rKey,
+ "totalCount": totalCount,
+ };
}
diff --git a/lib/provider/chat_call_provider.dart b/lib/provider/chat_call_provider.dart
new file mode 100644
index 0000000..45205df
--- /dev/null
+++ b/lib/provider/chat_call_provider.dart
@@ -0,0 +1,187 @@
+import 'dart:convert';
+import 'dart:ui';
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter_webrtc/flutter_webrtc.dart';
+import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
+
+class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
+ ///////////////////// Web RTC Video Calling //////////////////////
+ // Video Call
+ late RTCPeerConnection _peerConnection;
+ RTCVideoRenderer _localVideoRenderer = RTCVideoRenderer();
+ final RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
+
+ MediaStream? _localStream;
+ MediaStream? _remoteStream;
+
+ void initCallListeners() {
+ chatHubConnection.on("OnCallAcceptedAsync", onCallAcceptedAsync);
+ chatHubConnection.on("OnIceCandidateAsync", onIceCandidateAsync);
+ chatHubConnection.on("OnOfferAsync", onOfferAsync);
+ chatHubConnection.on("OnAnswerOffer", onAnswerOffer);
+ chatHubConnection.on("OnHangUpAsync", onHangUpAsync);
+ chatHubConnection.on("OnCallDeclinedAsync", onCallDeclinedAsync);
+ }
+
+ //Video Constraints
+ var videoConstraints = {
+ "video": {
+ "mandatory": {
+ "width": {"min": 320},
+ "height": {"min": 180}
+ },
+ "optional": [
+ {
+ "width": {"max": 1280}
+ },
+ {"frameRate": 25},
+ {"facingMode": "user"}
+ ]
+ },
+ "frameRate": 25,
+ "width": 420, //420,//640,//1280,
+ "height": 240 //240//480//720
+ };
+
+ // Audio Constraints
+ var audioConstraints = {
+ "sampleRate": 8000,
+ "sampleSize": 16,
+ "channelCount": 2,
+ "echoCancellation": true,
+ "audio": true,
+ };
+
+ Future _createPeerConnection() async {
+ // {"url": "stun:stun.l.google.com:19302"},
+ Map configuration = {
+ "iceServers": [
+ {"urls": 'stun:15.185.116.59:3478'},
+ {"urls": "turn:15.185.116.59:3479", "username": "admin", "credential": "admin"}
+ ]
+ };
+
+ Map offerSdpConstraints = {
+ "mandatory": {
+ "OfferToReceiveAudio": true,
+ "OfferToReceiveVideo": true,
+ },
+ "optional": [],
+ };
+
+ RTCPeerConnection pc = await createPeerConnection(configuration, offerSdpConstraints);
+ // if (pc != null) print(pc);
+ //pc.addStream(widget.localStream);
+
+ pc.onIceCandidate = (e) {
+ if (e.candidate != null) {
+ print(json.encode({
+ 'candidate': e.candidate.toString(),
+ 'sdpMid': e.sdpMid.toString(),
+ 'sdpMlineIndex': e.sdpMLineIndex,
+ }));
+ }
+ };
+ pc.onIceConnectionState = (e) {
+ print(e);
+ };
+ pc.onAddStream = (stream) {
+ print('addStream: ' + stream.id);
+ _remoteRenderer.srcObject = stream;
+ };
+ return pc;
+ }
+
+ void init() {
+ initRenderers();
+ _createPeerConnection().then((pc) {
+ _peerConnection = pc;
+ // _setRemoteDescription(widget.info);
+ });
+ }
+
+ void initRenderers() {
+ _localVideoRenderer.initialize();
+ _remoteRenderer.initialize();
+ initLocalCamera();
+ }
+
+ void initLocalCamera() async {
+ _localStream = await navigator.mediaDevices.getUserMedia({'video': true, 'audio': true});
+ _localVideoRenderer.srcObject = _localStream;
+ // _localVideoRenderer.srcObject = await navigator.mediaDevices
+ // .getUserMedia({'video': true, 'audio': true});
+ print('this source Object');
+ print('this suarce ${_localVideoRenderer.srcObject != null}');
+ notifyListeners();
+ }
+
+ void startCall({required String callType}) {}
+
+ void endCall() {}
+
+ void checkCall(Map message) {
+ switch (message["callStatus"]) {
+ case 'connected':
+ {}
+ break;
+ case 'offer':
+ {}
+ break;
+ case 'accept':
+ {}
+ break;
+ case 'candidate':
+ {}
+ break;
+ case 'bye':
+ {}
+ break;
+ case 'leave':
+ {}
+ break;
+ }
+ }
+
+ //// Listeners Methods ////
+
+ void onCallAcceptedAsync(List