From 86ac29946fb2fea5ba17ea84d2e763f76064c170 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Sun, 20 Nov 2022 12:19:54 +0300 Subject: [PATCH 1/7] Chat Updates & Counter Event Modifications --- lib/api/chat/chat_provider_model.dart | 144 ++++++++++++++++++++------ lib/ui/chat/chat_home.dart | 2 +- lib/ui/chat/chat_home_screen.dart | 42 ++++---- 3 files changed, 134 insertions(+), 54 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 7439b98..2e8bcb8 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -44,7 +44,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { bool _firstAutoscrollExecuted = false; bool _shouldAutoscroll = false; - Future getUserAutoLoginToken() async { + Future getUserAutoLoginToken(BuildContext cxt) async { Response response = await ApiClient().postJsonForResponse( "${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", { @@ -76,7 +76,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { return searchUserJsonModel(response.body); } - List searchUserJsonModel(String str) => List.from(json.decode(str).map((x) => ChatUser.fromJson(x))); + List searchUserJsonModel(String str) => List.from( + json.decode(str).map( + (x) => ChatUser.fromJson(x), + ), + ); void getUserRecentChats() async { Response response = await ApiClient().getJsonForResponse( @@ -90,9 +94,18 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { token: AppState().chatDetails!.response!.token, ); ChatUserModel favUList = userToList(favRes.body); + GetUserChatHistoryNotDeliveredAsync( + userId: int.parse( + AppState().chatDetails!.response!.id.toString(), + ), + ); if (favUList.response != null) { favUsersList = favUList.response!; - favUsersList.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase())); + favUsersList.sort( + (ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo( + b.userName!.toLowerCase(), + ), + ); for (dynamic user in recentChat.response!) { for (dynamic favUser in favUList.response!) { if (user.id == favUser.id) { @@ -101,16 +114,23 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } } - pChatHistory = recentChat.response == null ? [] : recentChat.response; - if (pChatHistory != null) pChatHistory!.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase())); + pChatHistory = recentChat.response ?? []; + pChatHistory!.sort( + (ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo( + b.userName!.toLowerCase(), + ), + ); searchedChats = pChatHistory; isLoading = false; notifyListeners(); } - Future GetUserChatHistoryNotDeliveredAsync(int userId) async { - await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]); + Future GetUserChatHistoryNotDeliveredAsync({required int userId}) async { + await hubConnection.invoke( + "GetUserChatHistoryNotDeliveredAsync", + args: [userId], + ); return ""; } @@ -132,35 +152,89 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } else { if (loadMore) { - List temp = getSingleUserChatModel(response.body).reversed.toList(); - userChatHistory.addAll(temp); + List temp = getSingleUserChatModel( + response.body, + ).reversed.toList(); + userChatHistory.addAll( + temp, + ); } else { - userChatHistory = getSingleUserChatModel(response.body).reversed.toList(); + userChatHistory = getSingleUserChatModel( + response.body, + ).reversed.toList(); } } + await GetUserChatHistoryNotDeliveredAsync( + userId: senderUID, + ); isLoading = false; - await GetUserChatHistoryNotDeliveredAsync(senderUID); notifyListeners(); + markRead( + userChatHistory, + receiverUID, + ); + } + + void markRead(List data, reciverID) { + for (SingleUserChatModel element in data!) { + if (!element.isSeen!) { + dynamic data = [ + { + "userChatHistoryId": element.userChatHistoryId, + "TargetUserId": element.targetUserId, + "isDelivered": true, + "isSeen": true, + } + ]; + updateUserChatHistoryStatusAsync(data); + } + } + for (ChatUser element in searchedChats!) { + if (element.id == reciverID) { + element.unreadMessageCount = 0; + notifyListeners(); + } + } } void updateUserChatHistoryStatusAsync(List data) { - hubConnection.invoke("UpdateUserChatHistoryStatusAsync", args: [data]); + hubConnection.invoke( + "UpdateUserChatHistoryStatusAsync", + args: [data], + ); } - List getSingleUserChatModel(String str) => List.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); + List getSingleUserChatModel(String str) => List.from( + json.decode(str).map( + (x) => SingleUserChatModel.fromJson(x), + ), + ); - ChatUserModel userToList(String str) => ChatUserModel.fromJson(json.decode(str)); + ChatUserModel userToList(String str) => ChatUserModel.fromJson( + json.decode(str), + ); Future uploadAttachments(String userId, File file) async { dynamic result; - dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatMediaImageUploadUrl}')); + dynamic request = MultipartRequest( + 'POST', + Uri.parse( + '${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatMediaImageUploadUrl}', + ), + ); request.fields.addAll({'userId': userId, 'fileSource': '1'}); request.files.add(await MultipartFile.fromPath('files', file.path)); - request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'}); + request.headers.addAll( + { + 'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}', + }, + ); try { StreamedResponse response = await request.send(); if (response.statusCode == 200) { - result = jsonDecode(await response.stream.bytesToString()); + result = jsonDecode( + await response.stream.bytesToString(), + ); } else { result = []; } @@ -176,7 +250,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future buildHubConnection() async { HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); hubConnection = HubConnectionBuilder() - .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp) + .withUrl( + ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", + options: httpOp, + ) .withAutomaticReconnect( retryDelays: [2000, 5000, 10000, 20000], ) @@ -194,6 +271,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ({String? connectionId}) {}, ); if (hubConnection.state != HubConnectionState.Connected) { + print("Started"); await hubConnection.start(); hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); @@ -260,23 +338,23 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void chatNotDelivered(List? args) { dynamic items = args!.toList(); for (dynamic item in items[0]) { - dynamic data = [ - { - "userChatHistoryId": item["userChatHistoryId"], - "TargetUserId": item["targetUserId"], - "isDelivered": true, - "isSeen": true, + searchedChats!.forEach((element) { + if (element.id == item["currentUserId"]) { + var val = element.unreadMessageCount == null ? 0 : element.unreadMessageCount; + element.unreadMessageCount = val! + 1; } - ]; - updateUserChatHistoryStatusAsync(data); + }); + // dynamic data = [ + // { + // "userChatHistoryId": item["userChatHistoryId"], + // "TargetUserId": item["targetUserId"], + // "isDelivered": true, + // "isSeen": true, + // } + // ]; + // updateUserChatHistoryStatusAsync(data); } - logger.d(items); - // for (var user in searchedChats!) { - // if (user.id == items.first["id"]) { - // user.userStatus = items.first["userStatus"]; - // } - // } - // notifyListeners();2 + notifyListeners(); } void changeStatus(List? args) { diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 9884d59..06a2c32 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -34,7 +34,7 @@ class _ChatHomeState extends State { // TODO: implement initState super.initState(); data = Provider.of(context, listen: false); - data.getUserAutoLoginToken().then((Object? value) { + data.getUserAutoLoginToken(context).then((Object? value) { data.getUserRecentChats(); }); } diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 05623f7..816aaec 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -7,6 +7,7 @@ import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_sheet.dart'; @@ -134,26 +135,26 @@ class _ChatHomeScreenState extends State { mainAxisAlignment: MainAxisAlignment.end, mainAxisSize: MainAxisSize.max, children: [ - // if (m.searchedChats![index].unreadMessageCount != null) - // Flexible( - // child: Container( - // padding: EdgeInsets.zero, - // alignment: Alignment.centerRight, - // width: 18, - // height: 18, - // decoration: const BoxDecoration( - // color: MyColors.redColor, - // borderRadius: BorderRadius.all( - // Radius.circular(20), - // ), - // ), - // child: (m.searchedChats![index].unreadMessageCount!.toString()) - // .toText10( - // color: MyColors.white, - // ) - // .center, - // ), - // ), + if (m.searchedChats![index].unreadMessageCount! > 0) + Flexible( + child: Container( + padding: EdgeInsets.zero, + alignment: Alignment.centerRight, + width: 18, + height: 18, + decoration: const BoxDecoration( + color: MyColors.redColor, + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + ), + child: (m.searchedChats![index].unreadMessageCount!.toString()) + .toText10( + color: MyColors.white, + ) + .center, + ), + ), Flexible( child: IconButton( alignment: Alignment.centerRight, @@ -192,6 +193,7 @@ class _ChatHomeScreenState extends State { AppRoutes.chatDetailed, arguments: {"targetUser": m.searchedChats![index], "isNewChat": false}, ).then((Object? value) { + // m.GetUserChatHistoryNotDeliveredAsync(userId: int.parse(AppState().chatDetails!.response!.id.toString())); m.clearSelections(); m.notifyListeners(); }); From fab16db8b3350f58eb67c6db381cc35c4f7033b4 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Sun, 20 Nov 2022 15:29:25 +0300 Subject: [PATCH 2/7] Chat Updates & Counter Event Modifications --- lib/api/chat/chat_provider_model.dart | 50 ++++++++++++++------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 2e8bcb8..7dbc0be 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -29,7 +29,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { late HubConnection hubConnection; L.Logger logger = L.Logger(); bool hubConInitialized = false; - + String chatCID = ''; bool isLoading = true; bool isChatScreenActive = false; late File selectedFile; @@ -40,17 +40,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List favUsersList = []; int paginationVal = 0; - //Scroll - bool _firstAutoscrollExecuted = false; - bool _shouldAutoscroll = false; - Future getUserAutoLoginToken(BuildContext cxt) async { Response response = await ApiClient().postJsonForResponse( "${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", { - "employeeNumber": int.parse( + "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - ), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" }, ); @@ -173,6 +168,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { userChatHistory, receiverUID, ); + generateConvId(); + } + + void generateConvId() async { + Uuid uuid = const Uuid(); + chatCID = uuid.v4(); } void markRead(List data, reciverID) { @@ -506,13 +507,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future sendChatToServer( {required int chatEventId, required fileTypeId, required int targetUserId, required String targetUserName, required chatReplyId, required bool isAttachment, required bool isReply}) async { Uuid uuid = const Uuid(); + var msg = message.text; SingleUserChatModel data = SingleUserChatModel( chatEventId: chatEventId, chatSource: 1, contant: msg, contantNo: uuid.v4(), - conversationId: uuid.v4(), + conversationId: chatCID, createdDate: DateTime.now(), currentUserId: AppState().chatDetails!.response!.id, currentUserName: AppState().chatDetails!.response!.userName, @@ -743,22 +745,22 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { sFileType = ""; } - void scrollListener() { - _firstAutoscrollExecuted = true; - if (scrollController.hasClients && scrollController.position.pixels == scrollController.position.maxScrollExtent) { - _shouldAutoscroll = true; - } else { - _shouldAutoscroll = false; - } - } - - void scrollToBottom() { - scrollController.animateTo( - scrollController.position.maxScrollExtent + 100, - duration: const Duration(milliseconds: 500), - curve: Curves.easeIn, - ); - } + // void scrollListener() { + // _firstAutoscrollExecuted = true; + // if (scrollController.hasClients && scrollController.position.pixels == scrollController.position.maxScrollExtent) { + // _shouldAutoscroll = true; + // } else { + // _shouldAutoscroll = false; + // } + // } + // + // void scrollToBottom() { + // scrollController.animateTo( + // scrollController.position.maxScrollExtent + 100, + // duration: const Duration(milliseconds: 500), + // curve: Curves.easeIn, + // ); + // } void msgScroll() { scrollController.animateTo( From c1f3f17c89fbe496f16b794986a38db0fad275e8 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Sun, 20 Nov 2022 15:32:51 +0300 Subject: [PATCH 3/7] Chat Updates & Counter Event Modifications --- lib/api/chat/chat_provider_model.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 7dbc0be..ac26c38 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -541,7 +541,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); String chatData = - '{"contant":"$msg","contantNo":"${uuid.v4()}","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"${uuid.v4()}"}'; + '{"contant":"$msg","contantNo":"${uuid.v4()}","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"$chatCID"}'; await hubConnection.invoke("AddChatUserAsync", args: [json.decode(chatData)]); } From 2e88275285242704602d82b3e7e26758cf997f93 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 21 Nov 2022 09:31:53 +0300 Subject: [PATCH 4/7] Chat Updates & Counter Event Modifications --- lib/api/chat/chat_provider_model.dart | 18 +- lib/classes/consts.dart | 4 +- lib/models/chat/call.dart | 226 ++++++++++-------- .../chat/call/chat_incoming_call_screen.dart | 2 +- .../chat/call/chat_outgoing_call_screen.dart | 5 +- lib/ui/chat/chat_detailed_screen.dart | 69 +++--- lib/ui/chat/chat_home.dart | 4 +- 7 files changed, 173 insertions(+), 155 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index ac26c38..868aa7a 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -43,11 +43,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future getUserAutoLoginToken(BuildContext cxt) async { Response response = await ApiClient().postJsonForResponse( "${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", - { - "employeeNumber": - AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG" - }, + {"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG"}, ); login.UserAutoLoginModel userLoginResponse = login.userAutoLoginModelFromJson( response.body, @@ -58,7 +54,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { AppState().setchatUserDetails = userLoginResponse; await buildHubConnection(); } else { - Utils.showToast(userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr"); + Utils.showToast( + userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr", + ); return; } } @@ -94,7 +92,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { AppState().chatDetails!.response!.id.toString(), ), ); - if (favUList.response != null) { + if (favUList.response != null && recentChat.response != null) { favUsersList = favUList.response!; favUsersList.sort( (ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo( @@ -249,7 +247,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } Future buildHubConnection() async { - HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); + HttpConnectionOptions httpOp = HttpConnectionOptions( + skipNegotiation: false, + logMessageContent: true, + ); hubConnection = HubConnectionBuilder() .withUrl( ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", @@ -272,7 +273,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ({String? connectionId}) {}, ); if (hubConnection.state != HubConnectionState.Connected) { - print("Started"); await hubConnection.start(); hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index ede22e3..c5788f9 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server - static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - //static String baseUrl = "https://hmgwebservices.com"; // Live server + //static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; diff --git a/lib/models/chat/call.dart b/lib/models/chat/call.dart index eacdd03..20f6a79 100644 --- a/lib/models/chat/call.dart +++ b/lib/models/chat/call.dart @@ -1,117 +1,133 @@ -class IncomingCallData { - String? callerID; - String? receiverID; - String? msgID; - String? notfID; +// To parse this JSON data, do +// +// final callDataModel = callDataModelFromJson(jsonString); + +import 'dart:convert'; + +class CallDataModel { + CallDataModel({ + this.callerId, + this.callReciverId, + this.notificationForeground, + this.message, + 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, + }); + + String? callerId; + String? callReciverId; String? notificationForeground; - String? count; String? message; - String? appointmentNo; String? title; - String? projectID; - String? notificationType; - String? background; - String? doctorname; - String? clinicname; - String? speciality; - String? appointmentdate; - String? appointmenttime; String? type; - String? sessionId; String? identity; String? name; - String? videoUrl; - String? picture; - String? token; String? isCall; - String? sound; + String? isWebrtc; + String? contant; + String? contantNo; + String? chatEventId; + dynamic? fileTypeId; + String? currentUserId; + String? chatSource; + List? userChatHistoryLineRequestList; String? server; - String? isWebRTC; - IncomingCallData( - {this.msgID, - this.notfID, - this.notificationForeground, - this.count, - this.message, - this.appointmentNo, - this.title, - this.projectID, - this.notificationType, - this.background, - this.doctorname, - this.clinicname, - this.speciality, - this.appointmentdate, - this.appointmenttime, - this.type, - this.sessionId, - this.identity, - this.name, - this.videoUrl, - this.picture, - this.isCall, - this.sound}); + 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"], + callReciverId: json["callReciverID"] == null ? null : json["callReciverID"], + 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"], + ); + + Map toJson() => { + "callerID": callerId == null ? null : callerId, + "callReciverID": callReciverId == null ? null : callReciverId, + "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, + }; +} + +class UserChatHistoryLineRequestList { + UserChatHistoryLineRequestList({ + this.isSeen, + this.isDelivered, + this.targetUserId, + this.targetUserStatus, + }); + + bool? isSeen; + bool? isDelivered; + int? targetUserId; + int? targetUserStatus; - IncomingCallData.fromJson(Map json) { - callerID = json['callerID']; - receiverID = json['PatientID']; - msgID = json['msgID']; - notfID = json['notfID']; - notificationForeground = json['notification_foreground']; - count = json['count']; - message = json['message']; - appointmentNo = json['AppointmentNo']; - title = json['title']; - projectID = json['ProjectID']; - notificationType = json['NotificationType']; - background = json['background']; - doctorname = json['doctorname']; - clinicname = json['clinicname']; - speciality = json['speciality']; - appointmentdate = json['appointmentdate']; - appointmenttime = json['appointmenttime']; - type = json['type']; - sessionId = json['session_id']; - token = json['token']; - identity = json['identity']; - name = json['name']; - videoUrl = json['videoUrl']; - picture = json['picture']; - isCall = json['is_call']; - sound = json['sound']; - server = json['server']; - isWebRTC = json['is_webrtc'] ?? "true"; - } + 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"], + ); - Map toJson() { - Map data = Map(); - data['msgID'] = this.msgID; - data['notfID'] = this.notfID; - data['notification_foreground'] = this.notificationForeground; - data['count'] = this.count; - data['message'] = this.message; - data['AppointmentNo'] = this.appointmentNo; - data['title'] = this.title; - data['ProjectID'] = this.projectID; - data['NotificationType'] = this.notificationType; - data['background'] = this.background; - data['doctorname'] = this.doctorname; - data['clinicname'] = this.clinicname; - data['speciality'] = this.speciality; - data['appointmentdate'] = this.appointmentdate; - data['appointmenttime'] = this.appointmenttime; - data['type'] = this.type; - data['session_id'] = this.sessionId; - data['token'] = this.token; - data['identity'] = this.identity; - data['name'] = this.name; - data['videoUrl'] = this.videoUrl; - data['picture'] = this.picture; - data['is_call'] = this.isCall; - data['sound'] = this.sound; - data['server'] = this.server; - data['is_webrtc'] = this.isWebRTC; - return data; - } + Map toJson() => { + "isSeen": isSeen == null ? null : isSeen, + "isDelivered": isDelivered == null ? null : isDelivered, + "targetUserId": targetUserId == null ? null : targetUserId, + "targetUserStatus": targetUserStatus == null ? null : targetUserStatus, + }; } diff --git a/lib/ui/chat/call/chat_incoming_call_screen.dart b/lib/ui/chat/call/chat_incoming_call_screen.dart index b98763a..a0b8247 100644 --- a/lib/ui/chat/call/chat_incoming_call_screen.dart +++ b/lib/ui/chat/call/chat_incoming_call_screen.dart @@ -7,7 +7,7 @@ import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/models/chat/call.dart'; class IncomingCall extends StatefulWidget { - IncomingCallData incomingCallData; + CallDataModel incomingCallData; bool? isVideoCall; IncomingCall({Key? key, required this.incomingCallData, this.isVideoCall}) : super(key: key); diff --git a/lib/ui/chat/call/chat_outgoing_call_screen.dart b/lib/ui/chat/call/chat_outgoing_call_screen.dart index 25bc05d..627c24a 100644 --- a/lib/ui/chat/call/chat_outgoing_call_screen.dart +++ b/lib/ui/chat/call/chat_outgoing_call_screen.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:ui'; import 'package:camera/camera.dart'; @@ -7,10 +8,11 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/chat/call.dart'; class OutGoingCall extends StatefulWidget { - IncomingCallData OutGoingCallData; + CallDataModel OutGoingCallData; bool? isVideoCall; OutGoingCall({Key? key, required this.OutGoingCallData, this.isVideoCall}) : super(key: key); @@ -36,6 +38,7 @@ class _OutGoingCallState extends State with SingleTickerProviderSt milliseconds: 500, ), ); + logger.d(jsonEncode(widget.OutGoingCallData)); //_runAnimation(); // connectSignaling(); WidgetsBinding.instance.addPostFrameCallback( diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 347c573..4a8e70c 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:convert'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -10,6 +11,7 @@ import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/chat/call.dart'; import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart'; import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart'; @@ -17,6 +19,7 @@ import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; +import 'package:signalr_netcore/signalr_client.dart'; import 'package:swipe_to/swipe_to.dart'; class ChatDetailScreen extends StatefulWidget { @@ -55,13 +58,14 @@ class _ChatDetailScreenState extends State { Widget build(BuildContext context) { userDetails = ModalRoute.of(context)!.settings.arguments; data = Provider.of(context, listen: false); - if (userDetails != null) + if (userDetails != null) { data.getSingleUserChatHistory( senderUID: AppState().chatDetails!.response!.id!.toInt(), receiverUID: userDetails["targetUser"].id, loadMore: false, isNewChat: userDetails["isNewChat"], ); + } return Scaffold( backgroundColor: const Color(0xFFF8F8F8), @@ -72,7 +76,10 @@ class _ChatDetailScreenState extends State { actions: [ IconButton( onPressed: () { - makeCall("AUDIO"); + // makeCall( + // callType: "AUDIO", + // con: data.hubConnection, + // ); }, icon: SvgPicture.asset( "assets/icons/chat/call.svg", @@ -82,7 +89,10 @@ class _ChatDetailScreenState extends State { ), IconButton( onPressed: () { - makeCall("VIDEO"); + // makeCall( + // callType: "VIDEO", + // con: data.hubConnection, + // ); }, icon: SvgPicture.asset( "assets/icons/chat/video_call.svg", @@ -345,45 +355,34 @@ class _ChatDetailScreenState extends State { ); } - void makeCall(String callType) async { - // final server = await SelectionDialog( - // context, - // title: "Select Server", - // items: ["https://livecareturn.hmg.com:8086", "https://104.197.179.1:8086"] - // ).show(); - - Map json = { - "callerID": "9920", - "PatientID": "1231755", - "msgID": "123", - "notfID": "123", + void makeCall({required String callType, required HubConnection con}) async { + print("================== Make call Triggered ============================"); + logger.d(jsonEncode(AppState().chatDetails!.response)); + Map json = { + "callerID": AppState().chatDetails!.response!.id!.toString(), + "callReciverID": userDetails["targetUser"].id.toString(), "notification_foreground": "true", - "count": "1", - "message": "Doctor is calling ", - "AppointmentNo": "123", - "title": "Rayyan Hospital", - "ProjectID": "123", - "NotificationType": "10", - "background": "1", - "doctorname": "Dr Sulaiman Al Habib", - "clinicname": "ENT Clinic", - "speciality": "Speciality", - "appointmentdate": "Sun, 15th Dec, 2019", - "appointmenttime": "09:00", - "type": "video", - "session_id": - "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImN0eSI6InR3aWxpby1mcGE7dj0xIn0.eyJqdGkiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0LTE1OTg3NzQ1MDYiLCJpc3MiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0Iiwic3ViIjoiQUNhYWQ1YTNmOGM2NGZhNjczNTY3NTYxNTc0N2YyNmMyYiIsImV4cCI6MTU5ODc3ODEwNiwiZ3JhbnRzIjp7ImlkZW50aXR5IjoiSGFyb29uMSIsInZpZGVvIjp7InJvb20iOiJTbWFsbERhaWx5U3RhbmR1cCJ9fX0.7XUS5uMQQJfkrBZu9EjQ6STL6R7iXkso6BtO1HmrQKk", - "identity": "Haroon1", - "name": "SmallDailyStandup", - "videoUrl": "video", - "picture": "video", + "message": "Aamir is calling ", + "title": "Video Call", + "type": callType == "VIDEO" ? "Video" : "Audio", + "identity": "Aamir.Muhammad", + "name": "Aamir Saleem Ahmad", "is_call": "true", "is_webrtc": "true", + "contant": "Start video Call Aamir.Muhammad", + "contantNo": "775d1f11-62d9-6fcc-91f6-21f8c14559fb", + "chatEventId": "3", + "fileTypeId": null, + "currentUserId": "266642", + "chatSource": "1", + "userChatHistoryLineRequestList": [ + {"isSeen": false, "isDelivered": false, "targetUserId": 341682, "targetUserStatus": 4} + ], // "server": "https://192.168.8.163:8086", "server": "https://livecareturn.hmg.com:8086", }; - IncomingCallData incomingCallData = IncomingCallData.fromJson(json); + CallDataModel incomingCallData = CallDataModel.fromJson(json); await Navigator.push( context, MaterialPageRoute( diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 06a2c32..b2db98a 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -34,18 +34,18 @@ class _ChatHomeState extends State { // TODO: implement initState super.initState(); data = Provider.of(context, listen: false); - data.getUserAutoLoginToken(context).then((Object? value) { + data.getUserAutoLoginToken(context).whenComplete(() { data.getUserRecentChats(); }); } @override void dispose() { + super.dispose(); data.clearAll(); if (data.hubConInitialized) { data.hubConnection.stop(); } - super.dispose(); } @override From 76169e5cb883f81e708ffcf46c18478723a06fd6 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 21 Nov 2022 09:53:27 +0300 Subject: [PATCH 5/7] Chat Updates & Counter Event Modifications --- lib/api/chat/chat_provider_model.dart | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 868aa7a..83827c3 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -87,11 +87,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { token: AppState().chatDetails!.response!.token, ); ChatUserModel favUList = userToList(favRes.body); - GetUserChatHistoryNotDeliveredAsync( - userId: int.parse( - AppState().chatDetails!.response!.id.toString(), - ), - ); + if (favUList.response != null && recentChat.response != null) { favUsersList = favUList.response!; favUsersList.sort( @@ -119,7 +115,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } - Future GetUserChatHistoryNotDeliveredAsync({required int userId}) async { + Future getUserChatHistoryNotDeliveredAsync({required int userId}) async { await hubConnection.invoke( "GetUserChatHistoryNotDeliveredAsync", args: [userId], @@ -157,7 +153,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ).reversed.toList(); } } - await GetUserChatHistoryNotDeliveredAsync( + await getUserChatHistoryNotDeliveredAsync( userId: senderUID, ); isLoading = false; @@ -274,6 +270,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { ); if (hubConnection.state != HubConnectionState.Connected) { await hubConnection.start(); + getUserChatHistoryNotDeliveredAsync( + userId: int.parse( + AppState().chatDetails!.response!.id.toString(), + ), + ); hubConnection.on("OnUpdateUserStatusAsync", changeStatus); hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); // hubConnection.on("OnSeenChatUserAsync", onChatSeen); @@ -565,14 +566,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } if (isFileSelected && !isMsgReply) { Utils.showLoading(context); - logger.d("Normal Attachment Message"); + //logger.d("Normal Attachment Message"); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); String? ext = getFileExtension(selectedFile.path); Utils.hideLoading(context); sendChatToServer(chatEventId: 2, fileTypeId: getFileType(ext.toString()), targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: true, chatReplyId: null, isReply: false); } if (!isFileSelected && isMsgReply) { - logger.d("Normal Text Message With Reply"); + // logger.d("Normal Text Message With Reply"); if (message.text == null || message.text.isEmpty) { return; } @@ -580,7 +581,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, chatReplyId: repliedMsg.first.userChatHistoryId, isAttachment: false, isReply: true); } if (isFileSelected && isMsgReply) { - logger.d("Attachment Message With Reply"); + // logger.d("Attachment Message With Reply"); Utils.showLoading(context); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); String? ext = getFileExtension(selectedFile.path); From 32ee7920412f618859eeb67da139bf7db3f30c9e Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 21 Nov 2022 09:54:14 +0300 Subject: [PATCH 6/7] Chat Updates & Counter Event Modifications --- lib/api/chat/chat_provider_model.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 83827c3..69f0fe5 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -573,7 +573,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { sendChatToServer(chatEventId: 2, fileTypeId: getFileType(ext.toString()), targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: true, chatReplyId: null, isReply: false); } if (!isFileSelected && isMsgReply) { - // logger.d("Normal Text Message With Reply"); + // logger.d("Normal Text Message With Reply"); if (message.text == null || message.text.isEmpty) { return; } @@ -581,7 +581,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, chatReplyId: repliedMsg.first.userChatHistoryId, isAttachment: false, isReply: true); } if (isFileSelected && isMsgReply) { - // logger.d("Attachment Message With Reply"); + // logger.d("Attachment Message With Reply"); Utils.showLoading(context); dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile); String? ext = getFileExtension(selectedFile.path); From ab5de25c8118690f266877b7819f3872f333f578 Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Mon, 21 Nov 2022 09:56:29 +0300 Subject: [PATCH 7/7] Chat Updates & Counter Event Modifications --- lib/api/chat/chat_provider_model.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/api/chat/chat_provider_model.dart b/lib/api/chat/chat_provider_model.dart index 69f0fe5..7a27c1f 100644 --- a/lib/api/chat/chat_provider_model.dart +++ b/lib/api/chat/chat_provider_model.dart @@ -43,7 +43,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future getUserAutoLoginToken(BuildContext cxt) async { Response response = await ApiClient().postJsonForResponse( "${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin", - {"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG"}, + { + "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), + "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", + }, ); login.UserAutoLoginModel userLoginResponse = login.userAutoLoginModelFromJson( response.body,