|  |  |  | import 'dart:async'; | 
					
						
							|  |  |  | import 'dart:convert'; | 
					
						
							|  |  |  | import 'dart:io'; | 
					
						
							|  |  |  | import 'dart:typed_data'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import 'package:audio_waveforms/audio_waveforms.dart'; | 
					
						
							|  |  |  | import 'package:easy_localization/easy_localization.dart'; | 
					
						
							|  |  |  | import 'package:flutter/cupertino.dart'; | 
					
						
							|  |  |  | import 'package:flutter/foundation.dart'; | 
					
						
							|  |  |  | import 'package:flutter/services.dart'; | 
					
						
							|  |  |  | import 'package:http/http.dart'; | 
					
						
							|  |  |  | import 'package:just_audio/just_audio.dart' as JustAudio; | 
					
						
							|  |  |  | import 'package:just_audio/just_audio.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/api/chat/chat_api_client.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/api/my_team/my_team_api_client.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/app_state/app_state.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/classes/consts.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/classes/encryption.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/classes/utils.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/main.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/models/chat/chat_user_image_model.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as userLoginToken; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/models/my_team/get_employee_subordinates_list.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/widgets/image_picker.dart'; | 
					
						
							|  |  |  | import 'package:open_file/open_file.dart'; | 
					
						
							|  |  |  | import 'package:path_provider/path_provider.dart'; | 
					
						
							|  |  |  | import 'package:permission_handler/permission_handler.dart'; | 
					
						
							|  |  |  | import 'package:signalr_netcore/hub_connection.dart'; | 
					
						
							|  |  |  | import 'package:signalr_netcore/signalr_client.dart'; | 
					
						
							|  |  |  | import 'package:uuid/uuid.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { | 
					
						
							|  |  |  |   ScrollController scrollController = ScrollController(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   TextEditingController message = TextEditingController(); | 
					
						
							|  |  |  |   TextEditingController search = TextEditingController(); | 
					
						
							|  |  |  |   List<SingleUserChatModel> userChatHistory = [], repliedMsg = []; | 
					
						
							|  |  |  |   List<ChatUser>? pChatHistory, searchedChats; | 
					
						
							|  |  |  |   String chatCID = ''; | 
					
						
							|  |  |  |   bool isLoading = true; | 
					
						
							|  |  |  |   bool isChatScreenActive = false; | 
					
						
							|  |  |  |   int receiverID = 0; | 
					
						
							|  |  |  |   late File selectedFile; | 
					
						
							|  |  |  |   String sFileType = ""; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   List<ChatUser> favUsersList = []; | 
					
						
							|  |  |  |   int paginationVal = 0; | 
					
						
							|  |  |  |   int? cTypingUserId = 0; | 
					
						
							|  |  |  |   bool isTextMsg = false, isReplyMsg = false, isAttachmentMsg = false, isVoiceMsg = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Audio Recoding Work
 | 
					
						
							|  |  |  |   Timer? _timer; | 
					
						
							|  |  |  |   int _recodeDuration = 0; | 
					
						
							|  |  |  |   bool isRecoding = false; | 
					
						
							|  |  |  |   bool isPause = false; | 
					
						
							|  |  |  |   bool isPlaying = false; | 
					
						
							|  |  |  |   String? path; | 
					
						
							|  |  |  |   String? musicFile; | 
					
						
							|  |  |  |   late Directory appDirectory; | 
					
						
							|  |  |  |   late RecorderController recorderController; | 
					
						
							|  |  |  |   late PlayerController playerController; | 
					
						
							|  |  |  |   List<GetEmployeeSubordinatesList> getEmployeeSubordinatesList = []; | 
					
						
							|  |  |  |   List<ChatUser> teamMembersList = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //Chat Home Page Counter
 | 
					
						
							|  |  |  |   int chatUConvCounter = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> getUserAutoLoginToken() async { | 
					
						
							|  |  |  |     userLoginToken.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken(); | 
					
						
							|  |  |  |     if (userLoginResponse.response != null) { | 
					
						
							|  |  |  |       AppState().setchatUserDetails = userLoginResponse; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       AppState().setchatUserDetails = userLoginResponse; | 
					
						
							|  |  |  |       Utils.showToast( | 
					
						
							|  |  |  |         userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr", | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> buildHubConnection() async { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     chatHubConnection = await getHubConnection(); | 
					
						
							|  |  |  |     await chatHubConnection.start(); | 
					
						
							|  |  |  |     if (kDebugMode) { | 
					
						
							|  |  |  |       logger.i("Hub Conn: Startedddddddd"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived); | 
					
						
							|  |  |  |     chatHubConnection.on("OnGetChatConversationCount", onNewChatConversion); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<HubConnection> getHubConnection() async { | 
					
						
							|  |  |  |     HubConnection hub; | 
					
						
							|  |  |  |     HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); | 
					
						
							|  |  |  |     hub = HubConnectionBuilder() | 
					
						
							|  |  |  |         .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp) | 
					
						
							|  |  |  |         .withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build(); | 
					
						
							|  |  |  |     return hub; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void registerEvents() { | 
					
						
							|  |  |  |     chatHubConnection.on("OnUpdateUserStatusAsync", changeStatus); | 
					
						
							|  |  |  |     //   chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
 | 
					
						
							|  |  |  |     chatHubConnection.on("OnSubmitChatAsync", OnSubmitChatAsync); | 
					
						
							|  |  |  |     chatHubConnection.on("OnUserTypingAsync", onUserTyping); | 
					
						
							|  |  |  |     chatHubConnection.on("OnUserCountAsync", userCountAsync); | 
					
						
							|  |  |  |     //  chatHubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
 | 
					
						
							|  |  |  |     chatHubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered); | 
					
						
							|  |  |  |     chatHubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus); | 
					
						
							|  |  |  |     if (kDebugMode) { | 
					
						
							|  |  |  |       logger.i("All listeners registered"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void getUserRecentChats() async { | 
					
						
							|  |  |  |     if (chatHubConnection.state != HubConnectionState.Connected) { | 
					
						
							|  |  |  |       getUserAutoLoginToken().whenComplete(() async { | 
					
						
							|  |  |  |         await buildHubConnection(); | 
					
						
							|  |  |  |         getUserRecentChats(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ChatUserModel recentChat = await ChatApiClient().getRecentChats(); | 
					
						
							|  |  |  |     ChatUserModel favUList = await ChatApiClient().getFavUsers(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (favUList.response != null && recentChat.response != null) { | 
					
						
							|  |  |  |       favUsersList = favUList.response!; | 
					
						
							|  |  |  |       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) { | 
					
						
							|  |  |  |             user.isFav = favUser.isFav; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     pChatHistory = recentChat.response ?? []; | 
					
						
							|  |  |  |     pChatHistory!.sort( | 
					
						
							|  |  |  |       (ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase()), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |     searchedChats = pChatHistory; | 
					
						
							|  |  |  |     isLoading = false; | 
					
						
							|  |  |  |     await invokeUserChatHistoryNotDeliveredAsync( | 
					
						
							|  |  |  |       userId: int.parse( | 
					
						
							|  |  |  |         AppState().chatDetails!.response!.id.toString(), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |     sort(); | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |     if (searchedChats!.isNotEmpty || favUsersList.isNotEmpty) { | 
					
						
							|  |  |  |       getUserImages(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future invokeUserChatHistoryNotDeliveredAsync({required int userId}) async { | 
					
						
							|  |  |  |     await chatHubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]); | 
					
						
							|  |  |  |     return ""; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false}) async { | 
					
						
							|  |  |  |     isLoading = true; | 
					
						
							|  |  |  |     if (isNewChat) userChatHistory = []; | 
					
						
							|  |  |  |     if (!loadMore) paginationVal = 0; | 
					
						
							|  |  |  |     isChatScreenActive = true; | 
					
						
							|  |  |  |     receiverID = receiverUID; | 
					
						
							|  |  |  |     Response response = await ChatApiClient().getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore, paginationVal: paginationVal); | 
					
						
							|  |  |  |     if (response.statusCode == 204) { | 
					
						
							|  |  |  |       if (isNewChat) { | 
					
						
							|  |  |  |         userChatHistory = []; | 
					
						
							|  |  |  |       } else if (loadMore) { | 
					
						
							|  |  |  |         Utils.showToast("No More Data To Load"); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       if (loadMore) { | 
					
						
							|  |  |  |         List<SingleUserChatModel> temp = getSingleUserChatModel(response.body).reversed.toList(); | 
					
						
							|  |  |  |         userChatHistory.addAll(temp); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         userChatHistory = getSingleUserChatModel(response.body).reversed.toList(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     isLoading = false; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (isChatScreenActive && receiverUID == receiverID) { | 
					
						
							|  |  |  |       markRead(userChatHistory, receiverUID); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     generateConvId(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void generateConvId() async { | 
					
						
							|  |  |  |     Uuid uuid = const Uuid(); | 
					
						
							|  |  |  |     chatCID = uuid.v4(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void markRead(List<SingleUserChatModel> data, int receiverID) { | 
					
						
							|  |  |  |     for (SingleUserChatModel element in data!) { | 
					
						
							|  |  |  |       if (AppState().chatDetails!.response!.id! == element.targetUserId) { | 
					
						
							|  |  |  |         if (element.isSeen != null) { | 
					
						
							|  |  |  |           if (!element.isSeen!) { | 
					
						
							|  |  |  |             element.isSeen = true; | 
					
						
							|  |  |  |             dynamic data = [ | 
					
						
							|  |  |  |               { | 
					
						
							|  |  |  |                 "userChatHistoryId": element.userChatHistoryId, | 
					
						
							|  |  |  |                 "TargetUserId": element.currentUserId == receiverID ? element.currentUserId : element.targetUserId, | 
					
						
							|  |  |  |                 "isDelivered": true, | 
					
						
							|  |  |  |                 "isSeen": true, | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             ]; | 
					
						
							|  |  |  |             updateUserChatHistoryStatusAsync(data); | 
					
						
							|  |  |  |             notifyListeners(); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         for (ChatUser element in searchedChats!) { | 
					
						
							|  |  |  |           if (element.id == receiverID) { | 
					
						
							|  |  |  |             element.unreadMessageCount = 0; | 
					
						
							|  |  |  |             chatUConvCounter = 0; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void updateUserChatHistoryStatusAsync(List data) { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       chatHubConnection.invoke("UpdateUserChatHistoryStatusAsync", args: [data]); | 
					
						
							|  |  |  |     } catch (e) { | 
					
						
							|  |  |  |       throw e; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void updateUserChatHistoryOnMsg(List data) { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       chatHubConnection.invoke("UpdateUserChatHistoryStatusAsync", args: [data]); | 
					
						
							|  |  |  |     } catch (e) { | 
					
						
							|  |  |  |       throw e; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   List<SingleUserChatModel> getSingleUserChatModel(String str) => List<SingleUserChatModel>.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<dynamic> uploadAttachments(String userId, File file) async { | 
					
						
							|  |  |  |     dynamic result; | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       Object? response = await ChatApiClient().uploadMedia(userId, file); | 
					
						
							|  |  |  |       if (response != null) { | 
					
						
							|  |  |  |         result = response; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         result = []; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } catch (e) { | 
					
						
							|  |  |  |       throw e; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void updateUserChatStatus(List<Object?>? args) { | 
					
						
							|  |  |  |     dynamic items = args!.toList(); | 
					
						
							|  |  |  |     for (var cItem in items[0]) { | 
					
						
							|  |  |  |       for (SingleUserChatModel chat in userChatHistory) { | 
					
						
							|  |  |  |         if (cItem["contantNo"].toString() == chat.contantNo.toString()) { | 
					
						
							|  |  |  |           chat.isSeen = cItem["isSeen"]; | 
					
						
							|  |  |  |           chat.isDelivered = cItem["isDelivered"]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void onChatSeen(List<Object?>? args) { | 
					
						
							|  |  |  |     dynamic items = args!.toList(); | 
					
						
							|  |  |  |     // for (var user in searchedChats!) {
 | 
					
						
							|  |  |  |     //   if (user.id == items.first["id"]) {
 | 
					
						
							|  |  |  |     //     user.userStatus = items.first["userStatus"];
 | 
					
						
							|  |  |  |     //   }
 | 
					
						
							|  |  |  |     // }
 | 
					
						
							|  |  |  |     // notifyListeners();
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void userCountAsync(List<Object?>? args) { | 
					
						
							|  |  |  |     dynamic items = args!.toList(); | 
					
						
							|  |  |  |     // logger.d(items);
 | 
					
						
							|  |  |  |     //logger.d("---------------------------------User Count Async -------------------------------------");
 | 
					
						
							|  |  |  |     //logger.d(items);
 | 
					
						
							|  |  |  |     // for (var user in searchedChats!) {
 | 
					
						
							|  |  |  |     //   if (user.id == items.first["id"]) {
 | 
					
						
							|  |  |  |     //     user.userStatus = items.first["userStatus"];
 | 
					
						
							|  |  |  |     //   }
 | 
					
						
							|  |  |  |     // }
 | 
					
						
							|  |  |  |     // notifyListeners();
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void updateChatHistoryWindow(List<Object?>? args) { | 
					
						
							|  |  |  |     dynamic items = args!.toList(); | 
					
						
							|  |  |  |     if (kDebugMode) { | 
					
						
							|  |  |  |       logger.i("---------------------------------Update Chat History Windows  Async -------------------------------------"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     logger.d(items); | 
					
						
							|  |  |  |     // for (var user in searchedChats!) {
 | 
					
						
							|  |  |  |     //   if (user.id == items.first["id"]) {
 | 
					
						
							|  |  |  |     //     user.userStatus = items.first["userStatus"];
 | 
					
						
							|  |  |  |     //   }
 | 
					
						
							|  |  |  |     // }
 | 
					
						
							|  |  |  |     // notifyListeners();
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void chatNotDelivered(List<Object?>? args) { | 
					
						
							|  |  |  |     dynamic items = args!.toList(); | 
					
						
							|  |  |  |     for (dynamic item in items[0]) { | 
					
						
							|  |  |  |       for (ChatUser element in searchedChats!) { | 
					
						
							|  |  |  |         if (element.id == item["currentUserId"]) { | 
					
						
							|  |  |  |           int? val = element.unreadMessageCount ?? 0; | 
					
						
							|  |  |  |           element.unreadMessageCount = val! + 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void changeStatus(List<Object?>? args) { | 
					
						
							|  |  |  |     dynamic items = args!.toList(); | 
					
						
							|  |  |  |     for (ChatUser user in searchedChats!) { | 
					
						
							|  |  |  |       if (user.id == items.first["id"]) { | 
					
						
							|  |  |  |         user.userStatus = items.first["userStatus"]; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (teamMembersList != null) { | 
					
						
							|  |  |  |       if (teamMembersList.isNotEmpty) { | 
					
						
							|  |  |  |         for (ChatUser user in teamMembersList!) { | 
					
						
							|  |  |  |           if (user.id == items.first["id"]) { | 
					
						
							|  |  |  |             user.userStatus = items.first["userStatus"]; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void filter(String value) async { | 
					
						
							|  |  |  |     List<ChatUser>? tmp = []; | 
					
						
							|  |  |  |     if (value.isEmpty || value == "") { | 
					
						
							|  |  |  |       tmp = pChatHistory; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       for (ChatUser element in pChatHistory!) { | 
					
						
							|  |  |  |         if (element.userName!.toLowerCase().contains(value.toLowerCase())) { | 
					
						
							|  |  |  |           tmp.add(element); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     searchedChats = tmp; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> onMsgReceived(List<Object?>? parameters) async { | 
					
						
							|  |  |  |     List<SingleUserChatModel> data = [], temp = []; | 
					
						
							|  |  |  |     for (dynamic msg in parameters!) { | 
					
						
							|  |  |  |       data = getSingleUserChatModel(jsonEncode(msg)); | 
					
						
							|  |  |  |       temp = getSingleUserChatModel(jsonEncode(msg)); | 
					
						
							|  |  |  |       data.first.targetUserId = temp.first.currentUserId; | 
					
						
							|  |  |  |       data.first.targetUserName = temp.first.currentUserName; | 
					
						
							|  |  |  |       data.first.targetUserEmail = temp.first.currentUserEmail; | 
					
						
							|  |  |  |       data.first.currentUserId = temp.first.targetUserId; | 
					
						
							|  |  |  |       data.first.currentUserName = temp.first.targetUserName; | 
					
						
							|  |  |  |       data.first.currentUserEmail = temp.first.targetUserEmail; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       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.userChatReplyResponse != null) { | 
					
						
							|  |  |  |         if (data.first.fileTypeResponse != null) { | 
					
						
							|  |  |  |           if (data.first.userChatReplyResponse!.fileTypeId == 12 || data.first.userChatReplyResponse!.fileTypeId == 4 || data.first.userChatReplyResponse!.fileTypeId == 3) { | 
					
						
							|  |  |  |             data.first.userChatReplyResponse!.image = | 
					
						
							|  |  |  |                 await ChatApiClient().downloadURL(fileName: data.first.userChatReplyResponse!.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg"); | 
					
						
							|  |  |  |             data.first.userChatReplyResponse!.isImageLoaded = true; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (searchedChats != null) { | 
					
						
							|  |  |  |       dynamic contain = searchedChats!.where((ChatUser element) => element.id == data.first.currentUserId); | 
					
						
							|  |  |  |       if (contain.isEmpty) { | 
					
						
							|  |  |  |         List<String> emails = []; | 
					
						
							|  |  |  |         emails.add(await EmailImageEncryption().encrypt(val: data.first.currentUserEmail!)); | 
					
						
							|  |  |  |         List<ChatUserImageModel> 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()), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     setMsgTune(); | 
					
						
							|  |  |  |     if (isChatScreenActive && data.first.currentUserId == receiverID) { | 
					
						
							|  |  |  |       userChatHistory.insert(0, data.first); | 
					
						
							|  |  |  |     } 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<Object> list = [ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         "userChatHistoryId": data.first.userChatHistoryId, | 
					
						
							|  |  |  |         "TargetUserId": temp.first.targetUserId, | 
					
						
							|  |  |  |         "isDelivered": true, | 
					
						
							|  |  |  |         "isSeen": isChatScreenActive && data.first.currentUserId == receiverID ? true : false | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  |     updateUserChatHistoryOnMsg(list); | 
					
						
							|  |  |  |     invokeChatCounter(userId: AppState().chatDetails!.response!.id!); | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void OnSubmitChatAsync(List<Object?>? parameters) { | 
					
						
							|  |  |  |     print(isChatScreenActive); | 
					
						
							|  |  |  |     print(receiverID); | 
					
						
							|  |  |  |     print(isChatScreenActive); | 
					
						
							|  |  |  |     logger.i(parameters); | 
					
						
							|  |  |  |     List<SingleUserChatModel> data = [], temp = []; | 
					
						
							|  |  |  |     for (dynamic msg in parameters!) { | 
					
						
							|  |  |  |       data = getSingleUserChatModel(jsonEncode(msg)); | 
					
						
							|  |  |  |       temp = getSingleUserChatModel(jsonEncode(msg)); | 
					
						
							|  |  |  |       data.first.targetUserId = temp.first.currentUserId; | 
					
						
							|  |  |  |       data.first.targetUserName = temp.first.currentUserName; | 
					
						
							|  |  |  |       data.first.targetUserEmail = temp.first.currentUserEmail; | 
					
						
							|  |  |  |       data.first.currentUserId = temp.first.targetUserId; | 
					
						
							|  |  |  |       data.first.currentUserName = temp.first.targetUserName; | 
					
						
							|  |  |  |       data.first.currentUserEmail = temp.first.targetUserEmail; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (isChatScreenActive && data.first.currentUserId == receiverID) { | 
					
						
							|  |  |  |       int index = userChatHistory.indexWhere((SingleUserChatModel element) => element.userChatHistoryId == 0); | 
					
						
							|  |  |  |       logger.d(index); | 
					
						
							|  |  |  |       userChatHistory[index] = data.first; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void sort() { | 
					
						
							|  |  |  |     searchedChats!.sort( | 
					
						
							|  |  |  |       (ChatUser a, ChatUser b) => b.unreadMessageCount!.compareTo(a.unreadMessageCount!), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void onUserTyping(List<Object?>? parameters) { | 
					
						
							|  |  |  |     for (ChatUser user in searchedChats!) { | 
					
						
							|  |  |  |       if (user.id == parameters![1] && parameters[0] == true) { | 
					
						
							|  |  |  |         user.isTyping = parameters[0] as bool?; | 
					
						
							|  |  |  |         Future.delayed( | 
					
						
							|  |  |  |           const Duration(seconds: 2), | 
					
						
							|  |  |  |           () { | 
					
						
							|  |  |  |             user.isTyping = false; | 
					
						
							|  |  |  |             notifyListeners(); | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int getFileType(String value) { | 
					
						
							|  |  |  |     switch (value) { | 
					
						
							|  |  |  |       case ".pdf": | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |       case ".png": | 
					
						
							|  |  |  |         return 3; | 
					
						
							|  |  |  |       case ".txt": | 
					
						
							|  |  |  |         return 5; | 
					
						
							|  |  |  |       case ".jpg": | 
					
						
							|  |  |  |         return 12; | 
					
						
							|  |  |  |       case ".jpeg": | 
					
						
							|  |  |  |         return 4; | 
					
						
							|  |  |  |       case ".xls": | 
					
						
							|  |  |  |         return 7; | 
					
						
							|  |  |  |       case ".xlsx": | 
					
						
							|  |  |  |         return 7; | 
					
						
							|  |  |  |       case ".doc": | 
					
						
							|  |  |  |         return 6; | 
					
						
							|  |  |  |       case ".docx": | 
					
						
							|  |  |  |         return 6; | 
					
						
							|  |  |  |       case ".ppt": | 
					
						
							|  |  |  |         return 8; | 
					
						
							|  |  |  |       case ".pptx": | 
					
						
							|  |  |  |         return 8; | 
					
						
							|  |  |  |       case ".zip": | 
					
						
							|  |  |  |         return 2; | 
					
						
							|  |  |  |       case ".rar": | 
					
						
							|  |  |  |         return 2; | 
					
						
							|  |  |  |       case ".aac": | 
					
						
							|  |  |  |         return 13; | 
					
						
							|  |  |  |       case ".mp3": | 
					
						
							|  |  |  |         return 14; | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   String getFileTypeDescription(String value) { | 
					
						
							|  |  |  |     switch (value) { | 
					
						
							|  |  |  |       case ".pdf": | 
					
						
							|  |  |  |         return "application/pdf"; | 
					
						
							|  |  |  |       case ".png": | 
					
						
							|  |  |  |         return "image/png"; | 
					
						
							|  |  |  |       case ".txt": | 
					
						
							|  |  |  |         return "text/plain"; | 
					
						
							|  |  |  |       case ".jpg": | 
					
						
							|  |  |  |         return "image/jpg"; | 
					
						
							|  |  |  |       case ".jpeg": | 
					
						
							|  |  |  |         return "image/jpeg"; | 
					
						
							|  |  |  |       case ".ppt": | 
					
						
							|  |  |  |         return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; | 
					
						
							|  |  |  |       case ".pptx": | 
					
						
							|  |  |  |         return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; | 
					
						
							|  |  |  |       case ".doc": | 
					
						
							|  |  |  |         return "application/vnd.openxmlformats-officedocument.wordprocessingm"; | 
					
						
							|  |  |  |       case ".docx": | 
					
						
							|  |  |  |         return "application/vnd.openxmlformats-officedocument.wordprocessingm"; | 
					
						
							|  |  |  |       case ".xls": | 
					
						
							|  |  |  |         return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; | 
					
						
							|  |  |  |       case ".xlsx": | 
					
						
							|  |  |  |         return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; | 
					
						
							|  |  |  |       case ".zip": | 
					
						
							|  |  |  |         return "application/octet-stream"; | 
					
						
							|  |  |  |       case ".rar": | 
					
						
							|  |  |  |         return "application/octet-stream"; | 
					
						
							|  |  |  |       case ".aac": | 
					
						
							|  |  |  |         return "audio/aac"; | 
					
						
							|  |  |  |       case ".mp3": | 
					
						
							|  |  |  |         return "audio/mp3"; | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         return ""; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> sendChatToServer( | 
					
						
							|  |  |  |       {required int chatEventId, | 
					
						
							|  |  |  |       required fileTypeId, | 
					
						
							|  |  |  |       required int targetUserId, | 
					
						
							|  |  |  |       required String targetUserName, | 
					
						
							|  |  |  |       required chatReplyId, | 
					
						
							|  |  |  |       required bool isAttachment, | 
					
						
							|  |  |  |       required bool isReply, | 
					
						
							|  |  |  |       Uint8List? image, | 
					
						
							|  |  |  |       required bool isImageLoaded, | 
					
						
							|  |  |  |       String? userEmail, | 
					
						
							|  |  |  |       int? userStatus, | 
					
						
							|  |  |  |       File? voiceFile, | 
					
						
							|  |  |  |       required bool isVoiceAttached}) async { | 
					
						
							|  |  |  |     Uuid uuid = const Uuid(); | 
					
						
							|  |  |  |     String contentNo = uuid.v4(); | 
					
						
							|  |  |  |     String msg; | 
					
						
							|  |  |  |     if (isVoiceAttached) { | 
					
						
							|  |  |  |       msg = voiceFile!.path.split("/").last; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       msg = message.text; | 
					
						
							|  |  |  |       logger.w(msg); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     SingleUserChatModel data = SingleUserChatModel( | 
					
						
							|  |  |  |         userChatHistoryId: 0, | 
					
						
							|  |  |  |         chatEventId: chatEventId, | 
					
						
							|  |  |  |         chatSource: 1, | 
					
						
							|  |  |  |         contant: msg, | 
					
						
							|  |  |  |         contantNo: contentNo, | 
					
						
							|  |  |  |         conversationId: chatCID, | 
					
						
							|  |  |  |         createdDate: DateTime.now(), | 
					
						
							|  |  |  |         currentUserId: AppState().chatDetails!.response!.id, | 
					
						
							|  |  |  |         currentUserName: AppState().chatDetails!.response!.userName, | 
					
						
							|  |  |  |         targetUserId: targetUserId, | 
					
						
							|  |  |  |         targetUserName: 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()), | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  |             : null, | 
					
						
							|  |  |  |         image: image, | 
					
						
							|  |  |  |         isImageLoaded: isImageLoaded, | 
					
						
							|  |  |  |         voice: isVoiceMsg ? voiceFile! : null, | 
					
						
							|  |  |  |         voiceController: isVoiceMsg ? AudioPlayer() : null); | 
					
						
							|  |  |  |     if (kDebugMode) { | 
					
						
							|  |  |  |       logger.i("model data: " + jsonEncode(data)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     userChatHistory.insert(0, data); | 
					
						
							|  |  |  |     isTextMsg = false; | 
					
						
							|  |  |  |     isReplyMsg = false; | 
					
						
							|  |  |  |     isAttachmentMsg = false; | 
					
						
							|  |  |  |     isVoiceMsg = false; | 
					
						
							|  |  |  |     sFileType = ""; | 
					
						
							|  |  |  |     message.clear(); | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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"}'; | 
					
						
							|  |  |  |     await chatHubConnection.invoke("AddChatUserAsync", args: <Object>[json.decode(chatData)]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void sendChatMessage(BuildContext context, {required int targetUserId, required int userStatus, required String userEmail, required String targetUserName}) async { | 
					
						
							|  |  |  |     if (kDebugMode) { | 
					
						
							|  |  |  |       print("====================== Values ============================"); | 
					
						
							|  |  |  |       print("Is Text " + isTextMsg.toString()); | 
					
						
							|  |  |  |       print("isReply " + isReplyMsg.toString()); | 
					
						
							|  |  |  |       print("isAttachment " + isAttachmentMsg.toString()); | 
					
						
							|  |  |  |       print("isVoice " + isVoiceMsg.toString()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     //Text
 | 
					
						
							|  |  |  |     if (isTextMsg && !isAttachmentMsg && !isVoiceMsg && !isReplyMsg) { | 
					
						
							|  |  |  |       logger.d("// Normal Text Message"); | 
					
						
							|  |  |  |       if (message.text.isEmpty) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       sendChatToServer( | 
					
						
							|  |  |  |           chatEventId: 1, | 
					
						
							|  |  |  |           fileTypeId: null, | 
					
						
							|  |  |  |           targetUserId: targetUserId, | 
					
						
							|  |  |  |           targetUserName: targetUserName, | 
					
						
							|  |  |  |           isAttachment: false, | 
					
						
							|  |  |  |           chatReplyId: null, | 
					
						
							|  |  |  |           isReply: false, | 
					
						
							|  |  |  |           isImageLoaded: false, | 
					
						
							|  |  |  |           image: null, | 
					
						
							|  |  |  |           isVoiceAttached: false, | 
					
						
							|  |  |  |           userEmail: userEmail, | 
					
						
							|  |  |  |           userStatus: userStatus); | 
					
						
							|  |  |  |     } else if (isTextMsg && !isAttachmentMsg && !isVoiceMsg && isReplyMsg) { | 
					
						
							|  |  |  |       logger.d("// Text Message as Reply"); | 
					
						
							|  |  |  |       if (message.text.isEmpty) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       sendChatToServer( | 
					
						
							|  |  |  |           chatEventId: 1, | 
					
						
							|  |  |  |           fileTypeId: null, | 
					
						
							|  |  |  |           targetUserId: targetUserId, | 
					
						
							|  |  |  |           targetUserName: targetUserName, | 
					
						
							|  |  |  |           chatReplyId: repliedMsg.first.userChatHistoryId, | 
					
						
							|  |  |  |           isAttachment: false, | 
					
						
							|  |  |  |           isReply: true, | 
					
						
							|  |  |  |           isImageLoaded: repliedMsg.first.isImageLoaded!, | 
					
						
							|  |  |  |           image: repliedMsg.first.image, | 
					
						
							|  |  |  |           isVoiceAttached: false, | 
					
						
							|  |  |  |           voiceFile: null, | 
					
						
							|  |  |  |           userEmail: userEmail, | 
					
						
							|  |  |  |           userStatus: userStatus); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     //  Attachment
 | 
					
						
							|  |  |  |     else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && !isReplyMsg) { | 
					
						
							|  |  |  |       logger.d("// Normal Image Message"); | 
					
						
							|  |  |  |       Utils.showLoading(context); | 
					
						
							|  |  |  |       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, | 
					
						
							|  |  |  |           isImageLoaded: true, | 
					
						
							|  |  |  |           image: selectedFile.readAsBytesSync(), | 
					
						
							|  |  |  |           isVoiceAttached: false, | 
					
						
							|  |  |  |           userEmail: userEmail, | 
					
						
							|  |  |  |           userStatus: userStatus); | 
					
						
							|  |  |  |     } 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); | 
					
						
							|  |  |  |       Utils.hideLoading(context); | 
					
						
							|  |  |  |       sendChatToServer( | 
					
						
							|  |  |  |           chatEventId: 2, | 
					
						
							|  |  |  |           fileTypeId: getFileType(ext.toString()), | 
					
						
							|  |  |  |           targetUserId: targetUserId, | 
					
						
							|  |  |  |           targetUserName: targetUserName, | 
					
						
							|  |  |  |           isAttachment: true, | 
					
						
							|  |  |  |           chatReplyId: repliedMsg.first.userChatHistoryId, | 
					
						
							|  |  |  |           isReply: true, | 
					
						
							|  |  |  |           isImageLoaded: true, | 
					
						
							|  |  |  |           image: selectedFile.readAsBytesSync(), | 
					
						
							|  |  |  |           isVoiceAttached: false, | 
					
						
							|  |  |  |           userEmail: userEmail, | 
					
						
							|  |  |  |           userStatus: userStatus); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     //Voice
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     else if (!isTextMsg && !isAttachmentMsg && isVoiceMsg && !isReplyMsg) { | 
					
						
							|  |  |  |       logger.d("// Normal Voice Message"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!isPause) { | 
					
						
							|  |  |  |         path = await recorderController.stop(false); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (kDebugMode) { | 
					
						
							|  |  |  |         logger.i("path:" + path!); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       File voiceFile = File(path!); | 
					
						
							|  |  |  |       voiceFile.readAsBytesSync(); | 
					
						
							|  |  |  |       _timer?.cancel(); | 
					
						
							|  |  |  |       isPause = false; | 
					
						
							|  |  |  |       isPlaying = false; | 
					
						
							|  |  |  |       isRecoding = false; | 
					
						
							|  |  |  |       Utils.showLoading(context); | 
					
						
							|  |  |  |       dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), voiceFile); | 
					
						
							|  |  |  |       String? ext = getFileExtension(voiceFile.path); | 
					
						
							|  |  |  |       Utils.hideLoading(context); | 
					
						
							|  |  |  |       sendChatToServer( | 
					
						
							|  |  |  |           chatEventId: 2, | 
					
						
							|  |  |  |           fileTypeId: getFileType(ext.toString()), | 
					
						
							|  |  |  |           targetUserId: targetUserId, | 
					
						
							|  |  |  |           targetUserName: targetUserName, | 
					
						
							|  |  |  |           chatReplyId: null, | 
					
						
							|  |  |  |           isAttachment: true, | 
					
						
							|  |  |  |           isReply: isReplyMsg, | 
					
						
							|  |  |  |           isImageLoaded: false, | 
					
						
							|  |  |  |           voiceFile: voiceFile, | 
					
						
							|  |  |  |           isVoiceAttached: true, | 
					
						
							|  |  |  |           userEmail: userEmail, | 
					
						
							|  |  |  |           userStatus: userStatus); | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							|  |  |  |     } else if (!isTextMsg && !isAttachmentMsg && isVoiceMsg && isReplyMsg) { | 
					
						
							|  |  |  |       logger.d("// Voice as Reply Msg"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!isPause) { | 
					
						
							|  |  |  |         path = await recorderController.stop(false); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (kDebugMode) { | 
					
						
							|  |  |  |         logger.i("path:" + path!); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       File voiceFile = File(path!); | 
					
						
							|  |  |  |       voiceFile.readAsBytesSync(); | 
					
						
							|  |  |  |       _timer?.cancel(); | 
					
						
							|  |  |  |       isPause = false; | 
					
						
							|  |  |  |       isPlaying = false; | 
					
						
							|  |  |  |       isRecoding = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Utils.showLoading(context); | 
					
						
							|  |  |  |       dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), voiceFile); | 
					
						
							|  |  |  |       String? ext = getFileExtension(voiceFile.path); | 
					
						
							|  |  |  |       Utils.hideLoading(context); | 
					
						
							|  |  |  |       sendChatToServer( | 
					
						
							|  |  |  |           chatEventId: 2, | 
					
						
							|  |  |  |           fileTypeId: getFileType(ext.toString()), | 
					
						
							|  |  |  |           targetUserId: targetUserId, | 
					
						
							|  |  |  |           targetUserName: targetUserName, | 
					
						
							|  |  |  |           chatReplyId: null, | 
					
						
							|  |  |  |           isAttachment: true, | 
					
						
							|  |  |  |           isReply: isReplyMsg, | 
					
						
							|  |  |  |           isImageLoaded: false, | 
					
						
							|  |  |  |           voiceFile: voiceFile, | 
					
						
							|  |  |  |           isVoiceAttached: true, | 
					
						
							|  |  |  |           userEmail: userEmail, | 
					
						
							|  |  |  |           userStatus: userStatus); | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (searchedChats != null) { | 
					
						
							|  |  |  |       dynamic contain = searchedChats!.where((ChatUser element) => element.id == targetUserId); | 
					
						
							|  |  |  |       if (contain.isEmpty) { | 
					
						
							|  |  |  |         List<String> emails = []; | 
					
						
							|  |  |  |         emails.add(await EmailImageEncryption().encrypt(val: userEmail)); | 
					
						
							|  |  |  |         List<ChatUserImageModel> chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails); | 
					
						
							|  |  |  |         searchedChats!.add( | 
					
						
							|  |  |  |           ChatUser( | 
					
						
							|  |  |  |             id: targetUserId, | 
					
						
							|  |  |  |             userName: targetUserName, | 
					
						
							|  |  |  |             unreadMessageCount: 0, | 
					
						
							|  |  |  |             email: userEmail, | 
					
						
							|  |  |  |             isImageLoading: false, | 
					
						
							|  |  |  |             image: chatImages.first.profilePicture ?? "", | 
					
						
							|  |  |  |             isImageLoaded: true, | 
					
						
							|  |  |  |             isTyping: false, | 
					
						
							|  |  |  |             isFav: false, | 
					
						
							|  |  |  |             userStatus: userStatus, | 
					
						
							|  |  |  |             userLocalDownlaodedImage: await downloadImageLocal(chatImages.first.profilePicture, targetUserId.toString()), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |         notifyListeners(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // else {
 | 
					
						
							|  |  |  |     //   List<String> emails = [];
 | 
					
						
							|  |  |  |     //   emails.add(await EmailImageEncryption().encrypt(val: userEmail));
 | 
					
						
							|  |  |  |     //   List<ChatUserImageModel> chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails);
 | 
					
						
							|  |  |  |     //   searchedChats!.add(
 | 
					
						
							|  |  |  |     //     ChatUser(
 | 
					
						
							|  |  |  |     //       id: targetUserId,
 | 
					
						
							|  |  |  |     //       userName: targetUserName,
 | 
					
						
							|  |  |  |     //       unreadMessageCount: 0,
 | 
					
						
							|  |  |  |     //       email: userEmail,
 | 
					
						
							|  |  |  |     //       isImageLoading: false,
 | 
					
						
							|  |  |  |     //       image: chatImages.first.profilePicture ?? "",
 | 
					
						
							|  |  |  |     //       isImageLoaded: true,
 | 
					
						
							|  |  |  |     //       isTyping: false,
 | 
					
						
							|  |  |  |     //       isFav: false,
 | 
					
						
							|  |  |  |     //       userStatus: userStatus,
 | 
					
						
							|  |  |  |     //       userLocalDownlaodedImage: await downloadImageLocal(chatImages.first.profilePicture, targetUserId.toString()),
 | 
					
						
							|  |  |  |     //     ),
 | 
					
						
							|  |  |  |     //   );
 | 
					
						
							|  |  |  |     //   notifyListeners();
 | 
					
						
							|  |  |  |     // }
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void selectImageToUpload(BuildContext context) { | 
					
						
							|  |  |  |     ImageOptions.showImageOptionsNew(context, true, (String image, File file) async { | 
					
						
							|  |  |  |       if (checkFileSize(file.path)) { | 
					
						
							|  |  |  |         selectedFile = file; | 
					
						
							|  |  |  |         isAttachmentMsg = true; | 
					
						
							|  |  |  |         isTextMsg = false; | 
					
						
							|  |  |  |         sFileType = getFileExtension(file.path)!; | 
					
						
							|  |  |  |         message.text = file.path.split("/").last; | 
					
						
							|  |  |  |         Navigator.of(context).pop(); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         Utils.showToast("Max 1 mb size is allowed to upload"); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void removeAttachment() { | 
					
						
							|  |  |  |     isAttachmentMsg = false; | 
					
						
							|  |  |  |     sFileType = ""; | 
					
						
							|  |  |  |     message.text = ''; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   String? getFileExtension(String fileName) { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       if (kDebugMode) { | 
					
						
							|  |  |  |         logger.i("ext: " + "." + fileName.split('.').last); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return "." + fileName.split('.').last; | 
					
						
							|  |  |  |     } catch (e) { | 
					
						
							|  |  |  |       return null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool checkFileSize(String path) { | 
					
						
							|  |  |  |     int fileSizeLimit = 1024; | 
					
						
							|  |  |  |     File f = File(path); | 
					
						
							|  |  |  |     double fileSizeInKB = f.lengthSync() / 1024; | 
					
						
							|  |  |  |     double fileSizeInMB = fileSizeInKB / 1024; | 
					
						
							|  |  |  |     if (fileSizeInKB > fileSizeLimit) { | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   String getType(String type) { | 
					
						
							|  |  |  |     switch (type) { | 
					
						
							|  |  |  |       case ".pdf": | 
					
						
							|  |  |  |         return "assets/images/pdf.svg"; | 
					
						
							|  |  |  |       case ".png": | 
					
						
							|  |  |  |         return "assets/images/png.svg"; | 
					
						
							|  |  |  |       case ".txt": | 
					
						
							|  |  |  |         return "assets/icons/chat/txt.svg"; | 
					
						
							|  |  |  |       case ".jpg": | 
					
						
							|  |  |  |         return "assets/images/jpg.svg"; | 
					
						
							|  |  |  |       case ".jpeg": | 
					
						
							|  |  |  |         return "assets/images/jpg.svg"; | 
					
						
							|  |  |  |       case ".xls": | 
					
						
							|  |  |  |         return "assets/icons/chat/xls.svg"; | 
					
						
							|  |  |  |       case ".xlsx": | 
					
						
							|  |  |  |         return "assets/icons/chat/xls.svg"; | 
					
						
							|  |  |  |       case ".doc": | 
					
						
							|  |  |  |         return "assets/icons/chat/doc.svg"; | 
					
						
							|  |  |  |       case ".docx": | 
					
						
							|  |  |  |         return "assets/icons/chat/doc.svg"; | 
					
						
							|  |  |  |       case ".ppt": | 
					
						
							|  |  |  |         return "assets/icons/chat/ppt.svg"; | 
					
						
							|  |  |  |       case ".pptx": | 
					
						
							|  |  |  |         return "assets/icons/chat/ppt.svg"; | 
					
						
							|  |  |  |       case ".zip": | 
					
						
							|  |  |  |         return "assets/icons/chat/zip.svg"; | 
					
						
							|  |  |  |       case ".rar": | 
					
						
							|  |  |  |         return "assets/icons/chat/zip.svg"; | 
					
						
							|  |  |  |       case ".aac": | 
					
						
							|  |  |  |         return "assets/icons/chat/aac.svg"; | 
					
						
							|  |  |  |       case ".mp3": | 
					
						
							|  |  |  |         return "assets/icons/chat/zip.mp3"; | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         return "assets/images/thumb.svg"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void chatReply(SingleUserChatModel data) { | 
					
						
							|  |  |  |     repliedMsg = []; | 
					
						
							|  |  |  |     data.isReplied = true; | 
					
						
							|  |  |  |     isReplyMsg = true; | 
					
						
							|  |  |  |     repliedMsg.add(data); | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void closeMe() { | 
					
						
							|  |  |  |     repliedMsg = []; | 
					
						
							|  |  |  |     isReplyMsg = false; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   String dateFormte(DateTime data) { | 
					
						
							|  |  |  |     DateFormat f = DateFormat('hh:mm a dd MMM yyyy'); | 
					
						
							|  |  |  |     f.format(data); | 
					
						
							|  |  |  |     return f.format(data); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> favoriteUser({required int userID, required int targetUserID}) async { | 
					
						
							|  |  |  |     fav.FavoriteChatUser favoriteChatUser = await ChatApiClient().favUser(userID: userID, targetUserID: targetUserID); | 
					
						
							|  |  |  |     if (favoriteChatUser.response != null) { | 
					
						
							|  |  |  |       for (ChatUser user in searchedChats!) { | 
					
						
							|  |  |  |         if (user.id == favoriteChatUser.response!.targetUserId!) { | 
					
						
							|  |  |  |           user.isFav = favoriteChatUser.response!.isFav; | 
					
						
							|  |  |  |           dynamic contain = favUsersList!.where((ChatUser element) => element.id == favoriteChatUser.response!.targetUserId!); | 
					
						
							|  |  |  |           if (contain.isEmpty) { | 
					
						
							|  |  |  |             favUsersList.add(user); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> unFavoriteUser({required int userID, required int targetUserID}) async { | 
					
						
							|  |  |  |     fav.FavoriteChatUser favoriteChatUser = await ChatApiClient().unFavUser(userID: userID, targetUserID: targetUserID); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (favoriteChatUser.response != null) { | 
					
						
							|  |  |  |       for (ChatUser user in searchedChats!) { | 
					
						
							|  |  |  |         if (user.id == favoriteChatUser.response!.targetUserId!) { | 
					
						
							|  |  |  |           user.isFav = favoriteChatUser.response!.isFav; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       favUsersList.removeWhere( | 
					
						
							|  |  |  |         (ChatUser element) => element.id == targetUserID, | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void clearSelections() { | 
					
						
							|  |  |  |     searchedChats = pChatHistory; | 
					
						
							|  |  |  |     search.clear(); | 
					
						
							|  |  |  |     isChatScreenActive = false; | 
					
						
							|  |  |  |     receiverID = 0; | 
					
						
							|  |  |  |     paginationVal = 0; | 
					
						
							|  |  |  |     message.text = ''; | 
					
						
							|  |  |  |     isAttachmentMsg = false; | 
					
						
							|  |  |  |     repliedMsg = []; | 
					
						
							|  |  |  |     sFileType = ""; | 
					
						
							|  |  |  |     isReplyMsg = false; | 
					
						
							|  |  |  |     isTextMsg = false; | 
					
						
							|  |  |  |     isVoiceMsg = false; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void clearAll() { | 
					
						
							|  |  |  |     searchedChats = pChatHistory; | 
					
						
							|  |  |  |     search.clear(); | 
					
						
							|  |  |  |     isChatScreenActive = false; | 
					
						
							|  |  |  |     receiverID = 0; | 
					
						
							|  |  |  |     paginationVal = 0; | 
					
						
							|  |  |  |     message.text = ''; | 
					
						
							|  |  |  |     isTextMsg = false; | 
					
						
							|  |  |  |     isAttachmentMsg = false; | 
					
						
							|  |  |  |     isVoiceMsg = false; | 
					
						
							|  |  |  |     isReplyMsg = false; | 
					
						
							|  |  |  |     repliedMsg = []; | 
					
						
							|  |  |  |     sFileType = ""; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void disposeData() { | 
					
						
							|  |  |  |     search.clear(); | 
					
						
							|  |  |  |     isChatScreenActive = false; | 
					
						
							|  |  |  |     receiverID = 0; | 
					
						
							|  |  |  |     paginationVal = 0; | 
					
						
							|  |  |  |     message.text = ''; | 
					
						
							|  |  |  |     isTextMsg = false; | 
					
						
							|  |  |  |     isAttachmentMsg = false; | 
					
						
							|  |  |  |     isVoiceMsg = false; | 
					
						
							|  |  |  |     isReplyMsg = false; | 
					
						
							|  |  |  |     repliedMsg = []; | 
					
						
							|  |  |  |     sFileType = ""; | 
					
						
							|  |  |  |     deleteData(); | 
					
						
							|  |  |  |     favUsersList.clear(); | 
					
						
							|  |  |  |     searchedChats?.clear(); | 
					
						
							|  |  |  |     pChatHistory?.clear(); | 
					
						
							|  |  |  |     chatHubConnection.stop(); | 
					
						
							|  |  |  |     AppState().chatDetails = null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void deleteData() { | 
					
						
							|  |  |  |     List<ChatUser> exists = [], unique = []; | 
					
						
							|  |  |  |     if (searchedChats != null) exists.addAll(searchedChats!); | 
					
						
							|  |  |  |     exists.addAll(favUsersList!); | 
					
						
							|  |  |  |     Map<String, ChatUser> profileMap = {}; | 
					
						
							|  |  |  |     for (ChatUser item in exists) { | 
					
						
							|  |  |  |       profileMap[item.email!] = item; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     unique = profileMap.values.toList(); | 
					
						
							|  |  |  |     for (ChatUser element in unique!) { | 
					
						
							|  |  |  |       deleteFile(element.id.toString()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void getUserImages() async { | 
					
						
							|  |  |  |     List<String> emails = []; | 
					
						
							|  |  |  |     List<ChatUser> exists = [], unique = []; | 
					
						
							|  |  |  |     exists.addAll(searchedChats!); | 
					
						
							|  |  |  |     exists.addAll(favUsersList!); | 
					
						
							|  |  |  |     Map<String, ChatUser> profileMap = {}; | 
					
						
							|  |  |  |     for (ChatUser item in exists) { | 
					
						
							|  |  |  |       profileMap[item.email!] = item; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     unique = profileMap.values.toList(); | 
					
						
							|  |  |  |     for (ChatUser element in unique!) { | 
					
						
							|  |  |  |       emails.add(await EmailImageEncryption().encrypt(val: element.email!)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     List<ChatUserImageModel> chatImages = await ChatApiClient().getUsersImages(encryptedEmails: emails); | 
					
						
							|  |  |  |     for (ChatUser user in searchedChats!) { | 
					
						
							|  |  |  |       for (ChatUserImageModel uImage in chatImages) { | 
					
						
							|  |  |  |         if (user.email == uImage.email) { | 
					
						
							|  |  |  |           user.image = uImage.profilePicture ?? ""; | 
					
						
							|  |  |  |           user.userLocalDownlaodedImage = await downloadImageLocal(uImage.profilePicture, user.id.toString()); | 
					
						
							|  |  |  |           user.isImageLoading = false; | 
					
						
							|  |  |  |           user.isImageLoaded = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for (ChatUser favUser in favUsersList) { | 
					
						
							|  |  |  |       for (ChatUserImageModel uImage in chatImages) { | 
					
						
							|  |  |  |         if (favUser.email == uImage.email) { | 
					
						
							|  |  |  |           favUser.image = uImage.profilePicture ?? ""; | 
					
						
							|  |  |  |           favUser.userLocalDownlaodedImage = await downloadImageLocal(uImage.profilePicture, favUser.id.toString()); | 
					
						
							|  |  |  |           favUser.isImageLoading = false; | 
					
						
							|  |  |  |           favUser.isImageLoaded = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<File?> downloadImageLocal(String? encodedBytes, String userID) async { | 
					
						
							|  |  |  |     File? myfile; | 
					
						
							|  |  |  |     if (encodedBytes == null) { | 
					
						
							|  |  |  |       return myfile; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       await deleteFile(userID); | 
					
						
							|  |  |  |       Uint8List decodedBytes = base64Decode(encodedBytes); | 
					
						
							|  |  |  |       Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); | 
					
						
							|  |  |  |       String dirPath = '${appDocumentsDirectory.path}/chat_images'; | 
					
						
							|  |  |  |       if (!await Directory(dirPath).exists()) { | 
					
						
							|  |  |  |         await Directory(dirPath).create(); | 
					
						
							|  |  |  |         await File('$dirPath/.nomedia').create(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       late File imageFile = File("$dirPath/$userID.jpg"); | 
					
						
							|  |  |  |       imageFile.writeAsBytesSync(decodedBytes); | 
					
						
							|  |  |  |       return imageFile; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future deleteFile(String userID) async { | 
					
						
							|  |  |  |     Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); | 
					
						
							|  |  |  |     String dirPath = '${appDocumentsDirectory.path}/chat_images'; | 
					
						
							|  |  |  |     late File imageFile = File('$dirPath/$userID.jpg'); | 
					
						
							|  |  |  |     if (await imageFile.exists()) { | 
					
						
							|  |  |  |       await imageFile.delete(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<String> downChatMedia(Uint8List bytes, String ext) async { | 
					
						
							|  |  |  |     String dir = (await getApplicationDocumentsDirectory()).path; | 
					
						
							|  |  |  |     File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext); | 
					
						
							|  |  |  |     await file.writeAsBytes(bytes); | 
					
						
							|  |  |  |     return file.path; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void setMsgTune() async { | 
					
						
							|  |  |  |     JustAudio.AudioPlayer player = JustAudio.AudioPlayer(); | 
					
						
							|  |  |  |     await player.setVolume(1.0); | 
					
						
							|  |  |  |     String audioAsset = ""; | 
					
						
							|  |  |  |     if (Platform.isAndroid) { | 
					
						
							|  |  |  |       audioAsset = "assets/audio/pulse_tone_android.mp3"; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       audioAsset = "assets/audio/pulse_tune_ios.caf"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       await player.setAsset(audioAsset); | 
					
						
							|  |  |  |       await player.load(); | 
					
						
							|  |  |  |       player.play(); | 
					
						
							|  |  |  |     } catch (e) { | 
					
						
							|  |  |  |       print("Error: $e"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> getChatMedia(BuildContext context, {required String fileName, required String fileTypeName, required int fileTypeID}) async { | 
					
						
							|  |  |  |     Utils.showLoading(context); | 
					
						
							|  |  |  |     if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 || fileTypeID == 2) { | 
					
						
							|  |  |  |       Uint8List encodedString = await ChatApiClient().downloadURL(fileName: fileName, fileTypeDescription: getFileTypeDescription(fileTypeName)); | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         String path = await downChatMedia(encodedString, fileTypeName ?? ""); | 
					
						
							|  |  |  |         Utils.hideLoading(context); | 
					
						
							|  |  |  |         OpenFile.open(path); | 
					
						
							|  |  |  |       } catch (e) { | 
					
						
							|  |  |  |         Utils.showToast("Cannot open file."); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void onNewChatConversion(List<Object?>? params) { | 
					
						
							|  |  |  |     dynamic items = params!.toList(); | 
					
						
							|  |  |  |     chatUConvCounter = items[0]["singleChatCount"] ?? 0; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future invokeChatCounter({required int userId}) async { | 
					
						
							|  |  |  |     await chatHubConnection.invoke("GetChatCounversationCount", args: [userId]); | 
					
						
							|  |  |  |     return ""; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void userTypingInvoke({required int currentUser, required int reciptUser}) async { | 
					
						
							|  |  |  |     await chatHubConnection.invoke("UserTypingAsync", args: [reciptUser, currentUser]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //////// Audio Recoding Work ////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> initAudio({required int receiverId}) async { | 
					
						
							|  |  |  |     // final dir = Directory((Platform.isAndroid
 | 
					
						
							|  |  |  |     //     ? await getExternalStorageDirectory() //FOR ANDROID
 | 
					
						
							|  |  |  |     //     : await getApplicationSupportDirectory() //FOR IOS
 | 
					
						
							|  |  |  |     // )!
 | 
					
						
							|  |  |  |     appDirectory = await getApplicationDocumentsDirectory(); | 
					
						
							|  |  |  |     String dirPath = '${appDirectory.path}/chat_audios'; | 
					
						
							|  |  |  |     if (!await Directory(dirPath).exists()) { | 
					
						
							|  |  |  |       await Directory(dirPath).create(); | 
					
						
							|  |  |  |       await File('$dirPath/.nomedia').create(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     path = "$dirPath/${AppState().chatDetails!.response!.id}-$receiverID-${DateTime.now().microsecondsSinceEpoch}.aac"; | 
					
						
							|  |  |  |     recorderController = RecorderController() | 
					
						
							|  |  |  |       ..androidEncoder = AndroidEncoder.aac | 
					
						
							|  |  |  |       ..androidOutputFormat = AndroidOutputFormat.mpeg4 | 
					
						
							|  |  |  |       ..iosEncoder = IosEncoder.kAudioFormatMPEG4AAC | 
					
						
							|  |  |  |       ..sampleRate = 6000 | 
					
						
							|  |  |  |       ..updateFrequency = const Duration(milliseconds: 100) | 
					
						
							|  |  |  |       ..bitRate = 18000; | 
					
						
							|  |  |  |     playerController = PlayerController(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void disposeAudio() { | 
					
						
							|  |  |  |     isRecoding = false; | 
					
						
							|  |  |  |     isPlaying = false; | 
					
						
							|  |  |  |     isPause = false; | 
					
						
							|  |  |  |     isVoiceMsg = false; | 
					
						
							|  |  |  |     recorderController.dispose(); | 
					
						
							|  |  |  |     playerController.dispose(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void startRecoding() async { | 
					
						
							|  |  |  |     PermissionStatus status = await Permission.microphone.request(); | 
					
						
							|  |  |  |     if (status.isDenied == true) { | 
					
						
							|  |  |  |       startRecoding(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       isVoiceMsg = true; | 
					
						
							|  |  |  |       recorderController.reset(); | 
					
						
							|  |  |  |       await recorderController.record(path); | 
					
						
							|  |  |  |       _recodeDuration = 0; | 
					
						
							|  |  |  |       _startTimer(); | 
					
						
							|  |  |  |       isRecoding = !isRecoding; | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> _startTimer() async { | 
					
						
							|  |  |  |     _timer?.cancel(); | 
					
						
							|  |  |  |     _timer = Timer.periodic(const Duration(seconds: 1), (Timer t) async { | 
					
						
							|  |  |  |       _recodeDuration++; | 
					
						
							|  |  |  |       if (_recodeDuration <= 59) { | 
					
						
							|  |  |  |         applyCounter(); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         pauseRecoding(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void applyCounter() { | 
					
						
							|  |  |  |     buildTimer(); | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> pauseRecoding() async { | 
					
						
							|  |  |  |     isPause = true; | 
					
						
							|  |  |  |     isPlaying = true; | 
					
						
							|  |  |  |     recorderController.pause(); | 
					
						
							|  |  |  |     path = await recorderController.stop(false); | 
					
						
							|  |  |  |     File file = File(path!); | 
					
						
							|  |  |  |     file.readAsBytesSync(); | 
					
						
							|  |  |  |     path = file.path; | 
					
						
							|  |  |  |     await playerController.preparePlayer(file.path, 1.0); | 
					
						
							|  |  |  |     _timer?.cancel(); | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> deleteRecoding() async { | 
					
						
							|  |  |  |     _recodeDuration = 0; | 
					
						
							|  |  |  |     _timer?.cancel(); | 
					
						
							|  |  |  |     if (path == null) { | 
					
						
							|  |  |  |       path = await recorderController.stop(true); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       await recorderController.stop(true); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (path != null && path!.isNotEmpty) { | 
					
						
							|  |  |  |       File delFile = File(path!); | 
					
						
							|  |  |  |       double fileSizeInKB = delFile.lengthSync() / 1024; | 
					
						
							|  |  |  |       double fileSizeInMB = fileSizeInKB / 1024; | 
					
						
							|  |  |  |       if (kDebugMode) { | 
					
						
							|  |  |  |         debugPrint("Deleted file size: ${delFile.lengthSync()}"); | 
					
						
							|  |  |  |         debugPrint("Deleted file size in KB: " + fileSizeInKB.toString()); | 
					
						
							|  |  |  |         debugPrint("Deleted file size in MB: " + fileSizeInMB.toString()); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (await delFile.exists()) { | 
					
						
							|  |  |  |         delFile.delete(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       isPause = false; | 
					
						
							|  |  |  |       isRecoding = false; | 
					
						
							|  |  |  |       isPlaying = false; | 
					
						
							|  |  |  |       isVoiceMsg = false; | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   String buildTimer() { | 
					
						
							|  |  |  |     String minutes = _formatNum(_recodeDuration ~/ 60); | 
					
						
							|  |  |  |     String seconds = _formatNum(_recodeDuration % 60); | 
					
						
							|  |  |  |     return '$minutes : $seconds'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   String _formatNum(int number) { | 
					
						
							|  |  |  |     String numberStr = number.toString(); | 
					
						
							|  |  |  |     if (number < 10) { | 
					
						
							|  |  |  |       numberStr = '0' + numberStr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return numberStr; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<String> downChatVoice(Uint8List bytes, String ext, SingleUserChatModel data) async { | 
					
						
							|  |  |  |     String dirPath = '${(await getApplicationDocumentsDirectory()).path}/chat_audios'; | 
					
						
							|  |  |  |     if (!await Directory(dirPath).exists()) { | 
					
						
							|  |  |  |       await Directory(dirPath).create(); | 
					
						
							|  |  |  |       await File('$dirPath/.nomedia').create(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     File file = File("$dirPath/${data.currentUserId}-${data.targetUserId}-${DateTime.now().microsecondsSinceEpoch}." + ext); | 
					
						
							|  |  |  |     await file.writeAsBytes(bytes); | 
					
						
							|  |  |  |     return file.path; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void scrollToMsg(SingleUserChatModel data) { | 
					
						
							|  |  |  |     if (data.userChatReplyResponse != null && data.userChatReplyResponse!.userChatHistoryId != null) { | 
					
						
							|  |  |  |       int index = userChatHistory.indexWhere((SingleUserChatModel element) => element.userChatHistoryId == data.userChatReplyResponse!.userChatHistoryId); | 
					
						
							|  |  |  |       if (index >= 1) { | 
					
						
							|  |  |  |         double contentSize = scrollController.position.viewportDimension + scrollController.position.maxScrollExtent; | 
					
						
							|  |  |  |         double target = contentSize * index / userChatHistory.length; | 
					
						
							|  |  |  |         scrollController.position.animateTo( | 
					
						
							|  |  |  |           target, | 
					
						
							|  |  |  |           duration: const Duration(seconds: 1), | 
					
						
							|  |  |  |           curve: Curves.easeInOut, | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> getTeamMembers() async { | 
					
						
							|  |  |  |     teamMembersList = []; | 
					
						
							|  |  |  |     isLoading = true; | 
					
						
							|  |  |  |     if (AppState().getemployeeSubordinatesList.isNotEmpty) { | 
					
						
							|  |  |  |       getEmployeeSubordinatesList = AppState().getemployeeSubordinatesList; | 
					
						
							|  |  |  |       for (GetEmployeeSubordinatesList element in getEmployeeSubordinatesList) { | 
					
						
							|  |  |  |         if (element.eMPLOYEEEMAILADDRESS != null) { | 
					
						
							|  |  |  |           if (element.eMPLOYEEEMAILADDRESS!.isNotEmpty) { | 
					
						
							|  |  |  |             teamMembersList.add( | 
					
						
							|  |  |  |               ChatUser( | 
					
						
							|  |  |  |                 id: int.parse(element.eMPLOYEENUMBER!), | 
					
						
							|  |  |  |                 email: element.eMPLOYEEEMAILADDRESS, | 
					
						
							|  |  |  |                 userName: element.eMPLOYEENAME, | 
					
						
							|  |  |  |                 phone: element.eMPLOYEEMOBILENUMBER, | 
					
						
							|  |  |  |                 userStatus: 0, | 
					
						
							|  |  |  |                 unreadMessageCount: 0, | 
					
						
							|  |  |  |                 isFav: false, | 
					
						
							|  |  |  |                 isTyping: false, | 
					
						
							|  |  |  |                 isImageLoading: false, | 
					
						
							|  |  |  |                 image: element.eMPLOYEEIMAGE ?? "", | 
					
						
							|  |  |  |                 isImageLoaded: element.eMPLOYEEIMAGE == null ? false : true, | 
					
						
							|  |  |  |                 userLocalDownlaodedImage: element.eMPLOYEEIMAGE == null ? null : await downloadImageLocal(element.eMPLOYEEIMAGE ?? "", element.eMPLOYEENUMBER!), | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       getEmployeeSubordinatesList = await MyTeamApiClient().getEmployeeSubordinates("", "", ""); | 
					
						
							|  |  |  |       AppState().setemployeeSubordinatesList = getEmployeeSubordinatesList; | 
					
						
							|  |  |  |       for (GetEmployeeSubordinatesList element in getEmployeeSubordinatesList) { | 
					
						
							|  |  |  |         if (element.eMPLOYEEEMAILADDRESS != null) { | 
					
						
							|  |  |  |           if (element.eMPLOYEEEMAILADDRESS!.isNotEmpty) { | 
					
						
							|  |  |  |             teamMembersList.add( | 
					
						
							|  |  |  |               ChatUser( | 
					
						
							|  |  |  |                 id: int.parse(element.eMPLOYEENUMBER!), | 
					
						
							|  |  |  |                 email: element.eMPLOYEEEMAILADDRESS, | 
					
						
							|  |  |  |                 userName: element.eMPLOYEENAME, | 
					
						
							|  |  |  |                 phone: element.eMPLOYEEMOBILENUMBER, | 
					
						
							|  |  |  |                 userStatus: 0, | 
					
						
							|  |  |  |                 unreadMessageCount: 0, | 
					
						
							|  |  |  |                 isFav: false, | 
					
						
							|  |  |  |                 isTyping: false, | 
					
						
							|  |  |  |                 isImageLoading: false, | 
					
						
							|  |  |  |                 image: element.eMPLOYEEIMAGE ?? "", | 
					
						
							|  |  |  |                 isImageLoaded: element.eMPLOYEEIMAGE == null ? false : true, | 
					
						
							|  |  |  |                 userLocalDownlaodedImage: element.eMPLOYEEIMAGE == null ? null : await downloadImageLocal(element.eMPLOYEEIMAGE ?? "", element.eMPLOYEENUMBER!), | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     isLoading = false; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |