From 790103bdc91a97c7d93ef1d3026ff5f2a12a23e4 Mon Sep 17 00:00:00 2001 From: Sultan khan <> Date: Wed, 14 Jun 2023 14:46:36 +0300 Subject: [PATCH] chat changes --- assets/langs/ar-SA.json | 14 +- assets/langs/en-US.json | 17 +- lib/api/profile_api_client.dart | 2 +- lib/app_state/app_state.dart | 2 +- lib/classes/consts.dart | 4 +- lib/generated/codegen_loader.g.dart | 41 ++- lib/generated/locale_keys.g.dart | 13 + lib/models/chat/get_group_chat_history.dart | 8 +- lib/models/chat/target_users.dart | 32 +++ lib/provider/chat_provider_model.dart | 233 +++++++++++++++--- lib/ui/chat/create_group.dart | 32 +-- lib/ui/chat/group_chat.dart | 4 +- lib/ui/chat/group_chat_bubble.dart | 2 +- lib/ui/chat/group_chat_detaied_screen.dart | 36 ++- .../dynamic_screens/dynamic_input_screen.dart | 1 + 15 files changed, 357 insertions(+), 84 deletions(-) create mode 100644 lib/models/chat/target_users.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 02256c2..98a584e 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -535,5 +535,17 @@ "areYouSureWantTodelete": "هل أنت متأكد من أنك تريد الحذف؟", "groupMembers": "أعضاء المجموعة", "manageGroup": "إدارة المجموعة", - "admin": "مسؤل" + "admin": "مسؤل", + "addUsers": "أضف المستخدمين إلى المجموعة", + "editGroups": "تحرير المجموعة", + "groupNameshouldbe": "يجب ألا يقل اسم المجموعة عن 10 أحرف", + "groupName": "أسم المجموعة", + "enterGroupNamePlease": "الرجاء إدخال اسم المجموعة", + "audioCall": "مكالمة صوتية", + "videoCall": "مكالمة فيديو", + "shareScreen": "شاشة المشاركة", + "searchByUserName": "البحث باسم المستخدم", + "userSearch": "بحث المستخدم", + "userName":"اسم المستخدم", + "userId":"معرف المستخدم" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 0c674a3..81edd2d 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -534,5 +534,18 @@ "areYouSureWantTodelete": "Are you sure want to delete?", "groupMembers": "Group Members", "manageGroup": "Manage Group", - "admin": "Admin" -} \ No newline at end of file + "admin": "Admin", + "addUsers": "Add users to the group", + "editGroups":"Edit Group", + "groupNameshouldbe": "Group name should be minimum 10 character long", + "enterGroupName": "Please enter valid group Name", + "groupName": "Group Name", + "enterGroupNamePlease": "Please enter group name", + "audioCall": "Audio Call", + "videoCall": "Video Call", + "shareScreen": "Share Screen", + "searchByUserName": "Search By Username", + "userSearch": "User Search", + "userName": "User Name", + "userId": "UserID" +} diff --git a/lib/api/profile_api_client.dart b/lib/api/profile_api_client.dart index 6a8cfb0..2a5f049 100644 --- a/lib/api/profile_api_client.dart +++ b/lib/api/profile_api_client.dart @@ -166,7 +166,7 @@ class ProfileApiClient { ], "P_CONTACT_RELATIONSHIP_ID": contactRelationId, "P_ACTION": actionType, - "PayrollCodeStr": "CS", + "PayrollCodeStr": "HMG", "LegislationCodeStr": "SA", }; postParams.addAll(AppState().postParamsJson); diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 45ec0a4..b065816 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -90,7 +90,7 @@ class AppState { String get getHuaweiPushToken => _huaweiPushToken; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.6, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 33, versionID: 4.6, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 76d2fbd..3777c74 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA 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/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index dabf498..1f1a0c3 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -545,7 +545,25 @@ class CodegenLoader extends AssetLoader{ "group": "مجموعة", "searchGroup": "مجموعة البحث", "connectHmgWifi": "قم بتوصيل HMG WIFI", - "connectedHmgWifi": "اتصال HMG WIFI" + "connectedHmgWifi": "اتصال HMG WIFI", + "manage": "يدير", + "members": "أعضاء", + "areYouSureWantTodelete": "هل أنت متأكد من أنك تريد الحذف؟", + "groupMembers": "أعضاء المجموعة", + "manageGroup": "إدارة المجموعة", + "admin": "مسؤل", + "addUsers": "أضف المستخدمين إلى المجموعة", + "editGroups": "تحرير المجموعة", + "groupNameshouldbe": "يجب ألا يقل اسم المجموعة عن 10 أحرف", + "groupName": "أسم المجموعة", + "enterGroupNamePlease": "الرجاء إدخال اسم المجموعة", + "audioCall": "مكالمة صوتية", + "videoCall": "مكالمة فيديو", + "shareScreen": "شاشة المشاركة", + "searchByUserName": "البحث باسم المستخدم", + "userSearch": "بحث المستخدم", + "userName": "اسم المستخدم", + "userId": "معرف المستخدم" }; static const Map en_US = { "mohemm": "Mohemm", @@ -1077,7 +1095,26 @@ static const Map en_US = { "youCanPlayDemo": "But you can play demo", "group": "Groups", "searchGroup": "Search Group", - "connectHmgWifi": "Connect HMG WIFI" + "connectHmgWifi": "Connect HMG WIFI", + "manage": "Manage", + "members": "Members", + "areYouSureWantTodelete": "Are you sure want to delete?", + "groupMembers": "Group Members", + "manageGroup": "Manage Group", + "admin": "Admin", + "addUsers": "Add users to the group", + "editGroups": "Edit Group", + "groupNameshouldbe": "Group name should be minimum 10 character long", + "enterGroupName": "Please enter valid group Name", + "groupName": "Group Name", + "enterGroupNamePlease": "Please enter group name", + "audioCall": "Audio Call", + "videoCall": "Video Call", + "shareScreen": "Share Screen", + "searchByUserName": "Search By Username", + "userSearch": "User Search", + "userName": "User Name", + "userId": "UserID" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index b9ea8b3..e97a7e6 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -522,4 +522,17 @@ abstract class LocaleKeys { static const groupMembers = "groupMembers"; static const manageGroup = "manageGroup"; static const admin = "admin"; + static const addUsers ="addUsers"; + static const editGroups ="editGroups"; + static const groupNameshouldbe ="groupNameshouldbe"; + static const enterGroupName ="enterGroupName"; + static const groupName ="groupName"; + static const enterGroupNamePlease ="enterGroupNamePlease"; + static const audioCall = 'audioCall'; + static const videoCall ='videoCall'; + static const shareScreen ='shareScreen'; + static const searchByUserName ='searchByUserName'; + static const userSearch ='userSearch'; + static const userName ='userName'; + static const userId ='userId'; } diff --git a/lib/models/chat/get_group_chat_history.dart b/lib/models/chat/get_group_chat_history.dart index c0068e2..c8476b1 100644 --- a/lib/models/chat/get_group_chat_history.dart +++ b/lib/models/chat/get_group_chat_history.dart @@ -86,10 +86,10 @@ class GetGroupChatHistoryAsync { fileTypeResponse = json['fileTypeResponse'] != null ? new FileTypeResponse.fromJson(json['fileTypeResponse']) : null; - groupChatReplyResponse = json["userChatReplyResponse"] == null ? null : GroupChatReplyResponse.fromJson(json["userChatReplyResponse"]); + groupChatReplyResponse = json["groupChatReplyResponse"] == null ? null : GroupChatReplyResponse.fromJson(json["groupChatReplyResponse"]); isReplied= json['isReplied']; - isImageLoaded= json['isImageLoaded']; + isImageLoaded= json['isImageLoaded'] ??false; image= json['image']; voice= json['voice']; voiceController = json["fileTypeId"] == 13 ? AudioPlayer() : null; @@ -126,7 +126,7 @@ class GetGroupChatHistoryAsync { } data['isReplied'] =isReplied; - data['isImageLoaded'] = isImageLoaded; + data['isImageLoaded'] = isImageLoaded ?? false; data['image'] = image; data['voice'] = voice; data["fileTypeId"] == 13 ? AudioPlayer() : null; @@ -140,7 +140,7 @@ class GroupChatHistoryTargetUserList { bool? isDelivered; int? targetUserId; String? targetUserName; - Null? userAction; + dynamic? userAction; GroupChatHistoryTargetUserList( {this.groupChatHistoryLineId, diff --git a/lib/models/chat/target_users.dart b/lib/models/chat/target_users.dart new file mode 100644 index 0000000..d399a38 --- /dev/null +++ b/lib/models/chat/target_users.dart @@ -0,0 +1,32 @@ +class TargetUsers { + bool? isSeen; + bool? isDelivered; + int? targetUserId; + int? userAction; + int? userStatus; + + TargetUsers( + {this.isSeen, + this.isDelivered, + this.targetUserId, + this.userAction, + this.userStatus}); + + TargetUsers.fromJson(Map json) { + isSeen = json['isSeen']; + isDelivered = json['isDelivered']; + targetUserId = json['targetUserId']; + userAction = json['userAction']; + userStatus = json['userStatus']; + } + + Map toJson() { + Map data = new Map(); + data['isSeen'] = this.isSeen; + data['isDelivered'] = this.isDelivered; + data['targetUserId'] = this.targetUserId; + data['userAction'] = this.userAction; + data['userStatus'] = this.userStatus; + return data; + } +} diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index bb7dd63..824a19f 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -32,6 +32,7 @@ import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as userLoginToken; import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; +import 'package:mohem_flutter_app/models/chat/target_users.dart'; import 'package:mohem_flutter_app/models/my_team/get_employee_subordinates_list.dart'; import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart'; import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; @@ -89,7 +90,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { //Chat Home Page Counter int chatUConvCounter = 0; - late List groupChatHistory; + late List groupChatHistory, groupChatReplyData; /// Search Provider List? chatUsersList = []; @@ -121,6 +122,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); chatHubConnection.on("OnGetChatConversationCount", onNewChatConversion); + + //group On message + + chatHubConnection.on("OnDeliveredGroupChatHistoryAsync", onGroupMsgReceived); } Future getHubConnection() async { @@ -140,6 +145,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void registerEvents() { chatHubConnection.on("OnUpdateUserStatusAsync", changeStatus); // chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); + chatHubConnection.on("OnSubmitChatAsync", OnSubmitChatAsync); chatHubConnection.on("OnUserTypingAsync", onUserTyping); chatHubConnection.on("OnUserCountAsync", userCountAsync); @@ -148,6 +154,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { "OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); chatHubConnection.on( "OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); + chatHubConnection.on( + "OnGetGroupUserStatusAsync", getGroupUserStatus); + + // + // {"type":1,"target":"","arguments":[[{"id":217869,"userName":"Sultan.Khan","email":"Sultan.Khan@cloudsolutions.com.sa","phone":null,"title":"Sultan.Khan","userStatus":1,"image":null,"unreadMessageCount":0,"userAction":3,"isPin":false,"isFav":false,"isAdmin":false,"rKey":null,"totalCount":0,"isHuaweiDevice":false,"deviceToken":null},{"id":15153,"userName":"Tamer.Fanasheh","email":"Tamer.F@cloudsolutions.com.sa","phone":null,"title":"Tamer Fanasheh","userStatus":2,"image":null,"unreadMessageCount":0,"userAction":3,"isPin":false,"isFav":false,"isAdmin":true,"rKey":null,"totalCount":0,"isHuaweiDevice":false,"deviceToken":null}]]} if (kDebugMode) { logger.i("All listeners registered"); @@ -288,6 +299,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List.from( json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); + List getGroupChatHistoryAsync(String str) => + List.from( + json.decode(str).map((x) => groupchathistory.GetGroupChatHistoryAsync.fromJson(x))); + + Future uploadAttachments(String userId, File file) async { dynamic result; try { @@ -316,6 +332,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } + void getGroupUserStatus(List? args){ + //note: need to implement this function... + print(args); + } + void onChatSeen(List? args) { dynamic items = args!.toList(); // for (var user in searchedChats!) { @@ -495,6 +516,107 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } + Future onGroupMsgReceived(List? parameters) async { + List data = [], temp = []; + + + for (dynamic msg in parameters!) { + // groupChatHistory.add(groupchathistory.GetGroupChatHistoryAsync.fromJson(msg)); + data.add(groupchathistory.GetGroupChatHistoryAsync.fromJson(msg)); + temp =data; + // data.first.currentUserId = temp.first.currentUserId; + // data.first.currentUserName = temp.first.currentUserName; + // + // data.first.currentUserId = temp.first.currentUserId; + // data.first.currentUserName = temp.first.currentUserName; + + + if (data.first.fileTypeId == 12 || + data.first.fileTypeId == 4 || + data.first.fileTypeId == 3) { + data.first.image = await ChatApiClient().downloadURL( + fileName: data.first.contant!, + fileTypeDescription: + data.first.fileTypeResponse!.fileTypeDescription ?? + "image/jpg"); + } + if (data.first.groupChatReplyResponse != null) { + if (data.first.fileTypeResponse != null) { + if (data.first.groupChatReplyResponse!.fileTypeId == 12 || + data.first.groupChatReplyResponse!.fileTypeId == 4 || + data.first.groupChatReplyResponse!.fileTypeId == 3) { + data.first.groupChatReplyResponse!.image = await ChatApiClient() + .downloadURL( + fileName: data.first.groupChatReplyResponse!.contant!, + fileTypeDescription: + data.first.fileTypeResponse!.fileTypeDescription ?? + "image/jpg"); + data.first.groupChatReplyResponse!.isImageLoaded = true; + } + } + } + } + + // if (searchedChats != null) { + // dynamic contain = searchedChats! + // .where((ChatUser element) => element.id == data.first.currentUserId); + // if (contain.isEmpty) { + // List emails = []; + // emails.add(await EmailImageEncryption() + // .encrypt(val: data.first.currentUserEmail!)); + // List chatImages = + // await ChatApiClient().getUsersImages(encryptedEmails: emails); + // searchedChats!.add( + // ChatUser( + // id: data.first.currentUserId, + // userName: data.first.currentUserName, + // email: data.first.currentUserEmail, + // unreadMessageCount: 0, + // isImageLoading: false, + // image: chatImages!.first.profilePicture ?? "", + // isImageLoaded: true, + // userStatus: 1, + // isTyping: false, + // userLocalDownlaodedImage: await downloadImageLocal( + // chatImages.first.profilePicture, + // data.first.currentUserId.toString()), + // ), + // ); + // } + // } + groupChatHistory.insert(0, data.first); + setMsgTune(); + // if (isChatScreenActive && data.first.currentUserId == receiverID) { + + // } else { + // if (searchedChats != null) { + // for (ChatUser user in searchedChats!) { + // if (user.id == data.first.currentUserId) { + // int tempCount = user.unreadMessageCount ?? 0; + // user.unreadMessageCount = tempCount + 1; + // } + // } + sort(); + //} + //} + // + // List list = [ + // { + // "userChatHistoryId": data.first.groupId, + // "TargetUserId": temp.first.currentUserId, + // "isDelivered": true, + // "isSeen": isChatScreenActive && data.first.currentUserId == receiverID + // ? true + // : false + // } + // ]; + // updateUserChatHistoryOnMsg(list); + // invokeChatCounter(userId: AppState().chatDetails!.response!.id!); + notifyListeners(); + } + + + void OnSubmitChatAsync(List? parameters) { print(isChatScreenActive); print(receiverID); @@ -711,7 +833,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { String? userEmail, int? userStatus, File? voiceFile, - required bool isVoiceAttached}) async { + required bool isVoiceAttached, + required List userList + }) async { Uuid uuid = const Uuid(); String contentNo = uuid.v4(); String msg; @@ -736,15 +860,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { groupName: targetUserName, isReplied: false, fileTypeId: fileTypeId, - // userChatReplyResponse: isReply ? UserChatReplyResponse.fromJson(repliedMsg.first.toJson()) : null, - // fileTypeResponse: isAttachment - // ? FileTypeResponse( - // fileTypeId: fileTypeId, - // fileTypeName: isVoiceMsg ? getFileExtension(voiceFile!.path).toString() : getFileExtension(selectedFile.path).toString(), - // fileKind: "file", - // fileName: isVoiceMsg ? msg : selectedFile.path.split("/").last, - // fileTypeDescription: isVoiceMsg ? getFileTypeDescription(getFileExtension(voiceFile!.path).toString()) : getFileTypeDescription(getFileExtension(selectedFile.path).toString()), - + fileTypeResponse: isAttachment + ? groupchathistory.FileTypeResponse( + fileTypeId: fileTypeId, + fileTypeName: isVoiceMsg ? getFileExtension(voiceFile!.path).toString() : getFileExtension(selectedFile.path).toString(), + fileKind: "file", + fileName: isVoiceMsg ? msg : selectedFile.path.split("/").last, + fileTypeDescription: isVoiceMsg ? getFileTypeDescription(getFileExtension(voiceFile!.path).toString()) : getFileTypeDescription(getFileExtension(selectedFile.path).toString())) : null, image: image, isImageLoaded: isImageLoaded, voice: isVoiceMsg ? voiceFile! : null, @@ -752,7 +874,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { if (kDebugMode) { logger.i("model data: " + jsonEncode(data)); } - // groupChatHistory.insert(0, data); + groupChatHistory.insert(0, data); isTextMsg = false; isReplyMsg = false; isAttachmentMsg = false; @@ -761,11 +883,15 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { message.clear(); notifyListeners(); - String chatData = - '{"contant":"$msg","contantNo":"$contentNo","chatEventId":$chatEventId,"fileTypeId":$fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"groupId":$targetGroupId,"groupChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":${AppState().chatDetails!.response!.id},"userAction":0,"userStatus":1}],"conversationId":"${uuid.v4()}"}'; + List targetUsers =[]; + + for (GroupUserList element in userList) { + targetUsers.add(TargetUsers(isDelivered: false,isSeen: false, targetUserId: element.id, userAction: element.userAction, userStatus: element.userStatus)); + + } - // String chatData = - // '{"contant":"$msg","contantNo":"$contentNo","chatEventId":$chatEventId,"fileTypeId": $fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"userChatHistoryLineRequestList":[{"isSeen":false,"isDelivered":false,"targetUserId":$targetUserId,"targetUserStatus":1}],"chatReplyId":$chatReplyId,"conversationId":"$chatCID"}'; + String chatData = + '{"contant":"$msg","contantNo":"$contentNo","chatEventId":$chatEventId,"fileTypeId":$fileTypeId,"currentUserId":${AppState().chatDetails!.response!.id},"chatSource":1,"groupId":$targetGroupId,"groupChatHistoryLineRequestList":${json.encode(targetUsers)},"chatReplyId": $chatReplyId,"conversationId":"${uuid.v4()}"}'; await chatHubConnection.invoke("AddGroupChatHistoryAsync", args: [json.decode(chatData)]); @@ -775,7 +901,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { {required int targetUserId, required int userStatus, required String userEmail, - required String targetUserName}) async { + required String targetUserName, + required List userList, + }) async { if (isTextMsg && !isAttachmentMsg && !isVoiceMsg && !isReplyMsg) { logger.d("// Normal Text Message"); if (message.text.isEmpty) { @@ -793,7 +921,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { image: null, isVoiceAttached: false, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); } else if (isTextMsg && !isAttachmentMsg && !isVoiceMsg && isReplyMsg) { logger.d("// Text Message as Reply"); if (message.text.isEmpty) { @@ -804,15 +934,17 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { fileTypeId: null, targetGroupId: targetUserId, targetUserName: targetUserName, - chatReplyId: repliedMsg.first.userChatHistoryId, + chatReplyId: groupChatReplyData.first.groupChatHistoryId, isAttachment: false, isReply: true, - isImageLoaded: repliedMsg.first.isImageLoaded!, - image: repliedMsg.first.image, + isImageLoaded: groupChatReplyData.first.isImageLoaded!, + image: groupChatReplyData.first.image, isVoiceAttached: false, voiceFile: null, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); } // Attachment else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && !isReplyMsg) { @@ -820,12 +952,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Utils.showLoading(context); dynamic value = await uploadAttachments( AppState().chatDetails!.response!.id.toString(), selectedFile); - // String? ext = getFileExtension(selectedFile.path); + String? ext = getFileExtension(selectedFile.path); Utils.hideLoading(context); sendGroupChatToServer( chatEventId: 2, - fileTypeId: "jpg", - //getFileType(ext.toString()), + fileTypeId: getFileType(ext.toString()), targetGroupId: targetUserId, targetUserName: targetUserName, isAttachment: true, @@ -835,18 +966,20 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { image: selectedFile.readAsBytesSync(), isVoiceAttached: false, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); } else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && isReplyMsg) { logger.d("// Image as Reply Msg"); Utils.showLoading(context); dynamic value = await uploadAttachments( AppState().chatDetails!.response!.id.toString(), selectedFile); - // String? ext = getFileExtension(selectedFile.path); + String? ext = getFileExtension(selectedFile.path); Utils.hideLoading(context); sendGroupChatToServer( chatEventId: 2, - fileTypeId: "jpg", - //getFileType(ext.toString()), + fileTypeId: getFileType(ext.toString()), + targetGroupId: targetUserId, targetUserName: targetUserName, isAttachment: true, @@ -856,7 +989,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { image: selectedFile.readAsBytesSync(), isVoiceAttached: false, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); } //Voice @@ -878,12 +1013,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Utils.showLoading(context); dynamic value = await uploadAttachments( AppState().chatDetails!.response!.id.toString(), voiceFile); - // String? ext = getFileExtension(voiceFile.path); + String? ext = getFileExtension(voiceFile.path); Utils.hideLoading(context); sendGroupChatToServer( chatEventId: 2, - fileTypeId: "jpg", - //getFileType(ext.toString()), + fileTypeId: getFileType(ext.toString()), + //, targetGroupId: targetUserId, targetUserName: targetUserName, chatReplyId: null, @@ -893,7 +1028,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { voiceFile: voiceFile, isVoiceAttached: true, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); notifyListeners(); } else if (!isTextMsg && !isAttachmentMsg && isVoiceMsg && isReplyMsg) { logger.d("// Voice as Reply Msg"); @@ -914,12 +1051,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Utils.showLoading(context); dynamic value = await uploadAttachments( AppState().chatDetails!.response!.id.toString(), voiceFile); - // String? ext = getFileExtension(voiceFile.path); + String? ext = getFileExtension(voiceFile.path); Utils.hideLoading(context); sendGroupChatToServer( chatEventId: 2, - fileTypeId: "jpg", - //getFileType(ext.toString()), + fileTypeId: getFileType(ext.toString()), targetGroupId: targetUserId, targetUserName: targetUserName, chatReplyId: null, @@ -929,7 +1065,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { voiceFile: voiceFile, isVoiceAttached: true, userEmail: userEmail, - userStatus: userStatus); + userStatus: userStatus, + userList:userList + ); notifyListeners(); } if (searchedChats != null) { @@ -964,7 +1102,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { {required int targetUserId, required int userStatus, required String userEmail, - required String targetUserName}) async { + required String targetUserName, + + }) async { if (kDebugMode) { print("====================== Values ============================"); print("Is Text " + isTextMsg.toString()); @@ -1266,7 +1406,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { repliedMsg.add(data); notifyListeners(); } - + void groupChatReply(groupchathistory.GetGroupChatHistoryAsync data) { + groupChatReplyData = []; + data.isReplied = true; + isReplyMsg = true; + groupChatReplyData.add(data); + notifyListeners(); + } void closeMe() { repliedMsg = []; isReplyMsg = false; @@ -1551,6 +1697,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { await chatHubConnection .invoke("UserTypingAsync", args: [reciptUser, currentUser]); } + void groupTypingInvoke( + {required GroupResponse groupDetails, required int groupId}) async { + var data = json.decode(json.encode(groupDetails.groupUserList)); + await chatHubConnection + .invoke("GroupTypingAsync", args: ["${groupDetails.adminUser!.userName}",data, groupId ]); + } + //////// Audio Recoding Work //////////////////// diff --git a/lib/ui/chat/create_group.dart b/lib/ui/chat/create_group.dart index 32efe79..43b2635 100644 --- a/lib/ui/chat/create_group.dart +++ b/lib/ui/chat/create_group.dart @@ -186,8 +186,8 @@ class _CreateGroupBottomSheetState extends State { Row( children: [ DynamicTextFieldWidget( - "Group Name", - groupName.isEmpty ? "Please enter group name" : groupName, + LocaleKeys.groupName.tr(), + groupName.isEmpty ? LocaleKeys.enterGroupNamePlease.tr() : groupName, inputAction: TextInputAction.done, onChange: (String text) { groupName = text; @@ -204,7 +204,7 @@ class _CreateGroupBottomSheetState extends State { height: 35, child: CheckboxListTile( contentPadding: EdgeInsets.zero, - title: "Audio Call".toText10(), + title: LocaleKeys.audioCall.tr().toText10(), checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), @@ -225,7 +225,7 @@ class _CreateGroupBottomSheetState extends State { height: 35, child: CheckboxListTile( contentPadding: EdgeInsets.zero, - title: "Video Call".toText10(), + title: LocaleKeys.videoCall.tr().toText10(), checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), value: isVideoCall, @@ -245,7 +245,7 @@ class _CreateGroupBottomSheetState extends State { height: 35, child: CheckboxListTile( contentPadding: EdgeInsets.zero, - title: "Attachments".toText10(), + title:LocaleKeys.attachments.tr().toText10(), checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), value: isAttachments, @@ -263,7 +263,7 @@ class _CreateGroupBottomSheetState extends State { contentPadding: EdgeInsets.zero, checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), - title: "Share Screen".toText10(), + title:LocaleKeys.shareScreen.tr().toText10(), value: isShareScreen, onChanged: (bool? newValue) { setState(() { @@ -276,22 +276,22 @@ class _CreateGroupBottomSheetState extends State { ], ), 11.height, - "User Search".toText16(), + LocaleKeys.userSearch.tr().toText16(), 11.height, Row( children: [ - radioOption(widget.fromChat ? "UserId" : "Name", 0, + radioOption(widget.fromChat ? LocaleKeys.userId.tr() : LocaleKeys.name.tr(), 0, _selectedSearchIndex), - radioOption("User Name", 1, _selectedSearchIndex), - radioOption("Email", 2, _selectedSearchIndex), + radioOption(LocaleKeys.userName.tr(), 1, _selectedSearchIndex), + radioOption(LocaleKeys.email.tr(), 2, _selectedSearchIndex), ], ), 14.height, Row( children: [ DynamicTextFieldWidget( - "Search", - "Search By Username", + LocaleKeys.search.tr(), + LocaleKeys.searchByUserName.tr(), inputAction: TextInputAction.done, suffixIconData: Icons.search, onChange: (String text) { @@ -302,6 +302,8 @@ class _CreateGroupBottomSheetState extends State { IconButton( constraints: const BoxConstraints(), onPressed: () async { + provider.chatUsersList!.clear(); + provider.pageNo =1; await SystemChannels.textInput .invokeMethod('TextInput.hide'); widget.fromChat ? fetchChatUser() : fetchUserByInput(); @@ -318,7 +320,7 @@ class _CreateGroupBottomSheetState extends State { padding: EdgeInsets.only(top: 21, bottom: 8), children: [ if (favouriteUserList?.isNotEmpty ?? false) ...[ - "Favorites".toText16(), + LocaleKeys.favorite.tr().toText16(), 12.height, ListView.separated( physics: const NeverScrollableScrollPhysics(), @@ -662,9 +664,9 @@ class _CreateGroupBottomSheetState extends State { void createGroup() async { RegExp validCharacters = RegExp(r'^[a-zA-Z0-9_\-=@,\.;]+$'); if (!validCharacters.hasMatch(groupName)) { - Utils.showToast("Please enter valid group Name"); + Utils.showToast(LocaleKeys.enterGroupName.tr()); } else if (groupName.length < 10) { - Utils.showToast("Group name should be minimum 10 character long"); + Utils.showToast(LocaleKeys.groupNameshouldbe.tr()); } else { List? mainUsers = []; ChatUser admin = diff --git a/lib/ui/chat/group_chat.dart b/lib/ui/chat/group_chat.dart index 6ba690d..35b4c5c 100644 --- a/lib/ui/chat/group_chat.dart +++ b/lib/ui/chat/group_chat.dart @@ -223,7 +223,7 @@ class _GropChatHomeScreenState extends State { context, callBackFunc: () {}, child: CreateGroupBottomSheet( - title:"Add users to the group", + title:LocaleKeys.addUsers.tr(), apiMode: LocaleKeys.delegate.tr(), fromChat: true, onSelectEmployee: (ReplacementList _selectedEmployee) {}, @@ -295,7 +295,7 @@ void goToSelected(GroupResponse? groupDetails, ChatProviderModel m, String value context, callBackFunc: () {}, child: CreateGroupBottomSheet( - title:"Edit Group", + title:LocaleKeys.editGroups.tr(), apiMode: LocaleKeys.delegate.tr(), fromChat: true, onSelectEmployee: (ReplacementList _selectedEmployee) {}, diff --git a/lib/ui/chat/group_chat_bubble.dart b/lib/ui/chat/group_chat_bubble.dart index 80e6606..69a50df 100644 --- a/lib/ui/chat/group_chat_bubble.dart +++ b/lib/ui/chat/group_chat_bubble.dart @@ -481,7 +481,7 @@ class GroupChatBubble extends StatelessWidget { {required bool isReplyPreview, required String fileName, required String fileTypeDescription}) { - if (cItem.isImageLoaded! && cItem.image != null) { + if (cItem.isImageLoaded != null && cItem.image != null) { return Image.memory( cItem.image!, height: isReplyPreview ? 32 : 140, diff --git a/lib/ui/chat/group_chat_detaied_screen.dart b/lib/ui/chat/group_chat_detaied_screen.dart index cd1fb49..c43a2df 100644 --- a/lib/ui/chat/group_chat_detaied_screen.dart +++ b/lib/ui/chat/group_chat_detaied_screen.dart @@ -148,9 +148,9 @@ class _GroupChatDetailScreenState extends State { cItem: m.groupChatHistory[i], ), onRightSwipe: () { - // m.chatReply( - // m.groupChatHistory[i], - // ); + m.groupChatReply( + m.groupChatHistory[i], + ); }, ).onPress(() async { logger.w(m.userChatHistory[i].toJson()); @@ -184,15 +184,15 @@ class _GroupChatDetailScreenState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString() + (AppState().chatDetails!.response!.userName == m.groupChatReplyData.first.currentUserName.toString() ? "You" - : m.repliedMsg.first.currentUserName.toString().replaceAll(".", " ")) + : m.groupChatReplyData.first.currentUserName.toString().replaceAll(".", " ")) .toText14(color: MyColors.lightGreenColor), - (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(color: MyColors.grey71Color, maxLine: 2) + (m.groupChatReplyData.isNotEmpty ? m.groupChatReplyData.first.contant! : "").toText12(color: MyColors.grey71Color, maxLine: 2) ], ).expanded, 12.width, - if (m.isReplyMsg && m.repliedMsg.isNotEmpty) showReplyImage(m.repliedMsg, m), + if (m.isReplyMsg && m.groupChatReplyData.isNotEmpty) showReplyImage(m.groupChatReplyData, m), 12.width, const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe), ], @@ -249,11 +249,13 @@ class _GroupChatDetailScreenState extends State { }), SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26) .onPress( - () => m.sendChatMessage(context, + () => m.sendGroupChatMessage(context, targetUserId: params!.groupChatDetails!.groupId!, userStatus: 0, userEmail: "", - targetUserName: params!.groupChatDetails!.groupName!), + targetUserName: params!.groupChatDetails!.groupName!, + userList: params!.groupChatDetails!.groupUserList! + ), ) .paddingOnly(right: 21), ], @@ -292,7 +294,7 @@ class _GroupChatDetailScreenState extends State { ), onChanged: (String val) { m.inputBoxDirection(val); - m.userTypingInvoke(currentUser: AppState().chatDetails!.response!.id!, reciptUser: params!.groupChatDetails!.groupId!); + m.groupTypingInvoke(groupDetails: params!.groupChatDetails!, groupId: params!.groupChatDetails!.groupId!); }, ).expanded, ), @@ -307,7 +309,9 @@ class _GroupChatDetailScreenState extends State { RotationTransition( turns: const AlwaysStoppedAnimation(45 / 360), child: const Icon(Icons.attach_file_rounded, size: 26, color: MyColors.grey3AColor).onPress( - () => m.selectImageToUpload(context), + () => { + m.selectImageToUpload(context) + }, ), ).paddingOnly(right: 15), const Icon( @@ -322,7 +326,9 @@ class _GroupChatDetailScreenState extends State { targetUserId: params!.groupChatDetails!.groupId!, userStatus: 0, userEmail: "", - targetUserName: params!.groupChatDetails!.groupName!), + targetUserName: params!.groupChatDetails!.groupName!, + userList: params!.groupChatDetails!.groupUserList! + ), ) .paddingOnly(right: 21), ], @@ -335,7 +341,7 @@ class _GroupChatDetailScreenState extends State { ); } - Widget showReplyImage(List data, ChatProviderModel m) { + Widget showReplyImage(List data, ChatProviderModel m) { if (data.first.isImageLoaded! && data.first.image != null) { return Container( width: 43, @@ -381,4 +387,8 @@ class _GroupChatDetailScreenState extends State { // callPro.stopListeners(); // }); } + GroupUserList getCurrentUser(int id, GroupResponse groupChatDetails) { + return groupChatDetails.groupUserList!.firstWhere((GroupUserList item) => item.id ==id); + } + } diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart index bd9305d..a6ffcf1 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -344,6 +344,7 @@ class _DynamicInputScreenState extends State { // commenting to test // DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!); // idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date); + } }